Live data from Hacker News

Subsecond: A runtime hotpatching engine for Rust hot-reloading

docs.rs

11–20 of 41 posts

Re: Subsecond: A runtime hotpatching engine for Rust hot-reloading

#11
post #7

Interesting, but the documentation makes it sound like you have to preemptively wrap all the code you think you might want to change in a special wrapper "call" function. If true that makes this a lot less appealing than existing solutions for other languages that can modify any function without special annotations.

You basically need to wrap your program's `tick()` function. Otherwise you might be in the middle of malloc, hot-patch, and your struct's layout and alignment changes, and your program crashes due to undefined behavior.

The goal is that frameworks just bake `subsecond::current` into their `tick()` function and end-users get hot-patching for free.

Re: Subsecond: A runtime hotpatching engine for Rust hot-reloading

#12
post #7

Interesting, but the documentation makes it sound like you have to preemptively wrap all the code you think you might want to change in a special wrapper "call" function. If true that makes this a lot less appealing than existing solutions for other languages that can modify any function without special annotations.

You basically need to wrap your program's `tick()` function. Otherwise you might be in the middle of malloc, hot-patch, and your struct's layout and alignment changes, and your program crashes due to undefined behavior. The goal is that frameworks just bake `subsecond::current` into their `tick()` function and end-users get hot-patching for free.

[deleted]

Re: Subsecond: A runtime hotpatching engine for Rust hot-reloading

#13

Creator here - haven't had a chance to write up a blog post yet! Stay tuned. The gist of it is that we intercept the Rust linking phase and then drive `rustc` manually. There's some diffing logic that compares assembly between compiles and then a linking phase where we patch symbols against the running process. Works across macOS, Windows, Linux, iOS, Android, and WASM. On my m4 I can get 130ms compile-patch times, q…

[deleted]

Re: Subsecond: A runtime hotpatching engine for Rust hot-reloading

#14
post #7

Interesting, but the documentation makes it sound like you have to preemptively wrap all the code you think you might want to change in a special wrapper "call" function. If true that makes this a lot less appealing than existing solutions for other languages that can modify any function without special annotations.

Strong agree here. The 'purity' BS of not modifying the running programs address space appears to come at the cost of significant programmer pain-in-the-ass. Having to hand-hold the library to maintain the indirection table is a hard no for me.

Metaprogramming that maintenance burden seems like it should be relatively straight-forward, if you've written a linker already.

Re: Subsecond: A runtime hotpatching engine for Rust hot-reloading

#15
I really want rust dylibs to be a reality. A plugin system where a library can implement a specific versioned number of a trait and we can dynamically load in that implementation to get changed behaviour. Right now implementing anything like that requires a lot of unsafe which I'm not comfortable with.

Re: Subsecond: A runtime hotpatching engine for Rust hot-reloading

#16
post #7

Interesting, but the documentation makes it sound like you have to preemptively wrap all the code you think you might want to change in a special wrapper "call" function. If true that makes this a lot less appealing than existing solutions for other languages that can modify any function without special annotations.

You basically need to wrap your program's `tick()` function. Otherwise you might be in the middle of malloc, hot-patch, and your struct's layout and alignment changes, and your program crashes due to undefined behavior. The goal is that frameworks just bake `subsecond::current` into their `tick()` function and end-users get hot-patching for free.

How would you preempt the running program during malloc? Isn't there a well-defined reload point? Major red flags going up if your program can just change at any random point..

Also, didn't the article say explicitly that struct layout changes aren't supported??

Re: Subsecond: A runtime hotpatching engine for Rust hot-reloading

#17
post #16

Earlier quoted context omitted.

You basically need to wrap your program's `tick()` function. Otherwise you might be in the middle of malloc, hot-patch, and your struct's layout and alignment changes, and your program crashes due to undefined behavior. The goal is that frameworks just bake `subsecond::current` into their `tick()` function and end-users get hot-patching for free.

How would you preempt the running program during malloc? Isn't there a well-defined reload point? Major red flags going up if your program can just change at any random point.. Also, didn't the article say explicitly that struct layout changes aren't supported??

There is a well-defined reload point—it’s the `subsecond::call` wrapper around `tick()`. But the hypothetical design that you seem to have in mind where this doesn’t exist would not have a well-defined reload point, so it would need to be able to preempt your program anywhere.

Layout changes are supported for structs that don’t persist across the well-defined reload point.

Re: Subsecond: A runtime hotpatching engine for Rust hot-reloading

#18
post #14
post #7

Interesting, but the documentation makes it sound like you have to preemptively wrap all the code you think you might want to change in a special wrapper "call" function. If true that makes this a lot less appealing than existing solutions for other languages that can modify any function without special annotations.

Strong agree here. The 'purity' BS of not modifying the running programs address space appears to come at the cost of significant programmer pain-in-the-ass. Having to hand-hold the library to maintain the indirection table is a hard no for me. Metaprogramming that maintenance burden seems like it should be relatively straight-forward, if you've written a linker already.

The challenge is that if the program is busy in a spin loop, there's no way to preempt it and modify it. Things like malloc, spin loops, network requests, syscalls etc.

I looked into liveplusplus a lot and their unreal integration also requires a broker to get the most out of it. If you're building a game engine and want to support struct layout and alignment changes, you'll need to do some re-instancing. Hiding a `subsecond::call` deep in the bowels of the host framework hides it from the user and lets the framework handle any complicated state management it needs during hotpatches.

I wouldn't say it's purity - the first version of subsecond actually did do in-process modification - but after playing around with it for a while, I much preferred the light runtime integration. The dioxus integration was about 5 lines of code, so it's quite minimal.

Post reply on HN