|
From: | Markus Doppelbauer |
Subject: | Re: [libmicrohttpd] Segfault after MHD_quiesce_daemon() |
Date: | Sat, 18 Jul 2015 17:25:47 +0200 |
Hi,
Sorry - I can't provide a testcase - I only have the coredumps.
IMHO the problem is, that two threads work in the same critical section MHD_cleanup_connections()
#1 MHD-Thread from microhttpd/daemon.c:2937 from MHD_select_thread()
#2 Worker-thread from microhttpd/daemon.c:4630 from MHD_get_daemon_info( MHD_DAEMON_INFO_CURRENT_CONNECTIONS )
Both threads meet each other in MHD_cleanup_connections()
Down below an other core-dump. In that case the worker-thread crashed.
Thanks a lot
Markus
# Main-Thread after MHD_quiesce_daemon()
#1 0x0000003bd6e33e05 in abort () from /lib64/libc.so.6
No symbol table info available.
#2 0x0000003bd6e70537 in __libc_message () from /lib64/libc.so.6
No symbol table info available.
#3 0x0000003bd6e75e66 in malloc_printerr () from /lib64/libc.so.6
No symbol table info available.
#4 0x000000000045fc2a in MHD_cleanup_connections (daemon=0x28d8bf0) at microhttpd/daemon.c:2038
pos = 0x7fb4f00009c0
#5 0x000000000045ff54 in MHD_get_daemon_info (daemon=0x28cf9f0, info_type=<value optimized out>) at microhttpd/daemon.c:4630
i = <value optimized out>
# MHD-Thread
#0 0x0000003bd720e264 in __lll_lock_wait () from /lib64/libpthread.so.0
No symbol table info available.
#1 0x0000003bd7209508 in _L_lock_854 () from /lib64/libpthread.so.0
No symbol table info available.
#2 0x0000003bd72093d7 in pthread_mutex_lock () from /lib64/libpthread.so.0
No symbol table info available.
#3 0x00000000006c73fe in http_NotifyConnectionCallback (cls=0x7fff32d7a1e0, connection=<value optimized out>, socket_context=<value optimized out>, toe=<value optimized out>) at global/daemon.cpp:1782
daemonqueue = 0x7fff32d7a1e0
#4 0x000000000045fc5a in MHD_cleanup_connections (daemon=0x28d8bf0) at microhttpd/daemon.c:2046
pos = 0x7fb4f00009c0
#5 0x0000000000463a25 in MHD_select_thread (cls=0x28d8bf0) at microhttpd/daemon.c:2937
daemon = 0x28d8bf0
#6 0x0000003bd72079d1 in start_thread () from /lib64/libpthread.so.0
No symbol table info available.
#7 0x0000003bd6ee88fd in clone () from /lib64/libc.so.6
No symbol table info available.
Am Samstag, den 18.07.2015, 16:31 +0200 schrieb Christian Grothoff:Hi! I'm sorry, but I still don't even see how the race could happen. I checked all calls to MHD_pool_destroy, and the respective connection is always in 1 of 3 disjoint ownership states: 1) never aliased, about to be freed (failures during connection setup) 2) 'active' connection, going down without keep-alive, pool is freed 'early' during the handler thread (technically not necessary, we could keep it around until case (3), but that'd keep the RAM busy longer than necessary). This should only happen from the thread that handles everything wrt. this connection. 3) MHD_cleanup_connections going over all connections that are really dead; here, a lock is used. Note that in 1&2, MHD_cleanup_connections() would never touch that pool, as it is not in the respective DLL. So sorry, I cannot reproduce your issue. Again, a testcase would be very helpful... As for the need of the info call to invoke cleanup: it is necessary, as otherwise the counter could be way off (I think especially in the case you describe, it could cause non-termination to not call cleanup). Now, the MHD_pool_destroy in connection.c, that one should be truly harmless to remove, so you could safely play with that... Happy hacking! -Christian On 07/17/2015 09:57 AM, Markus Doppelbauer wrote: > Sorry the NULL patch is the wrong fix - it makes it only more > unlikely to double-free() the pool. The scheduler could interrupt > right before "pos->pool = NULL". > > Maybe the only solution is either to protect "MHD_cleanup_connections()" > with a mutex or to remove the call to "MHD_cleanup_connections()" > in "MHD_DAEMON_INFO_CURRENT_CONNECTIONS". > > Thanks a lot > Markus > > > > Am Donnerstag, den 16.07.2015, 22:13 +0200 schrieb Markus Doppelbauer: >> Hello, >> >> Maybe simply nullify "pos->pool" after MHD_pool_destroy()"? >> Should avoid this double-free(). >> >> Or is there a chance to get the number of open connections >> without calling "MHD_cleanup_connections()"? >> >> Thanks a lot >> Markus >> >> >> } >> } >> MHD_pool_destroy (pos->pool); >> + pos->pool = NULL; >> #if HTTPS_SUPPORT >> if (NULL != pos->tls_session) >> gnutls_deinit (pos->tls_session); >> >
[Prev in Thread] | Current Thread | [Next in Thread] |