【问题标题】:Sending signal to thread from annother non-process and logging stack not happening从另一个非进程向线程发送信号并且日志堆栈没有发生
【发布时间】:2014-01-27 12:53:35
【问题描述】:

我正在尝试从另一个进程(而不是从创建该线程的进程)向 POSIX 线程发送信号。我使用 kill(...)::

发送信号的操作
int trap_handle(pid_t child_waited )
 69 {
 70     printf("%s, new value: %d, child_waited=<%ld>\n", __func__,g_var_x, child_waited);
 71     int errno_ = -1;
 72     errno_ = kill(child_waited, SIGUSR1);
 73     //syscall(SYS_tgkill, -1, child_waited, SIGUSR1);
 74     //errno_ = pthread_kill(child_waited, SIGUSR1);
 75     if(0==errno_)
 76         printf("Signal sent to thread: %ld\n", child_waited);
 77     else
 78         printf("pthread_kill failed: error:%d", errno_);
 79 }

并且在注册了 SIGUSR1 的线程中:

230 void baz() {
231     g_var_x++;
232 }
233
234 void bak() { baz(); }
235 void bar() { bak(); }
236 void foo() { bar(); }
237
238 void stack_dump()
239 {
240     printf("******trap() entry ******\n");
241     void *array[100];
242     size_t size;
243     // get void*'s for all entries on the stack
244     size = backtrace(array, 100);
245
246     // print out all the frames to stderr
247 //    fprintf(stderr, "Error: signal %d:\n", sig);
248     backtrace_symbols_fd(array, size, STDERR_FILENO);
249     printf("*******trap() exit ******\n");
250 }
251
252 void* thread_proc_one(void *lParam)
253 {
254     printf("--Entry: thread_one debugee tid<%ld> \n", syscall(SYS_gettid));
255     g_arg_params.debugee_tid =  syscall(SYS_gettid);
256
257     struct sigaction trap_action;
258     //printf("Childprocess <tid> %d\n", syscall (SYS_gettid));
259     memset(&trap_action, 0, sizeof(trap_action));
260     sigaction(SIGUSR1, NULL, &trap_action);
261     trap_action.sa_sigaction = stack_dump;
262     trap_action.sa_flags = SA_SIGINFO | SA_RESTART | SA_NODEFER;
263     sigaction(SIGUSR1, &trap_action, NULL);
....

现在预计它将回溯 Thraed 堆栈,而不是调用它的主进程。但没有发生。 stack_dump 被调用,但不是记录线程堆栈,而是记录其父堆栈。回溯显示创建此 thread_proc_one 线程的进程堆栈。

这里有人遇到过这个问题吗? 希望我清楚。

【问题讨论】:

标签: c++ c linux multithreading signals


【解决方案1】:

sigaction() 为整个进程安装一个信号处理程序。

来自man sigaction(我的斜体):

sigaction() 系统调用用于更改进程 在接收到特定信号时所采取的操作。

哪个进程的线程处理它留给操作系统。

来自man 7 signal

信号处置是每个进程的属性:在多线程中 应用程序,一个特定的信号的处置是相同的 所有线程。

要确保某个信号由特定线程处理,请使用pthread_sigmask() 屏蔽除处理它的线程之外的所有线程的信号。

再次来自man 7 signal

进程中的每个线程都有一个独立的信号掩码,它 指示线程当前阻塞的信号集。 线程可以使用 pthread_sigmask(3) 操作其信号掩码。

因此,例如,这可以通过在创建任何线程之前在主线程中调用 pthread_sigmask() 屏蔽相关信号来完成,然后在线程内部再次处理信号调用 pthread_sigmask() 以取消屏蔽要处理的信号。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-09-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-22
    • 1970-01-01
    • 2012-03-24
    相关资源
    最近更新 更多