Skip to content

SIGTERM is not always handled properly in ServerApplication #2774

@akete

Description

@akete

When implementing "heavily multi-threaded" ServerApplication, approximately 1 in 10 runs terminates with unhandled SIGTERM.

  • Poco version: 2.0.0 (develop branch, commit a4a0052)
  • Platform: Linux 64-bit (Ubuntu 18.04)
  • How to reproduce (also see reproduce.zip):
    • Build poco_app, like: g++ -g -Og -O2 poco_app.cc -o poco_app -lPocoFoundation -lPocoUtil -lpthread
    • run reproduce.sh (runs application in gdb and sends SIGTERM to it after short delay)
    • gdb will (approx. 1 in 10) report something like:
Thread 2 "poco_app" received signal SIGTERM, Terminated.
[Switching to Thread 0x7ffff5010700 (LWP 14919)]
clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:78
78      ../sysdeps/unix/sysv/linux/x86_64/clone.S: No such file or directory.
#0  clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:78
#1  0x00007ffff754cec5 in create_thread (thread_ran=<synthetic pointer>, stackaddr=0x7fffef7fdfc0, stopped_start=<synthetic pointer>, attr=0x7ffff500fde0, pd=0x7fffef7fe700) at ../sysdeps/unix/sysv/linux/createthread.c:100
#2  __pthread_create_2_1 (newthread=<optimized out>, attr=<optimized out>, start_routine=<optimized out>, arg=0x7ffff0000b20) at pthread_create.c:797
#3  0x00007ffff7279925 in std::thread::_M_start_thread(std::unique_ptr<std::thread::_State, std::default_delete<std::thread::_State> >, void (*)()) () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#4  0x0000555555555d1c in std::thread::thread<std::_Bind<void (MyServerApp::*(MyServerApp*))()>>(std::_Bind<void (MyServerApp::*(MyServerApp*))()>&&) (__f=..., this=0x7ffff500fe78) at /usr/include/c++/7/thread:126
#5  MyServerApp::controller (this=0x7fffffffe700) at poco_app.cc:39
#6  0x00007ffff727966f in ?? () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#7  0x00007ffff754c6db in start_thread (arg=0x7ffff5010700) at pthread_create.c:463
#8  0x00007ffff6cd488f in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:95

It seems that signal mask is not inherited by threads that are created before call to ServerApplication::waitForTerminationRequest() (which applies the mask). If mask is applied before any other thread is created, this issue does not present. (see poco_app.cc in attached archive.

  • Possible solutions:
    • apply signal mask in ServerApplication before calling initialize()
    • add additional member like ServerApplication::willUseWaitForTerminationRequestInMultithreadedApplication() that should be called before any additional threads are created and apply signal mask there.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions