Skip to content

Commit aa5cb7f

Browse files
elmarcobonzini
authored andcommitted
char: do not use atexit cleanup handler
It turns out qemu is calling exit() in various places from various threads without taking much care of resources state. The atexit() cleanup handlers cannot easily destroy resources that are in use (by the same thread or other). Since c1111a2, TCG arm guests run into the following abort() when running tests, the chardev mutex is locked during the write, so qemu_mutex_destroy() returns an error: #0 0x00007fffdbb806f5 in raise () at /lib64/libc.so.6 #1 0x00007fffdbb822fa in abort () at /lib64/libc.so.6 #2 0x00005555557616fe in error_exit (err=<optimized out>, msg=msg@entry=0x555555c38c30 <__func__.14622> "qemu_mutex_destroy") at /home/drjones/code/qemu/util/qemu-thread-posix.c:39 #3 0x0000555555b0be20 in qemu_mutex_destroy (mutex=mutex@entry=0x5555566aa0e0) at /home/drjones/code/qemu/util/qemu-thread-posix.c:57 #4 0x00005555558aab00 in qemu_chr_free_common (chr=0x5555566aa0e0) at /home/drjones/code/qemu/qemu-char.c:4029 #5 0x00005555558b05f9 in qemu_chr_delete (chr=<optimized out>) at /home/drjones/code/qemu/qemu-char.c:4038 #6 0x00005555558b05f9 in qemu_chr_delete (chr=<optimized out>) at /home/drjones/code/qemu/qemu-char.c:4044 #7 0x00005555558b062c in qemu_chr_cleanup () at /home/drjones/code/qemu/qemu-char.c:4557 #8 0x00007fffdbb851e8 in __run_exit_handlers () at /lib64/libc.so.6 #9 0x00007fffdbb85235 in () at /lib64/libc.so.6 #10 0x00005555558d1b39 in testdev_write (testdev=0x5555566aa0a0) at /home/drjones/code/qemu/backends/testdev.c:71 #11 0x00005555558d1b39 in testdev_write (chr=<optimized out>, buf=0x7fffc343fd9a "", len=0) at /home/drjones/code/qemu/backends/testdev.c:95 #12 0x00005555558adced in qemu_chr_fe_write (s=0x5555566aa0e0, buf=buf@entry=0x7fffc343fd98 "0q", len=len@entry=2) at /home/drjones/code/qemu/qemu-char.c:282 Instead of using a atexit() handler, only run the chardev cleanup as initially proposed at the end of main(), where there are less chances (hic) of conflicts or other races. Signed-off-by: Marc-André Lureau <[email protected]> Reported-by: Andrew Jones <[email protected]> Message-Id: <[email protected]> Signed-off-by: Paolo Bonzini <[email protected]>
1 parent 8caf911 commit aa5cb7f

File tree

3 files changed

+10
-3
lines changed

3 files changed

+10
-3
lines changed

include/sysemu/char.h

+7
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,13 @@ CharDriverState *qemu_chr_new(const char *label, const char *filename,
151151
*/
152152
void qemu_chr_disconnect(CharDriverState *chr);
153153

154+
/**
155+
* @qemu_chr_cleanup:
156+
*
157+
* Delete all chardevs (when leaving qemu)
158+
*/
159+
void qemu_chr_cleanup(void);
160+
154161
/**
155162
* @qemu_chr_new_noreplay:
156163
*

qemu-char.c

+1-3
Original file line numberDiff line numberDiff line change
@@ -4548,7 +4548,7 @@ void qmp_chardev_remove(const char *id, Error **errp)
45484548
qemu_chr_delete(chr);
45494549
}
45504550

4551-
static void qemu_chr_cleanup(void)
4551+
void qemu_chr_cleanup(void)
45524552
{
45534553
CharDriverState *chr, *tmp;
45544554

@@ -4603,8 +4603,6 @@ static void register_types(void)
46034603
* is specified
46044604
*/
46054605
qemu_add_machine_init_done_notifier(&muxes_realize_notify);
4606-
4607-
atexit(qemu_chr_cleanup);
46084606
}
46094607

46104608
type_init(register_types);

vl.c

+2
Original file line numberDiff line numberDiff line change
@@ -4608,7 +4608,9 @@ int main(int argc, char **argv, char **envp)
46084608
tpm_cleanup();
46094609
#endif
46104610

4611+
/* vhost-user must be cleaned up before chardevs. */
46114612
net_cleanup();
4613+
qemu_chr_cleanup();
46124614

46134615
return 0;
46144616
}

0 commit comments

Comments
 (0)