Occasional crash during shutdown when using Tor API
This is using a JNI wrapper.
I can probably create a test case for easier debugging. It seems like this is a race condition within the new pubsub system. I can reproduce this with an example program that configures Tor via the API and sends a SIGNAL TERM
shortly after tor begins running and the control socket becomes available.
(gdb) bt
#0 __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:50
#1 0x00007f8bcc822535 in __GI_abort () at abort.c:79
#2 0x00007f8b94b01dbe in tor_raw_abort_ () at src/lib/err/torerr.c:227
#3 0x00007f8b94b016d0 in crash_handler (sig=<optimized out>, si=<optimized out>, ctx_=<optimized out>) at src/lib/err/backtrace.c:175
#4 <signal handler called>
#5 0x00007f8b94ae0ae4 in max_in_sl (sl=<optimized out>, sl=<optimized out>, dflt=0) at src/lib/dispatch/dispatch_new.c:36
#6 dispatch_new (cfg=0x7f8b64033520) at src/lib/dispatch/dispatch_new.c:121
#7 0x00007f8b94ade9ac in pubsub_builder_finalize (builder=0x7f8b64029eb0, items_out=0x7f8b94c193b8 <the_pubsub_items>) at src/lib/pubsub/pubsub_build.c:293
#8 0x00007f8b9496666c in tor_mainloop_connect_pubsub (builder=0x7f8b64029eb0) at src/core/mainloop/mainloop_pubsub.c:56
#9 0x00007f8b94952741 in pubsub_install () at src/app/main/main.c:1246
#10 tor_run_main (tor_cfg=<optimized out>) at src/app/main/main.c:1297
#11 0x00007f8b9495034c in RunMain (env=0x7f8bc4250b18, thisObj=0x7f8b9431d9b8) at src/feature/api/TorApi.cc:179
#12 0x00007f8b949502dd in Java_api_TorApi_runMain (env=0x7f8bc4250b18, thisObj=0x7f8b9431d9b8) at src/feature/api/TorApi.cc:279
#13 0x00007f8bac8d4990 in ?? ()
#14 0x00007f8bac8ce450 in ?? ()
#15 0x0000000718c7c3a8 in ?? ()
#16 0x00007f8b9431d950 in ?? ()
#17 0x0000000000000000 in ?? ()
Bisecting found a8c0f4ddfe3f0a63bd499959c8d921346aa9766e is the first bad commit
.
The fault is at the first dereference (i don't know if it's *u
or *maxptr
). I'm guessing the memory was already freed for exit by the time this procedure is called.
29 static int
30 max_in_sl(const smartlist_t *sl, int dflt)
31 {
32 uint16_t *maxptr = NULL;
33 SMARTLIST_FOREACH_BEGIN(sl, uint16_t *, u) {
34 if (!maxptr)
35 maxptr = u;
36 else if (*u > *maxptr)
37 maxptr = u;
38 } SMARTLIST_FOREACH_END(u);
39
40 return maxptr ? *maxptr : dflt;
41 }
Tor was configured with --Log "notice stdout" --AvoidDiskWrites 1 --SocksPort unix:${HOME}/private_tor/test_socks --DisableNetwork 0
.
This shouldn't be a common edge case, but I stumbled upon it while testing something else.