drcov plugin won't work if program doesn't exit normally
bruce30262 opened this issue · 2 comments
First of all thanks @JRomainG and @vanhauser-thc for PR #56. The drcov plugin is very useful.
However I found that when a program doesn't exit normally, the plugin won't dump the coverage info into the file. So for example a simple program like:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(int argc, char *argv[]) {
int *p = NULL;
*p = 123; // crash
return 0;
}
Will results in an empty drcov file.
I'm not familiar with QEMU TCG plugin but I think it's because it only calls plugin_exit
in the atexit callback :
qemu_plugin_register_atexit_cb(id, plugin_exit, NULL);
So when program exit abnormally ( crash / hang / timeout / ctrl-c ...etc ) it won't dump the coverage info.
Is it possible to register plugin_exit
in other signal handlers, so when the program receive those signals and terminate itself it will also dump the coverage info ? Here are some signals I can think of :
- SIGTERM
- SIGINT
- SIGALRM
- SIGKILL
- SIGSEGV
Unfortunately, it doesn't seem to be that easy, as QEMU registers its own signal handlers. Ideally, a callback would be added to the dump_core_and_abort
function, but I do not believe that this is natively supported. You can however add it with a simple patch:
diff --git a/linux-user/signal.c b/linux-user/signal.c
index 8b23f67821..21bf7fcc60 100644
--- a/linux-user/signal.c
+++ b/linux-user/signal.c
@@ -632,6 +632,9 @@ static void QEMU_NORETURN dump_core_and_abort(int target_sig)
trace_user_force_sig(env, target_sig, host_sig);
gdb_signalled(env, target_sig);
+ /* notify plugins that we are about to exit */
+ qemu_plugin_atexit_cb();
+
/* dump core if supported by target binary format */
if (core_dump_signal(target_sig) && (ts->bprm->core_dump != NULL)) {
stop_all_tasks();
I see, thanks for the reply !