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

Unable to rollback crash in first load of plugin #42

Closed pixelherodev closed 4 years ago

pixelherodev commented 5 years ago

If the first load of a plugin (version number 1) crashes (e.g. segfault), rollback attempts to load a nonexistent version zero and appears to enter a feedback loop of constant crashing / signal handler / crashing / etc.

pixelherodev commented 5 years ago

Tested against various commits, all gave some form of error - some older versions seem to damage the stack somehow and are terminated, others have the same current error - an endless amount of

CR_TRACE: cr_signal_handler
CR_TRACE: cr_signal_handler
CR_TRACE: cr_signal_handler
CR_TRACE: cr_signal_handler
CR_TRACE: cr_signal_handler
CR_TRACE: cr_signal_handler
CR_TRACE: cr_signal_handler
CR_TRACE: cr_signal_handler
CR_TRACE: cr_signal_handler
CR_TRACE: cr_signal_handler
CR_TRACE: cr_signal_handler
CR_TRACE: cr_signal_handler
CR_TRACE: cr_signal_handler
CR_TRACE: cr_signal_handler
CR_TRACE: cr_signal_handler

until the process is manually terminated, etc

pixelherodev commented 5 years ago

My personal workaround is to have the host automatically do the equivalent of touching the plugin file immediately after first load, but this is of course not a preferred option.

To be fair, i only noticed the issue because I was deliberately testing using *(int*)NULL=0; and forgot to rebuild after removing that and encountered on the next run of the host, so it's probably not that bad (and I won't rule out that I'm just encountering a corner case, so I'll try to provide a tiny example that encounters the problem).

pixelherodev commented 5 years ago

This also only seems to happen on signal failures (segfaults, SIGABRT, etc), not other crashes.

fungos commented 5 years ago

Yes. I remember getting this at some testing, but then I didn't had a good solution either. If you have any decent solution (not sure about the touch tough, need to see your implementation anyway), I'm willing to merge.

pixelherodev commented 5 years ago

Basically, my workaround is to check if it's the first load, and if so fake a second version and go to that. It's not perfect - it only works if the plugin gets through CR_LOAD without issue, but it means that at least failures in CR_STEPs are caught on the first load.

Whenever a rollback to the first version is detected, it once again fakes a new copy, basically ensuring there's always at least two versions in the history.

It leaves two issues though:

I think the best solution for now is to reject rollback attempts on the first version instead and report it to the user as an error. That allows the client to report the error and e.g. enter a sleepy loop checking every second or so for a new update.

fungos commented 5 years ago

Agreed, I prefer to reject and report the first crash. It actually makes more sense as it is a first-run.

pixelherodev commented 5 years ago

Alrighty, watch out for a PR soon :)

pixelherodev commented 4 years ago

Whoops, sorry about the delay; haven't touched the project that was using this in a while.