Node.js calls beginExit, and we free our app.
Problem is, Node.js can still trigger a timer event after this point and crash at tear-down due to our timer using freed memory:
Exiting now
=================================================================
==22228==ERROR: AddressSanitizer: heap-use-after-free on address 0x6110000174c8 at pc 0x7f2442bf82fc bp 0x7ffdbf7f65b0 sp 0x7ffdbf7f65a0
READ of size 8 at 0x6110000174c8 thread T0
#0 0x7f2442bf82fb in sweep_timer_cb (/home/alexhultman/uWebSockets.js/dist/uws_linux_64.node+0x1022fb)
#1 0xa438b4 in uv__run_timers ../deps/uv/src/timer.c:174
#2 0xa47bab in uv_run ../deps/uv/src/unix/core.c:361
#3 0x8bea0d in node::Environment::CleanupHandles() (/usr/bin/node+0x8bea0d)
#4 0x8beda8 in node::Environment::RunCleanup() (/usr/bin/node+0x8beda8)
#5 0x8e533b in node::Start(v8::Isolate*, node::IsolateData*, std::vector<std::string, std::allocator<std::string> > const&, std::vector<std::string, std::allocator<std::string> > const&) (/usr/bin/node+0x8e533b)
#6 0x8e34a1 in node::Start(int, char**) (/usr/bin/node+0x8e34a1)
#7 0x7f245030ab96 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21b96)
#8 0x89dd44 (/usr/bin/node+0x89dd44)
0x6110000174c8 is located 8 bytes inside of 208-byte region [0x6110000174c0,0x611000017590)
freed by thread T0 here:
#0 0x7f24517227b8 in __interceptor_free (/usr/lib/x86_64-linux-gnu/libasan.so.4+0xde7b8)
#1 0x7f2442bd9d7d in void uWS_App_forcefully_free<uWS::TemplatedApp<false> >(v8::FunctionCallbackInfo<v8::Value> const&) (/home/alexhultman/uWebSockets.js/dist/uws_linux_64.node+0xe3d7d)
previously allocated by thread T0 here:
#0 0x7f2451722b50 in __interceptor_malloc (/usr/lib/x86_64-linux-gnu/libasan.so.4+0xdeb50)
#1 0x7f2442bf6ac2 in us_create_child_socket_context (/home/alexhultman/uWebSockets.js/dist/uws_linux_64.node+0x100ac2)
#2 0x7f2442bd8d41 in void uWS_App_ws<uWS::TemplatedApp<false> >(v8::FunctionCallbackInfo<v8::Value> const&) (/home/alexhultman/uWebSockets.js/dist/uws_linux_64.node+0xe2d41)
#3 0xb5faee in v8::internal::MaybeHandle<v8::internal::Object> v8::internal::(anonymous namespace)::HandleApiCallHelper<false>(v8::internal::Isolate*, v8::internal::Handle<v8::internal::HeapObject>, v8::internal::Handle<v8::internal::HeapObject>, v8::internal::Handle<v8::internal::FunctionTemplateInfo>, v8::internal::Handle<v8::internal::Object>, v8::internal::BuiltinArguments) (/usr/bin/node+0xb5faee)
#4 0xb60658 in v8::internal::Builtin_HandleApiCall(int, v8::internal::Object**, v8::internal::Isolate*) (/usr/bin/node+0xb60658)
#5 0x7f244305be1c (<unknown module>)
#6 0x7f24430118d4 (<unknown module>)
#7 0x7f24430118d4 (<unknown module>)
#8 0x7f24430118d4 (<unknown module>)
#9 0x7f24430118d4 (<unknown module>)
#10 0x7f24430118d4 (<unknown module>)
#11 0x7f24430118d4 (<unknown module>)
#12 0x7f24430118d4 (<unknown module>)
#13 0x7f24430118d4 (<unknown module>)
#14 0x7f24430118d4 (<unknown module>)
#15 0x7f244300ee74 (<unknown module>)
#16 0x7f24430092c0 (<unknown module>)
#17 0xe6f612 in v8::internal::Execution::Call(v8::internal::Isolate*, v8::internal::Handle<v8::internal::Object>, v8::internal::Handle<v8::internal::Object>, int, v8::internal::Handle<v8::internal::Object>*) (/usr/bin/node+0xe6f612)
#18 0xafce98 in v8::Function::Call(v8::Local<v8::Context>, v8::Local<v8::Value>, int, v8::Local<v8::Value>*) (/usr/bin/node+0xafce98)
#19 0x8de029 in node::LoadEnvironment(node::Environment*) (/usr/bin/node+0x8de029)
#20 0x8e515f in node::Start(v8::Isolate*, node::IsolateData*, std::vector<std::string, std::allocator<std::string> > const&, std::vector<std::string, std::allocator<std::string> > const&) (/usr/bin/node+0x8e515f)
#21 0x8e34a1 in node::Start(int, char**) (/usr/bin/node+0x8e34a1)
#22 0x7f245030ab96 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21b96)
SUMMARY: AddressSanitizer: heap-use-after-free (/home/alexhultman/uWebSockets.js/dist/uws_linux_64.node+0x1022fb) in sweep_timer_cb
Shadow bytes around the buggy address:
0x0c227fffae40: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c227fffae50: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c227fffae60: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c227fffae70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c227fffae80: 00 00 00 00 00 00 00 00 00 00 00 fa fa fa fa fa
=>0x0c227fffae90: fa fa fa fa fa fa fa fa fd[fd]fd fd fd fd fd fd
0x0c227fffaea0: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
0x0c227fffaeb0: fd fd fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c227fffaec0: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
0x0c227fffaed0: fd fd fd fd fd fd fd fd fd fd fd fd fa fa fa fa
0x0c227fffaee0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
Addressable: 00
Partially addressable: 01 02 03 04 05 06 07
Heap left redzone: fa
Freed heap region: fd
Stack left redzone: f1
Stack mid redzone: f2
Stack right redzone: f3
Stack after return: f5
Stack use after scope: f8
Global redzone: f9
Global init order: f6
Poisoned by user: f7
Container overflow: fc
Array cookie: ac
Intra object redzone: bb
ASan internal: fe
Left alloca redzone: ca
Right alloca redzone: cb
==22228==ABORTING