Reputation: 374
I am trying to send signal to a POSIX thread from another process (Not from the process that created that thread. What I did to send signal using 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 }
And in a thread that registered 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);
....
Now This is expected that it will backtrace the Thraed stack not the main process that invoked it. But is not happening. stack_dump is called, but instead of logging thread stack, it is logging its parents stack. Backtrace is showing stack of the process that created this thread_proc_one thread.
Anyone here faced this issue? Hope I am clear.
Upvotes: 2
Views: 254
Reputation: 70951
sigaction()
installs a signal handler for the whole process.
From man sigaction
(italics by me):
The sigaction() system call is used to change the action taken by a process on receipt of a specific signal.
Which of the process' threads handles it is left to the OS.
From man 7 signal
:
The signal disposition is a per-process attribute: in a multithreaded application, the disposition of a particular signal is the same for all threads.
To make sure a certain signal is handled by a specific thread use pthread_sigmask()
to mask out the signal for all threads but the one to handle it.
Again from man 7 signal
:
Each thread in a process has an independent signal mask, which indicates the set of signals that the thread is currently blocking. A thread can manipulate its signal mask using pthread_sigmask(3).
So this, for example, could be done by callîng pthread_sigmask()
in the main thread masking out the signal in question prior to creating any thread, and then inside the thread to handle the signal call pthread_sigmask()
again to unmask the signal to be handled.
Upvotes: 1