我正在尝试从另一个进程向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,但不记录线程堆栈,而是记录其父堆栈。 Backtrace显示创建此thread_proc_one线程的进程的堆栈。
这里有人遇到过这个问题吗? 希望我很清楚。
答案 0 :(得分:1)
sigaction()
为整个过程安装信号处理程序。
来自我man sigaction
(斜体):
sigaction()系统调用用于更改进程在收到特定信号时所采取的操作。
哪个进程'线程处理它留给操作系统。
来自man 7 signal
:
信号处理是一个每进程属性:在多线程中 应用程序,特定信号的配置是相同的 所有线程。
为了确保特定线程处理某个信号,请使用pthread_sigmask()
来屏蔽所有线程的信号,但是要处理它的信号。
再次来自man 7 signal
:
进程中的每个线程都有一个独立的信号掩码 表示线程当前阻塞的信号集。 线程可以使用 pthread_sigmask(3)操作其信号掩码。
因此,例如,这可以通过主线程中的callîngpthread_sigmask()
在创建任何线程之前屏蔽所讨论的信号,然后在线程内处理信号调用pthread_sigmask()
来完成再次取消屏蔽要处理的信号。