fungos / cr

cr.h: A Simple C Hot Reload Header-only Library
https://fungos.github.io/cr-simple-c-hot-reload/
MIT License
1.54k stars 101 forks source link

Different behaviour in linux and win #31

Closed septag closed 5 years ago

septag commented 5 years ago

I've noticed a different behaviour in windows and linux versions. in windows the normal static vars (ones without CR_STATE) are not restored after plugin reload. But in linux, all variables are restored and doesn't actually care about CR_STATE I guess this would be from restoring .bss section. And also other question is, if we backup and restore all static vars, what is the point of CR_STATE ?

fungos commented 5 years ago

I think this shouldn't happen, unless the compiler and linker is doing something weird or unless I've forgot about something specific I did, which I doubt. It would require a bit more invesitgation to understand why this difference is happening.

The BSS is where zero-initialized static things are allocated, and I manage it because it basically:

  1. does not require any construction/initialization code to run when something new appears (a new non-initialized static variable is introduced in the code), it is always zeroed; and,
  2. is almost always safe to restore it, unless the code change was too intense - which was not the case most of the time in a rapid feedback cycle development;

We could really go into more control about everything, but that would almost require writing a dynamic linker for example, but then we have better and more expensive alternatives to cr :)

So, for my use case, I decided that the abusing BSS and CR_STATE is a good equilibrium between practicality, stability and effort required to get something usable.

On the other hand, we can introduce one option to disable managing BSS.

septag commented 5 years ago

yes, seems legit

But the the problem with windows vs other platforms inconsistency still persists. Here's how I reproduce it:

void update() {
    static bool once = false;
    if (!once) {
        print_something();
        once = true;
    }
}

On windows, print_something() runs everytime the plugin reloads, while on linux, it runs only the first time. btw, should once accounted as zero-initialized reside in .bss ?

fungos commented 5 years ago

In fact, that is the issue. It is implementation dependent, there it's no well defined standard. So each linker may do different things. If you look at one of my samples, I have this case but with CR_STATE. I think I did had this issue and forgot writing about it. I think documenting and giving a option to disable .bss use would be the only way out.

See the "-fno-zero-initialized-in-bss" section here http://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html