How to determine if code is running in signal-handler context?
up vote
11
down vote
favorite
I just found out that someone is calling - from a signal handler - a definitely not async-signal-safe function that I wrote.
So, now I'm curious: how to circumvent this situation from happening again? I'd like to be able to easily determine if my code is running in signal handler context (language is C, but wouldn't the solution apply to any language?):
int myfunc( void )
if( in_signal_handler_context() ) return(-1)
// rest of function goes here
return( 0 );
This is under Linux.
Hope this isn't an easy answer, or else I'll feel like an idiot.
linux signals handler
add a comment |
up vote
11
down vote
favorite
I just found out that someone is calling - from a signal handler - a definitely not async-signal-safe function that I wrote.
So, now I'm curious: how to circumvent this situation from happening again? I'd like to be able to easily determine if my code is running in signal handler context (language is C, but wouldn't the solution apply to any language?):
int myfunc( void )
if( in_signal_handler_context() ) return(-1)
// rest of function goes here
return( 0 );
This is under Linux.
Hope this isn't an easy answer, or else I'll feel like an idiot.
linux signals handler
add a comment |
up vote
11
down vote
favorite
up vote
11
down vote
favorite
I just found out that someone is calling - from a signal handler - a definitely not async-signal-safe function that I wrote.
So, now I'm curious: how to circumvent this situation from happening again? I'd like to be able to easily determine if my code is running in signal handler context (language is C, but wouldn't the solution apply to any language?):
int myfunc( void )
if( in_signal_handler_context() ) return(-1)
// rest of function goes here
return( 0 );
This is under Linux.
Hope this isn't an easy answer, or else I'll feel like an idiot.
linux signals handler
I just found out that someone is calling - from a signal handler - a definitely not async-signal-safe function that I wrote.
So, now I'm curious: how to circumvent this situation from happening again? I'd like to be able to easily determine if my code is running in signal handler context (language is C, but wouldn't the solution apply to any language?):
int myfunc( void )
if( in_signal_handler_context() ) return(-1)
// rest of function goes here
return( 0 );
This is under Linux.
Hope this isn't an easy answer, or else I'll feel like an idiot.
linux signals handler
linux signals handler
edited Nov 11 at 1:04
AkaZecik
8129
8129
asked Jan 28 '11 at 20:27
smcdow
2221510
2221510
add a comment |
add a comment |
6 Answers
6
active
oldest
votes
up vote
7
down vote
accepted
Apparently, newer Linux/x86 (probably since some 2.6.x kernel) calls signal handlers from the vdso
. You could use this fact to inflict the following horrible hack upon the unsuspecting world:
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <signal.h>
#include <unistd.h>
uintmax_t vdso_start = 0;
uintmax_t vdso_end = 0; /* actually, next byte */
int check_stack_for_vdso(uint32_t *esp, size_t len)
size_t i;
for (i = 0; i < len; i++, esp++)
if (*esp >= vdso_start && *esp < vdso_end)
return 1;
return 0;
void handler(int signo)
uint32_t *esp;
__asm__ __volatile__ ("mov %%esp, %0" : "=r"(esp));
/* XXX only for demonstration, don't call printf from a signal handler */
printf("handler: check_stack_for_vdso() = %dn", check_stack_for_vdso(esp, 20));
void parse_maps()
FILE *maps;
char buf[256];
char path[7];
uintmax_t start, end, offset, inode;
char r, w, x, p;
unsigned major, minor;
maps = fopen("/proc/self/maps", "rt");
if (maps == NULL)
return;
while (!feof(maps) && !ferror(maps))
if (fgets(buf, 256, maps) != NULL)
if (sscanf(buf, "%jx-%jx %c%c%c%c %jx %u:%u %ju %6s",
&start, &end, &r, &w, &x, &p, &offset,
&major, &minor, &inode, path) == 11)
if (!strcmp(path, "[vdso]"))
vdso_start = start;
vdso_end = end;
break;
fclose(maps);
printf("[vdso] at %jx-%jxn", vdso_start, vdso_end);
int main()
struct sigaction sa;
uint32_t *esp;
parse_maps();
memset(&sa, 0, sizeof(struct sigaction));
sa.sa_handler = handler;
sa.sa_flags = SA_RESTART;
if (sigaction(SIGUSR1, &sa, NULL) < 0)
perror("sigaction");
exit(1);
__asm__ __volatile__ ("mov %%esp, %0" : "=r"(esp));
printf("before kill: check_stack_for_vdso() = %dn", check_stack_for_vdso(esp, 20));
kill(getpid(), SIGUSR1);
__asm__ __volatile__ ("mov %%esp, %0" : "=r"(esp));
printf("after kill: check_stack_for_vdso() = %dn", check_stack_for_vdso(esp, 20));
return 0;
SCNR.
I wasn't aware that signal handlers were called from the vdso. Could you point to a reference? At any rate, I like this hack. A lot. It'd be easy enough to roll this up into a opaque library. The trick would be making sure that parse_maps() was called before any signal handlers.
– smcdow
Jan 28 '11 at 22:40
The best reference I can find is lxr.free-electrons.com/source/arch/x86/kernel/…
– ninjalj
Jan 28 '11 at 23:10
But the comment at line 320 looks interesting: lxr.free-electrons.com/source/arch/x86/kernel/…
– ninjalj
Jan 28 '11 at 23:11
We're running on stock RHEL-5 distros -- Linux-2.6.18, so maybe I'll be able to use this. I'll write up a test case next week (which really means that I'll copy-and-paste your code to see what it does :-). Thanks.
– smcdow
Jan 29 '11 at 16:47
add a comment |
up vote
3
down vote
If we can assume your application doesn't manually block signals using sigprocmask()
or pthread_sigmask()
, then this is pretty simple: get your current thread ID (tid
). Open /proc/tid/status
and get the values for SigBlk
and SigCgt
. AND
those two values. If the result of that AND
is non-zero, then that thread is currently running from inside a signal handler. I've tested this myself and it works.
You'd need the process ID (PID), not the thread ID. And doing this will involve calling non-async-signal-safe functions, barring writing your own.
– mgarey
Mar 8 at 21:55
1
@mgarey good point, make sure you do this only using async-signal safe functions such as the open() and read() system calls which is definitely doable. However if the program is multithreaded then you MUST use tid which will differ from pid. Being inside a signal handler is a thread specific state.
– David Yeager
May 6 at 21:56
David, you are quite right - I stand corrected.
– mgarey
May 7 at 17:15
add a comment |
up vote
0
down vote
There are two proper ways to deal with this:
Have your co-workers stop doing the wrong thing. Good luck pulling this off with the boss, though...
Make your function re-entrant and async-safe. If necessary, provide a function with a different signature (e.g. using the widely-used
*_r
naming convention) with the additional arguments that are necessary for state preservation.
As for the non-proper way to do this, on Linux with GNU libc you can use backtrace()
and friends to go through the caller list of your function. It's not easy to get right, safe or portable, but it might do for a while:
/*
* *** Warning ***
*
* Black, fragile and unportable magic ahead
*
* Do not use this, lest the daemons of hell be unleashed upon you
*/
int in_signal_handler_context()
int i, n;
void *bt[1000];
char **bts = NULL;
n = backtrace(bt, 1000);
bts = backtrace_symbols(bt, n);
for (i = 0; i < n; ++i)
printf("%i - %sn", i, bts[i]);
/* Have a look at the caller chain */
for (i = 0; i < n; ++i)
/* Far more checks are needed here to avoid misfires */
if (strstr(bts[i], "(__libc_start_main+") != NULL)
return 0;
if (strstr(bts[i], "libc.so.6(+") != NULL)
return 1;
return 0;
void unsafe()
if (in_signal_handler_context())
printf("John, you know you are an idiot, right?n");
In my opinion, it might just be better to quit rather than be forced to write code like this.
I've just triedbacktrace()
, and it just doesn't work:__libc_start_main
is in the trace both in and out of signal handling context.
– P Shved
Jan 28 '11 at 21:42
As I mentioned, it's not easy to get right. You have to find a difference in the backtrace between the two cases and use that. E.g for my test I assumed that no libc function would be in the backtrace before reachingmain()
, unless it's the signal handling code. What does your backtrace look like in each case?
– thkala
Jan 28 '11 at 21:45
Two comments: (1) I was afraid it might be something like this. (2) Not to be a snot, but printf(3) is not an async-signal-safe function. You'd have to use write(2). -- A list of async-signal-safe functions (at least, the list that I usually refer to) can be found here: pubs.opengroup.org/onlinepubs/009695399/functions/…
– smcdow
Jan 28 '11 at 21:49
This is why I avoided trying to give a direct answer at all. What you are asking for requires a hack as @thkala has proposed. Hence, it is probably better to find a diplomatic solution.
– Judge Maygarden
Jan 28 '11 at 21:51
@smcdow: I know quite well thatprintf()
is not async safe - but neither is the function that's using it (i.e. your function) :-)
– thkala
Jan 28 '11 at 21:55
|
show 5 more comments
up vote
0
down vote
You could work out something using sigaltstack. Set up an alternative signal stack, get the stack pointer in some async-safe way, if within the alternative stack go on, otherwise abort().
I thought about something like that, but I don't think I could guarantee that I'd have the alternate stack set up before my function was called from a signal handler. I should also reiterate that my function is NEVER supposed to be called from a signal handler, and the documentation says so.
– smcdow
Jan 28 '11 at 21:58
There's an easier way.sigaltstack
is required to return an error if you're already running on the alternate stack and try to make changes to it, so you could just try calling it and see if the call fails.
– R..
Mar 22 '11 at 20:40
add a comment |
up vote
0
down vote
I guess you need to do the following. This is a complex solution, which combines the best practices not only from coding, but from software engineering as well!
- Persuade your boss that naming convention on signal handlers is a good thing. Propose, for example, a Hungarian notation, and tell that it was used in Microsoft with great success.
So, all signal handlers will start withsighnd
, likesighndInterrupt
. - Your function that detects signal handling context would do the following:
- Get the
backtrace()
. - Look if any of the functions in it begin with
sighnd...
. If it does, then congratulations, you're inside a signal handler! - Otherwise, you're not.
- Get the
- Try to avoid working with Jimmy in the same company. "There can be only one", you know.
We're going to have a janitor make a pass over the code base and report back any and all functions being called from signal handlers. I'm cringing already.
– smcdow
Jan 28 '11 at 21:59
@smcdow, by the way, you could employ a static analysis tool for that. But then again, you'd have to annotate each signal handler, which makes the solution proposed not any more complex. :-)
– P Shved
Jan 28 '11 at 22:07
some time ago there was a Valgrind tool to look for signal handler problems, it was called crocus.
– ninjalj
Jan 28 '11 at 22:25
@ninjalj, Valgrind is a dynamic analysis tool, not a static one. Anyway, I've just devised a way to do it statically, but that's quite off-topic here.
– P Shved
Jan 28 '11 at 22:28
add a comment |
up vote
0
down vote
for code optimized at -O2 or better (istr) have found need to add -fno-omit-frame-pointer
else gcc will optimize out the stack context information
add a comment |
6 Answers
6
active
oldest
votes
6 Answers
6
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
7
down vote
accepted
Apparently, newer Linux/x86 (probably since some 2.6.x kernel) calls signal handlers from the vdso
. You could use this fact to inflict the following horrible hack upon the unsuspecting world:
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <signal.h>
#include <unistd.h>
uintmax_t vdso_start = 0;
uintmax_t vdso_end = 0; /* actually, next byte */
int check_stack_for_vdso(uint32_t *esp, size_t len)
size_t i;
for (i = 0; i < len; i++, esp++)
if (*esp >= vdso_start && *esp < vdso_end)
return 1;
return 0;
void handler(int signo)
uint32_t *esp;
__asm__ __volatile__ ("mov %%esp, %0" : "=r"(esp));
/* XXX only for demonstration, don't call printf from a signal handler */
printf("handler: check_stack_for_vdso() = %dn", check_stack_for_vdso(esp, 20));
void parse_maps()
FILE *maps;
char buf[256];
char path[7];
uintmax_t start, end, offset, inode;
char r, w, x, p;
unsigned major, minor;
maps = fopen("/proc/self/maps", "rt");
if (maps == NULL)
return;
while (!feof(maps) && !ferror(maps))
if (fgets(buf, 256, maps) != NULL)
if (sscanf(buf, "%jx-%jx %c%c%c%c %jx %u:%u %ju %6s",
&start, &end, &r, &w, &x, &p, &offset,
&major, &minor, &inode, path) == 11)
if (!strcmp(path, "[vdso]"))
vdso_start = start;
vdso_end = end;
break;
fclose(maps);
printf("[vdso] at %jx-%jxn", vdso_start, vdso_end);
int main()
struct sigaction sa;
uint32_t *esp;
parse_maps();
memset(&sa, 0, sizeof(struct sigaction));
sa.sa_handler = handler;
sa.sa_flags = SA_RESTART;
if (sigaction(SIGUSR1, &sa, NULL) < 0)
perror("sigaction");
exit(1);
__asm__ __volatile__ ("mov %%esp, %0" : "=r"(esp));
printf("before kill: check_stack_for_vdso() = %dn", check_stack_for_vdso(esp, 20));
kill(getpid(), SIGUSR1);
__asm__ __volatile__ ("mov %%esp, %0" : "=r"(esp));
printf("after kill: check_stack_for_vdso() = %dn", check_stack_for_vdso(esp, 20));
return 0;
SCNR.
I wasn't aware that signal handlers were called from the vdso. Could you point to a reference? At any rate, I like this hack. A lot. It'd be easy enough to roll this up into a opaque library. The trick would be making sure that parse_maps() was called before any signal handlers.
– smcdow
Jan 28 '11 at 22:40
The best reference I can find is lxr.free-electrons.com/source/arch/x86/kernel/…
– ninjalj
Jan 28 '11 at 23:10
But the comment at line 320 looks interesting: lxr.free-electrons.com/source/arch/x86/kernel/…
– ninjalj
Jan 28 '11 at 23:11
We're running on stock RHEL-5 distros -- Linux-2.6.18, so maybe I'll be able to use this. I'll write up a test case next week (which really means that I'll copy-and-paste your code to see what it does :-). Thanks.
– smcdow
Jan 29 '11 at 16:47
add a comment |
up vote
7
down vote
accepted
Apparently, newer Linux/x86 (probably since some 2.6.x kernel) calls signal handlers from the vdso
. You could use this fact to inflict the following horrible hack upon the unsuspecting world:
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <signal.h>
#include <unistd.h>
uintmax_t vdso_start = 0;
uintmax_t vdso_end = 0; /* actually, next byte */
int check_stack_for_vdso(uint32_t *esp, size_t len)
size_t i;
for (i = 0; i < len; i++, esp++)
if (*esp >= vdso_start && *esp < vdso_end)
return 1;
return 0;
void handler(int signo)
uint32_t *esp;
__asm__ __volatile__ ("mov %%esp, %0" : "=r"(esp));
/* XXX only for demonstration, don't call printf from a signal handler */
printf("handler: check_stack_for_vdso() = %dn", check_stack_for_vdso(esp, 20));
void parse_maps()
FILE *maps;
char buf[256];
char path[7];
uintmax_t start, end, offset, inode;
char r, w, x, p;
unsigned major, minor;
maps = fopen("/proc/self/maps", "rt");
if (maps == NULL)
return;
while (!feof(maps) && !ferror(maps))
if (fgets(buf, 256, maps) != NULL)
if (sscanf(buf, "%jx-%jx %c%c%c%c %jx %u:%u %ju %6s",
&start, &end, &r, &w, &x, &p, &offset,
&major, &minor, &inode, path) == 11)
if (!strcmp(path, "[vdso]"))
vdso_start = start;
vdso_end = end;
break;
fclose(maps);
printf("[vdso] at %jx-%jxn", vdso_start, vdso_end);
int main()
struct sigaction sa;
uint32_t *esp;
parse_maps();
memset(&sa, 0, sizeof(struct sigaction));
sa.sa_handler = handler;
sa.sa_flags = SA_RESTART;
if (sigaction(SIGUSR1, &sa, NULL) < 0)
perror("sigaction");
exit(1);
__asm__ __volatile__ ("mov %%esp, %0" : "=r"(esp));
printf("before kill: check_stack_for_vdso() = %dn", check_stack_for_vdso(esp, 20));
kill(getpid(), SIGUSR1);
__asm__ __volatile__ ("mov %%esp, %0" : "=r"(esp));
printf("after kill: check_stack_for_vdso() = %dn", check_stack_for_vdso(esp, 20));
return 0;
SCNR.
I wasn't aware that signal handlers were called from the vdso. Could you point to a reference? At any rate, I like this hack. A lot. It'd be easy enough to roll this up into a opaque library. The trick would be making sure that parse_maps() was called before any signal handlers.
– smcdow
Jan 28 '11 at 22:40
The best reference I can find is lxr.free-electrons.com/source/arch/x86/kernel/…
– ninjalj
Jan 28 '11 at 23:10
But the comment at line 320 looks interesting: lxr.free-electrons.com/source/arch/x86/kernel/…
– ninjalj
Jan 28 '11 at 23:11
We're running on stock RHEL-5 distros -- Linux-2.6.18, so maybe I'll be able to use this. I'll write up a test case next week (which really means that I'll copy-and-paste your code to see what it does :-). Thanks.
– smcdow
Jan 29 '11 at 16:47
add a comment |
up vote
7
down vote
accepted
up vote
7
down vote
accepted
Apparently, newer Linux/x86 (probably since some 2.6.x kernel) calls signal handlers from the vdso
. You could use this fact to inflict the following horrible hack upon the unsuspecting world:
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <signal.h>
#include <unistd.h>
uintmax_t vdso_start = 0;
uintmax_t vdso_end = 0; /* actually, next byte */
int check_stack_for_vdso(uint32_t *esp, size_t len)
size_t i;
for (i = 0; i < len; i++, esp++)
if (*esp >= vdso_start && *esp < vdso_end)
return 1;
return 0;
void handler(int signo)
uint32_t *esp;
__asm__ __volatile__ ("mov %%esp, %0" : "=r"(esp));
/* XXX only for demonstration, don't call printf from a signal handler */
printf("handler: check_stack_for_vdso() = %dn", check_stack_for_vdso(esp, 20));
void parse_maps()
FILE *maps;
char buf[256];
char path[7];
uintmax_t start, end, offset, inode;
char r, w, x, p;
unsigned major, minor;
maps = fopen("/proc/self/maps", "rt");
if (maps == NULL)
return;
while (!feof(maps) && !ferror(maps))
if (fgets(buf, 256, maps) != NULL)
if (sscanf(buf, "%jx-%jx %c%c%c%c %jx %u:%u %ju %6s",
&start, &end, &r, &w, &x, &p, &offset,
&major, &minor, &inode, path) == 11)
if (!strcmp(path, "[vdso]"))
vdso_start = start;
vdso_end = end;
break;
fclose(maps);
printf("[vdso] at %jx-%jxn", vdso_start, vdso_end);
int main()
struct sigaction sa;
uint32_t *esp;
parse_maps();
memset(&sa, 0, sizeof(struct sigaction));
sa.sa_handler = handler;
sa.sa_flags = SA_RESTART;
if (sigaction(SIGUSR1, &sa, NULL) < 0)
perror("sigaction");
exit(1);
__asm__ __volatile__ ("mov %%esp, %0" : "=r"(esp));
printf("before kill: check_stack_for_vdso() = %dn", check_stack_for_vdso(esp, 20));
kill(getpid(), SIGUSR1);
__asm__ __volatile__ ("mov %%esp, %0" : "=r"(esp));
printf("after kill: check_stack_for_vdso() = %dn", check_stack_for_vdso(esp, 20));
return 0;
SCNR.
Apparently, newer Linux/x86 (probably since some 2.6.x kernel) calls signal handlers from the vdso
. You could use this fact to inflict the following horrible hack upon the unsuspecting world:
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <signal.h>
#include <unistd.h>
uintmax_t vdso_start = 0;
uintmax_t vdso_end = 0; /* actually, next byte */
int check_stack_for_vdso(uint32_t *esp, size_t len)
size_t i;
for (i = 0; i < len; i++, esp++)
if (*esp >= vdso_start && *esp < vdso_end)
return 1;
return 0;
void handler(int signo)
uint32_t *esp;
__asm__ __volatile__ ("mov %%esp, %0" : "=r"(esp));
/* XXX only for demonstration, don't call printf from a signal handler */
printf("handler: check_stack_for_vdso() = %dn", check_stack_for_vdso(esp, 20));
void parse_maps()
FILE *maps;
char buf[256];
char path[7];
uintmax_t start, end, offset, inode;
char r, w, x, p;
unsigned major, minor;
maps = fopen("/proc/self/maps", "rt");
if (maps == NULL)
return;
while (!feof(maps) && !ferror(maps))
if (fgets(buf, 256, maps) != NULL)
if (sscanf(buf, "%jx-%jx %c%c%c%c %jx %u:%u %ju %6s",
&start, &end, &r, &w, &x, &p, &offset,
&major, &minor, &inode, path) == 11)
if (!strcmp(path, "[vdso]"))
vdso_start = start;
vdso_end = end;
break;
fclose(maps);
printf("[vdso] at %jx-%jxn", vdso_start, vdso_end);
int main()
struct sigaction sa;
uint32_t *esp;
parse_maps();
memset(&sa, 0, sizeof(struct sigaction));
sa.sa_handler = handler;
sa.sa_flags = SA_RESTART;
if (sigaction(SIGUSR1, &sa, NULL) < 0)
perror("sigaction");
exit(1);
__asm__ __volatile__ ("mov %%esp, %0" : "=r"(esp));
printf("before kill: check_stack_for_vdso() = %dn", check_stack_for_vdso(esp, 20));
kill(getpid(), SIGUSR1);
__asm__ __volatile__ ("mov %%esp, %0" : "=r"(esp));
printf("after kill: check_stack_for_vdso() = %dn", check_stack_for_vdso(esp, 20));
return 0;
SCNR.
answered Jan 28 '11 at 22:29
ninjalj
34.6k681123
34.6k681123
I wasn't aware that signal handlers were called from the vdso. Could you point to a reference? At any rate, I like this hack. A lot. It'd be easy enough to roll this up into a opaque library. The trick would be making sure that parse_maps() was called before any signal handlers.
– smcdow
Jan 28 '11 at 22:40
The best reference I can find is lxr.free-electrons.com/source/arch/x86/kernel/…
– ninjalj
Jan 28 '11 at 23:10
But the comment at line 320 looks interesting: lxr.free-electrons.com/source/arch/x86/kernel/…
– ninjalj
Jan 28 '11 at 23:11
We're running on stock RHEL-5 distros -- Linux-2.6.18, so maybe I'll be able to use this. I'll write up a test case next week (which really means that I'll copy-and-paste your code to see what it does :-). Thanks.
– smcdow
Jan 29 '11 at 16:47
add a comment |
I wasn't aware that signal handlers were called from the vdso. Could you point to a reference? At any rate, I like this hack. A lot. It'd be easy enough to roll this up into a opaque library. The trick would be making sure that parse_maps() was called before any signal handlers.
– smcdow
Jan 28 '11 at 22:40
The best reference I can find is lxr.free-electrons.com/source/arch/x86/kernel/…
– ninjalj
Jan 28 '11 at 23:10
But the comment at line 320 looks interesting: lxr.free-electrons.com/source/arch/x86/kernel/…
– ninjalj
Jan 28 '11 at 23:11
We're running on stock RHEL-5 distros -- Linux-2.6.18, so maybe I'll be able to use this. I'll write up a test case next week (which really means that I'll copy-and-paste your code to see what it does :-). Thanks.
– smcdow
Jan 29 '11 at 16:47
I wasn't aware that signal handlers were called from the vdso. Could you point to a reference? At any rate, I like this hack. A lot. It'd be easy enough to roll this up into a opaque library. The trick would be making sure that parse_maps() was called before any signal handlers.
– smcdow
Jan 28 '11 at 22:40
I wasn't aware that signal handlers were called from the vdso. Could you point to a reference? At any rate, I like this hack. A lot. It'd be easy enough to roll this up into a opaque library. The trick would be making sure that parse_maps() was called before any signal handlers.
– smcdow
Jan 28 '11 at 22:40
The best reference I can find is lxr.free-electrons.com/source/arch/x86/kernel/…
– ninjalj
Jan 28 '11 at 23:10
The best reference I can find is lxr.free-electrons.com/source/arch/x86/kernel/…
– ninjalj
Jan 28 '11 at 23:10
But the comment at line 320 looks interesting: lxr.free-electrons.com/source/arch/x86/kernel/…
– ninjalj
Jan 28 '11 at 23:11
But the comment at line 320 looks interesting: lxr.free-electrons.com/source/arch/x86/kernel/…
– ninjalj
Jan 28 '11 at 23:11
We're running on stock RHEL-5 distros -- Linux-2.6.18, so maybe I'll be able to use this. I'll write up a test case next week (which really means that I'll copy-and-paste your code to see what it does :-). Thanks.
– smcdow
Jan 29 '11 at 16:47
We're running on stock RHEL-5 distros -- Linux-2.6.18, so maybe I'll be able to use this. I'll write up a test case next week (which really means that I'll copy-and-paste your code to see what it does :-). Thanks.
– smcdow
Jan 29 '11 at 16:47
add a comment |
up vote
3
down vote
If we can assume your application doesn't manually block signals using sigprocmask()
or pthread_sigmask()
, then this is pretty simple: get your current thread ID (tid
). Open /proc/tid/status
and get the values for SigBlk
and SigCgt
. AND
those two values. If the result of that AND
is non-zero, then that thread is currently running from inside a signal handler. I've tested this myself and it works.
You'd need the process ID (PID), not the thread ID. And doing this will involve calling non-async-signal-safe functions, barring writing your own.
– mgarey
Mar 8 at 21:55
1
@mgarey good point, make sure you do this only using async-signal safe functions such as the open() and read() system calls which is definitely doable. However if the program is multithreaded then you MUST use tid which will differ from pid. Being inside a signal handler is a thread specific state.
– David Yeager
May 6 at 21:56
David, you are quite right - I stand corrected.
– mgarey
May 7 at 17:15
add a comment |
up vote
3
down vote
If we can assume your application doesn't manually block signals using sigprocmask()
or pthread_sigmask()
, then this is pretty simple: get your current thread ID (tid
). Open /proc/tid/status
and get the values for SigBlk
and SigCgt
. AND
those two values. If the result of that AND
is non-zero, then that thread is currently running from inside a signal handler. I've tested this myself and it works.
You'd need the process ID (PID), not the thread ID. And doing this will involve calling non-async-signal-safe functions, barring writing your own.
– mgarey
Mar 8 at 21:55
1
@mgarey good point, make sure you do this only using async-signal safe functions such as the open() and read() system calls which is definitely doable. However if the program is multithreaded then you MUST use tid which will differ from pid. Being inside a signal handler is a thread specific state.
– David Yeager
May 6 at 21:56
David, you are quite right - I stand corrected.
– mgarey
May 7 at 17:15
add a comment |
up vote
3
down vote
up vote
3
down vote
If we can assume your application doesn't manually block signals using sigprocmask()
or pthread_sigmask()
, then this is pretty simple: get your current thread ID (tid
). Open /proc/tid/status
and get the values for SigBlk
and SigCgt
. AND
those two values. If the result of that AND
is non-zero, then that thread is currently running from inside a signal handler. I've tested this myself and it works.
If we can assume your application doesn't manually block signals using sigprocmask()
or pthread_sigmask()
, then this is pretty simple: get your current thread ID (tid
). Open /proc/tid/status
and get the values for SigBlk
and SigCgt
. AND
those two values. If the result of that AND
is non-zero, then that thread is currently running from inside a signal handler. I've tested this myself and it works.
edited Apr 25 '17 at 22:08
Fabio Turati
2,47252138
2,47252138
answered Apr 25 '17 at 21:32
David Yeager
1246
1246
You'd need the process ID (PID), not the thread ID. And doing this will involve calling non-async-signal-safe functions, barring writing your own.
– mgarey
Mar 8 at 21:55
1
@mgarey good point, make sure you do this only using async-signal safe functions such as the open() and read() system calls which is definitely doable. However if the program is multithreaded then you MUST use tid which will differ from pid. Being inside a signal handler is a thread specific state.
– David Yeager
May 6 at 21:56
David, you are quite right - I stand corrected.
– mgarey
May 7 at 17:15
add a comment |
You'd need the process ID (PID), not the thread ID. And doing this will involve calling non-async-signal-safe functions, barring writing your own.
– mgarey
Mar 8 at 21:55
1
@mgarey good point, make sure you do this only using async-signal safe functions such as the open() and read() system calls which is definitely doable. However if the program is multithreaded then you MUST use tid which will differ from pid. Being inside a signal handler is a thread specific state.
– David Yeager
May 6 at 21:56
David, you are quite right - I stand corrected.
– mgarey
May 7 at 17:15
You'd need the process ID (PID), not the thread ID. And doing this will involve calling non-async-signal-safe functions, barring writing your own.
– mgarey
Mar 8 at 21:55
You'd need the process ID (PID), not the thread ID. And doing this will involve calling non-async-signal-safe functions, barring writing your own.
– mgarey
Mar 8 at 21:55
1
1
@mgarey good point, make sure you do this only using async-signal safe functions such as the open() and read() system calls which is definitely doable. However if the program is multithreaded then you MUST use tid which will differ from pid. Being inside a signal handler is a thread specific state.
– David Yeager
May 6 at 21:56
@mgarey good point, make sure you do this only using async-signal safe functions such as the open() and read() system calls which is definitely doable. However if the program is multithreaded then you MUST use tid which will differ from pid. Being inside a signal handler is a thread specific state.
– David Yeager
May 6 at 21:56
David, you are quite right - I stand corrected.
– mgarey
May 7 at 17:15
David, you are quite right - I stand corrected.
– mgarey
May 7 at 17:15
add a comment |
up vote
0
down vote
There are two proper ways to deal with this:
Have your co-workers stop doing the wrong thing. Good luck pulling this off with the boss, though...
Make your function re-entrant and async-safe. If necessary, provide a function with a different signature (e.g. using the widely-used
*_r
naming convention) with the additional arguments that are necessary for state preservation.
As for the non-proper way to do this, on Linux with GNU libc you can use backtrace()
and friends to go through the caller list of your function. It's not easy to get right, safe or portable, but it might do for a while:
/*
* *** Warning ***
*
* Black, fragile and unportable magic ahead
*
* Do not use this, lest the daemons of hell be unleashed upon you
*/
int in_signal_handler_context()
int i, n;
void *bt[1000];
char **bts = NULL;
n = backtrace(bt, 1000);
bts = backtrace_symbols(bt, n);
for (i = 0; i < n; ++i)
printf("%i - %sn", i, bts[i]);
/* Have a look at the caller chain */
for (i = 0; i < n; ++i)
/* Far more checks are needed here to avoid misfires */
if (strstr(bts[i], "(__libc_start_main+") != NULL)
return 0;
if (strstr(bts[i], "libc.so.6(+") != NULL)
return 1;
return 0;
void unsafe()
if (in_signal_handler_context())
printf("John, you know you are an idiot, right?n");
In my opinion, it might just be better to quit rather than be forced to write code like this.
I've just triedbacktrace()
, and it just doesn't work:__libc_start_main
is in the trace both in and out of signal handling context.
– P Shved
Jan 28 '11 at 21:42
As I mentioned, it's not easy to get right. You have to find a difference in the backtrace between the two cases and use that. E.g for my test I assumed that no libc function would be in the backtrace before reachingmain()
, unless it's the signal handling code. What does your backtrace look like in each case?
– thkala
Jan 28 '11 at 21:45
Two comments: (1) I was afraid it might be something like this. (2) Not to be a snot, but printf(3) is not an async-signal-safe function. You'd have to use write(2). -- A list of async-signal-safe functions (at least, the list that I usually refer to) can be found here: pubs.opengroup.org/onlinepubs/009695399/functions/…
– smcdow
Jan 28 '11 at 21:49
This is why I avoided trying to give a direct answer at all. What you are asking for requires a hack as @thkala has proposed. Hence, it is probably better to find a diplomatic solution.
– Judge Maygarden
Jan 28 '11 at 21:51
@smcdow: I know quite well thatprintf()
is not async safe - but neither is the function that's using it (i.e. your function) :-)
– thkala
Jan 28 '11 at 21:55
|
show 5 more comments
up vote
0
down vote
There are two proper ways to deal with this:
Have your co-workers stop doing the wrong thing. Good luck pulling this off with the boss, though...
Make your function re-entrant and async-safe. If necessary, provide a function with a different signature (e.g. using the widely-used
*_r
naming convention) with the additional arguments that are necessary for state preservation.
As for the non-proper way to do this, on Linux with GNU libc you can use backtrace()
and friends to go through the caller list of your function. It's not easy to get right, safe or portable, but it might do for a while:
/*
* *** Warning ***
*
* Black, fragile and unportable magic ahead
*
* Do not use this, lest the daemons of hell be unleashed upon you
*/
int in_signal_handler_context()
int i, n;
void *bt[1000];
char **bts = NULL;
n = backtrace(bt, 1000);
bts = backtrace_symbols(bt, n);
for (i = 0; i < n; ++i)
printf("%i - %sn", i, bts[i]);
/* Have a look at the caller chain */
for (i = 0; i < n; ++i)
/* Far more checks are needed here to avoid misfires */
if (strstr(bts[i], "(__libc_start_main+") != NULL)
return 0;
if (strstr(bts[i], "libc.so.6(+") != NULL)
return 1;
return 0;
void unsafe()
if (in_signal_handler_context())
printf("John, you know you are an idiot, right?n");
In my opinion, it might just be better to quit rather than be forced to write code like this.
I've just triedbacktrace()
, and it just doesn't work:__libc_start_main
is in the trace both in and out of signal handling context.
– P Shved
Jan 28 '11 at 21:42
As I mentioned, it's not easy to get right. You have to find a difference in the backtrace between the two cases and use that. E.g for my test I assumed that no libc function would be in the backtrace before reachingmain()
, unless it's the signal handling code. What does your backtrace look like in each case?
– thkala
Jan 28 '11 at 21:45
Two comments: (1) I was afraid it might be something like this. (2) Not to be a snot, but printf(3) is not an async-signal-safe function. You'd have to use write(2). -- A list of async-signal-safe functions (at least, the list that I usually refer to) can be found here: pubs.opengroup.org/onlinepubs/009695399/functions/…
– smcdow
Jan 28 '11 at 21:49
This is why I avoided trying to give a direct answer at all. What you are asking for requires a hack as @thkala has proposed. Hence, it is probably better to find a diplomatic solution.
– Judge Maygarden
Jan 28 '11 at 21:51
@smcdow: I know quite well thatprintf()
is not async safe - but neither is the function that's using it (i.e. your function) :-)
– thkala
Jan 28 '11 at 21:55
|
show 5 more comments
up vote
0
down vote
up vote
0
down vote
There are two proper ways to deal with this:
Have your co-workers stop doing the wrong thing. Good luck pulling this off with the boss, though...
Make your function re-entrant and async-safe. If necessary, provide a function with a different signature (e.g. using the widely-used
*_r
naming convention) with the additional arguments that are necessary for state preservation.
As for the non-proper way to do this, on Linux with GNU libc you can use backtrace()
and friends to go through the caller list of your function. It's not easy to get right, safe or portable, but it might do for a while:
/*
* *** Warning ***
*
* Black, fragile and unportable magic ahead
*
* Do not use this, lest the daemons of hell be unleashed upon you
*/
int in_signal_handler_context()
int i, n;
void *bt[1000];
char **bts = NULL;
n = backtrace(bt, 1000);
bts = backtrace_symbols(bt, n);
for (i = 0; i < n; ++i)
printf("%i - %sn", i, bts[i]);
/* Have a look at the caller chain */
for (i = 0; i < n; ++i)
/* Far more checks are needed here to avoid misfires */
if (strstr(bts[i], "(__libc_start_main+") != NULL)
return 0;
if (strstr(bts[i], "libc.so.6(+") != NULL)
return 1;
return 0;
void unsafe()
if (in_signal_handler_context())
printf("John, you know you are an idiot, right?n");
In my opinion, it might just be better to quit rather than be forced to write code like this.
There are two proper ways to deal with this:
Have your co-workers stop doing the wrong thing. Good luck pulling this off with the boss, though...
Make your function re-entrant and async-safe. If necessary, provide a function with a different signature (e.g. using the widely-used
*_r
naming convention) with the additional arguments that are necessary for state preservation.
As for the non-proper way to do this, on Linux with GNU libc you can use backtrace()
and friends to go through the caller list of your function. It's not easy to get right, safe or portable, but it might do for a while:
/*
* *** Warning ***
*
* Black, fragile and unportable magic ahead
*
* Do not use this, lest the daemons of hell be unleashed upon you
*/
int in_signal_handler_context()
int i, n;
void *bt[1000];
char **bts = NULL;
n = backtrace(bt, 1000);
bts = backtrace_symbols(bt, n);
for (i = 0; i < n; ++i)
printf("%i - %sn", i, bts[i]);
/* Have a look at the caller chain */
for (i = 0; i < n; ++i)
/* Far more checks are needed here to avoid misfires */
if (strstr(bts[i], "(__libc_start_main+") != NULL)
return 0;
if (strstr(bts[i], "libc.so.6(+") != NULL)
return 1;
return 0;
void unsafe()
if (in_signal_handler_context())
printf("John, you know you are an idiot, right?n");
In my opinion, it might just be better to quit rather than be forced to write code like this.
edited Jan 28 '11 at 21:45
answered Jan 28 '11 at 21:34
thkala
63.3k17130173
63.3k17130173
I've just triedbacktrace()
, and it just doesn't work:__libc_start_main
is in the trace both in and out of signal handling context.
– P Shved
Jan 28 '11 at 21:42
As I mentioned, it's not easy to get right. You have to find a difference in the backtrace between the two cases and use that. E.g for my test I assumed that no libc function would be in the backtrace before reachingmain()
, unless it's the signal handling code. What does your backtrace look like in each case?
– thkala
Jan 28 '11 at 21:45
Two comments: (1) I was afraid it might be something like this. (2) Not to be a snot, but printf(3) is not an async-signal-safe function. You'd have to use write(2). -- A list of async-signal-safe functions (at least, the list that I usually refer to) can be found here: pubs.opengroup.org/onlinepubs/009695399/functions/…
– smcdow
Jan 28 '11 at 21:49
This is why I avoided trying to give a direct answer at all. What you are asking for requires a hack as @thkala has proposed. Hence, it is probably better to find a diplomatic solution.
– Judge Maygarden
Jan 28 '11 at 21:51
@smcdow: I know quite well thatprintf()
is not async safe - but neither is the function that's using it (i.e. your function) :-)
– thkala
Jan 28 '11 at 21:55
|
show 5 more comments
I've just triedbacktrace()
, and it just doesn't work:__libc_start_main
is in the trace both in and out of signal handling context.
– P Shved
Jan 28 '11 at 21:42
As I mentioned, it's not easy to get right. You have to find a difference in the backtrace between the two cases and use that. E.g for my test I assumed that no libc function would be in the backtrace before reachingmain()
, unless it's the signal handling code. What does your backtrace look like in each case?
– thkala
Jan 28 '11 at 21:45
Two comments: (1) I was afraid it might be something like this. (2) Not to be a snot, but printf(3) is not an async-signal-safe function. You'd have to use write(2). -- A list of async-signal-safe functions (at least, the list that I usually refer to) can be found here: pubs.opengroup.org/onlinepubs/009695399/functions/…
– smcdow
Jan 28 '11 at 21:49
This is why I avoided trying to give a direct answer at all. What you are asking for requires a hack as @thkala has proposed. Hence, it is probably better to find a diplomatic solution.
– Judge Maygarden
Jan 28 '11 at 21:51
@smcdow: I know quite well thatprintf()
is not async safe - but neither is the function that's using it (i.e. your function) :-)
– thkala
Jan 28 '11 at 21:55
I've just tried
backtrace()
, and it just doesn't work: __libc_start_main
is in the trace both in and out of signal handling context.– P Shved
Jan 28 '11 at 21:42
I've just tried
backtrace()
, and it just doesn't work: __libc_start_main
is in the trace both in and out of signal handling context.– P Shved
Jan 28 '11 at 21:42
As I mentioned, it's not easy to get right. You have to find a difference in the backtrace between the two cases and use that. E.g for my test I assumed that no libc function would be in the backtrace before reaching
main()
, unless it's the signal handling code. What does your backtrace look like in each case?– thkala
Jan 28 '11 at 21:45
As I mentioned, it's not easy to get right. You have to find a difference in the backtrace between the two cases and use that. E.g for my test I assumed that no libc function would be in the backtrace before reaching
main()
, unless it's the signal handling code. What does your backtrace look like in each case?– thkala
Jan 28 '11 at 21:45
Two comments: (1) I was afraid it might be something like this. (2) Not to be a snot, but printf(3) is not an async-signal-safe function. You'd have to use write(2). -- A list of async-signal-safe functions (at least, the list that I usually refer to) can be found here: pubs.opengroup.org/onlinepubs/009695399/functions/…
– smcdow
Jan 28 '11 at 21:49
Two comments: (1) I was afraid it might be something like this. (2) Not to be a snot, but printf(3) is not an async-signal-safe function. You'd have to use write(2). -- A list of async-signal-safe functions (at least, the list that I usually refer to) can be found here: pubs.opengroup.org/onlinepubs/009695399/functions/…
– smcdow
Jan 28 '11 at 21:49
This is why I avoided trying to give a direct answer at all. What you are asking for requires a hack as @thkala has proposed. Hence, it is probably better to find a diplomatic solution.
– Judge Maygarden
Jan 28 '11 at 21:51
This is why I avoided trying to give a direct answer at all. What you are asking for requires a hack as @thkala has proposed. Hence, it is probably better to find a diplomatic solution.
– Judge Maygarden
Jan 28 '11 at 21:51
@smcdow: I know quite well that
printf()
is not async safe - but neither is the function that's using it (i.e. your function) :-)– thkala
Jan 28 '11 at 21:55
@smcdow: I know quite well that
printf()
is not async safe - but neither is the function that's using it (i.e. your function) :-)– thkala
Jan 28 '11 at 21:55
|
show 5 more comments
up vote
0
down vote
You could work out something using sigaltstack. Set up an alternative signal stack, get the stack pointer in some async-safe way, if within the alternative stack go on, otherwise abort().
I thought about something like that, but I don't think I could guarantee that I'd have the alternate stack set up before my function was called from a signal handler. I should also reiterate that my function is NEVER supposed to be called from a signal handler, and the documentation says so.
– smcdow
Jan 28 '11 at 21:58
There's an easier way.sigaltstack
is required to return an error if you're already running on the alternate stack and try to make changes to it, so you could just try calling it and see if the call fails.
– R..
Mar 22 '11 at 20:40
add a comment |
up vote
0
down vote
You could work out something using sigaltstack. Set up an alternative signal stack, get the stack pointer in some async-safe way, if within the alternative stack go on, otherwise abort().
I thought about something like that, but I don't think I could guarantee that I'd have the alternate stack set up before my function was called from a signal handler. I should also reiterate that my function is NEVER supposed to be called from a signal handler, and the documentation says so.
– smcdow
Jan 28 '11 at 21:58
There's an easier way.sigaltstack
is required to return an error if you're already running on the alternate stack and try to make changes to it, so you could just try calling it and see if the call fails.
– R..
Mar 22 '11 at 20:40
add a comment |
up vote
0
down vote
up vote
0
down vote
You could work out something using sigaltstack. Set up an alternative signal stack, get the stack pointer in some async-safe way, if within the alternative stack go on, otherwise abort().
You could work out something using sigaltstack. Set up an alternative signal stack, get the stack pointer in some async-safe way, if within the alternative stack go on, otherwise abort().
answered Jan 28 '11 at 21:51
Tobu
20k36889
20k36889
I thought about something like that, but I don't think I could guarantee that I'd have the alternate stack set up before my function was called from a signal handler. I should also reiterate that my function is NEVER supposed to be called from a signal handler, and the documentation says so.
– smcdow
Jan 28 '11 at 21:58
There's an easier way.sigaltstack
is required to return an error if you're already running on the alternate stack and try to make changes to it, so you could just try calling it and see if the call fails.
– R..
Mar 22 '11 at 20:40
add a comment |
I thought about something like that, but I don't think I could guarantee that I'd have the alternate stack set up before my function was called from a signal handler. I should also reiterate that my function is NEVER supposed to be called from a signal handler, and the documentation says so.
– smcdow
Jan 28 '11 at 21:58
There's an easier way.sigaltstack
is required to return an error if you're already running on the alternate stack and try to make changes to it, so you could just try calling it and see if the call fails.
– R..
Mar 22 '11 at 20:40
I thought about something like that, but I don't think I could guarantee that I'd have the alternate stack set up before my function was called from a signal handler. I should also reiterate that my function is NEVER supposed to be called from a signal handler, and the documentation says so.
– smcdow
Jan 28 '11 at 21:58
I thought about something like that, but I don't think I could guarantee that I'd have the alternate stack set up before my function was called from a signal handler. I should also reiterate that my function is NEVER supposed to be called from a signal handler, and the documentation says so.
– smcdow
Jan 28 '11 at 21:58
There's an easier way.
sigaltstack
is required to return an error if you're already running on the alternate stack and try to make changes to it, so you could just try calling it and see if the call fails.– R..
Mar 22 '11 at 20:40
There's an easier way.
sigaltstack
is required to return an error if you're already running on the alternate stack and try to make changes to it, so you could just try calling it and see if the call fails.– R..
Mar 22 '11 at 20:40
add a comment |
up vote
0
down vote
I guess you need to do the following. This is a complex solution, which combines the best practices not only from coding, but from software engineering as well!
- Persuade your boss that naming convention on signal handlers is a good thing. Propose, for example, a Hungarian notation, and tell that it was used in Microsoft with great success.
So, all signal handlers will start withsighnd
, likesighndInterrupt
. - Your function that detects signal handling context would do the following:
- Get the
backtrace()
. - Look if any of the functions in it begin with
sighnd...
. If it does, then congratulations, you're inside a signal handler! - Otherwise, you're not.
- Get the
- Try to avoid working with Jimmy in the same company. "There can be only one", you know.
We're going to have a janitor make a pass over the code base and report back any and all functions being called from signal handlers. I'm cringing already.
– smcdow
Jan 28 '11 at 21:59
@smcdow, by the way, you could employ a static analysis tool for that. But then again, you'd have to annotate each signal handler, which makes the solution proposed not any more complex. :-)
– P Shved
Jan 28 '11 at 22:07
some time ago there was a Valgrind tool to look for signal handler problems, it was called crocus.
– ninjalj
Jan 28 '11 at 22:25
@ninjalj, Valgrind is a dynamic analysis tool, not a static one. Anyway, I've just devised a way to do it statically, but that's quite off-topic here.
– P Shved
Jan 28 '11 at 22:28
add a comment |
up vote
0
down vote
I guess you need to do the following. This is a complex solution, which combines the best practices not only from coding, but from software engineering as well!
- Persuade your boss that naming convention on signal handlers is a good thing. Propose, for example, a Hungarian notation, and tell that it was used in Microsoft with great success.
So, all signal handlers will start withsighnd
, likesighndInterrupt
. - Your function that detects signal handling context would do the following:
- Get the
backtrace()
. - Look if any of the functions in it begin with
sighnd...
. If it does, then congratulations, you're inside a signal handler! - Otherwise, you're not.
- Get the
- Try to avoid working with Jimmy in the same company. "There can be only one", you know.
We're going to have a janitor make a pass over the code base and report back any and all functions being called from signal handlers. I'm cringing already.
– smcdow
Jan 28 '11 at 21:59
@smcdow, by the way, you could employ a static analysis tool for that. But then again, you'd have to annotate each signal handler, which makes the solution proposed not any more complex. :-)
– P Shved
Jan 28 '11 at 22:07
some time ago there was a Valgrind tool to look for signal handler problems, it was called crocus.
– ninjalj
Jan 28 '11 at 22:25
@ninjalj, Valgrind is a dynamic analysis tool, not a static one. Anyway, I've just devised a way to do it statically, but that's quite off-topic here.
– P Shved
Jan 28 '11 at 22:28
add a comment |
up vote
0
down vote
up vote
0
down vote
I guess you need to do the following. This is a complex solution, which combines the best practices not only from coding, but from software engineering as well!
- Persuade your boss that naming convention on signal handlers is a good thing. Propose, for example, a Hungarian notation, and tell that it was used in Microsoft with great success.
So, all signal handlers will start withsighnd
, likesighndInterrupt
. - Your function that detects signal handling context would do the following:
- Get the
backtrace()
. - Look if any of the functions in it begin with
sighnd...
. If it does, then congratulations, you're inside a signal handler! - Otherwise, you're not.
- Get the
- Try to avoid working with Jimmy in the same company. "There can be only one", you know.
I guess you need to do the following. This is a complex solution, which combines the best practices not only from coding, but from software engineering as well!
- Persuade your boss that naming convention on signal handlers is a good thing. Propose, for example, a Hungarian notation, and tell that it was used in Microsoft with great success.
So, all signal handlers will start withsighnd
, likesighndInterrupt
. - Your function that detects signal handling context would do the following:
- Get the
backtrace()
. - Look if any of the functions in it begin with
sighnd...
. If it does, then congratulations, you're inside a signal handler! - Otherwise, you're not.
- Get the
- Try to avoid working with Jimmy in the same company. "There can be only one", you know.
edited May 23 '17 at 11:54
Community♦
11
11
answered Jan 28 '11 at 21:53
P Shved
70.7k11105153
70.7k11105153
We're going to have a janitor make a pass over the code base and report back any and all functions being called from signal handlers. I'm cringing already.
– smcdow
Jan 28 '11 at 21:59
@smcdow, by the way, you could employ a static analysis tool for that. But then again, you'd have to annotate each signal handler, which makes the solution proposed not any more complex. :-)
– P Shved
Jan 28 '11 at 22:07
some time ago there was a Valgrind tool to look for signal handler problems, it was called crocus.
– ninjalj
Jan 28 '11 at 22:25
@ninjalj, Valgrind is a dynamic analysis tool, not a static one. Anyway, I've just devised a way to do it statically, but that's quite off-topic here.
– P Shved
Jan 28 '11 at 22:28
add a comment |
We're going to have a janitor make a pass over the code base and report back any and all functions being called from signal handlers. I'm cringing already.
– smcdow
Jan 28 '11 at 21:59
@smcdow, by the way, you could employ a static analysis tool for that. But then again, you'd have to annotate each signal handler, which makes the solution proposed not any more complex. :-)
– P Shved
Jan 28 '11 at 22:07
some time ago there was a Valgrind tool to look for signal handler problems, it was called crocus.
– ninjalj
Jan 28 '11 at 22:25
@ninjalj, Valgrind is a dynamic analysis tool, not a static one. Anyway, I've just devised a way to do it statically, but that's quite off-topic here.
– P Shved
Jan 28 '11 at 22:28
We're going to have a janitor make a pass over the code base and report back any and all functions being called from signal handlers. I'm cringing already.
– smcdow
Jan 28 '11 at 21:59
We're going to have a janitor make a pass over the code base and report back any and all functions being called from signal handlers. I'm cringing already.
– smcdow
Jan 28 '11 at 21:59
@smcdow, by the way, you could employ a static analysis tool for that. But then again, you'd have to annotate each signal handler, which makes the solution proposed not any more complex. :-)
– P Shved
Jan 28 '11 at 22:07
@smcdow, by the way, you could employ a static analysis tool for that. But then again, you'd have to annotate each signal handler, which makes the solution proposed not any more complex. :-)
– P Shved
Jan 28 '11 at 22:07
some time ago there was a Valgrind tool to look for signal handler problems, it was called crocus.
– ninjalj
Jan 28 '11 at 22:25
some time ago there was a Valgrind tool to look for signal handler problems, it was called crocus.
– ninjalj
Jan 28 '11 at 22:25
@ninjalj, Valgrind is a dynamic analysis tool, not a static one. Anyway, I've just devised a way to do it statically, but that's quite off-topic here.
– P Shved
Jan 28 '11 at 22:28
@ninjalj, Valgrind is a dynamic analysis tool, not a static one. Anyway, I've just devised a way to do it statically, but that's quite off-topic here.
– P Shved
Jan 28 '11 at 22:28
add a comment |
up vote
0
down vote
for code optimized at -O2 or better (istr) have found need to add -fno-omit-frame-pointer
else gcc will optimize out the stack context information
add a comment |
up vote
0
down vote
for code optimized at -O2 or better (istr) have found need to add -fno-omit-frame-pointer
else gcc will optimize out the stack context information
add a comment |
up vote
0
down vote
up vote
0
down vote
for code optimized at -O2 or better (istr) have found need to add -fno-omit-frame-pointer
else gcc will optimize out the stack context information
for code optimized at -O2 or better (istr) have found need to add -fno-omit-frame-pointer
else gcc will optimize out the stack context information
answered Jan 10 '12 at 22:12
chaosless
50348
50348
add a comment |
add a comment |
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f4832743%2fhow-to-determine-if-code-is-running-in-signal-handler-context%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown