How to determine if code is running in signal-handler context?









up vote
11
down vote

favorite
6












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.










share|improve this question



























    up vote
    11
    down vote

    favorite
    6












    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.










    share|improve this question

























      up vote
      11
      down vote

      favorite
      6









      up vote
      11
      down vote

      favorite
      6






      6





      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.










      share|improve this question















      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






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Nov 11 at 1:04









      AkaZecik

      8129




      8129










      asked Jan 28 '11 at 20:27









      smcdow

      2221510




      2221510






















          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.






          share|improve this answer




















          • 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


















          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.






          share|improve this answer






















          • 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

















          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.






          share|improve this answer






















          • 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










          • 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 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

















          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().






          share|improve this answer




















          • 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

















          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!



          1. 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 with sighnd, like sighndInterrupt.

          2. Your function that detects signal handling context would do the following:

            1. Get the backtrace().

            2. Look if any of the functions in it begin with sighnd.... If it does, then congratulations, you're inside a signal handler!

            3. Otherwise, you're not.


          3. Try to avoid working with Jimmy in the same company. "There can be only one", you know.





          share|improve this answer






















          • 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


















          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






          share|improve this answer




















            Your Answer






            StackExchange.ifUsing("editor", function ()
            StackExchange.using("externalEditor", function ()
            StackExchange.using("snippets", function ()
            StackExchange.snippets.init();
            );
            );
            , "code-snippets");

            StackExchange.ready(function()
            var channelOptions =
            tags: "".split(" "),
            id: "1"
            ;
            initTagRenderer("".split(" "), "".split(" "), channelOptions);

            StackExchange.using("externalEditor", function()
            // Have to fire editor after snippets, if snippets enabled
            if (StackExchange.settings.snippets.snippetsEnabled)
            StackExchange.using("snippets", function()
            createEditor();
            );

            else
            createEditor();

            );

            function createEditor()
            StackExchange.prepareEditor(
            heartbeatType: 'answer',
            convertImagesToLinks: true,
            noModals: true,
            showLowRepImageUploadWarning: true,
            reputationToPostImages: 10,
            bindNavPrevention: true,
            postfix: "",
            imageUploader:
            brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
            contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
            allowUrls: true
            ,
            onDemand: true,
            discardSelector: ".discard-answer"
            ,immediatelyShowMarkdownHelp:true
            );



            );













             

            draft saved


            draft discarded


















            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

























            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.






            share|improve this answer




















            • 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















            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.






            share|improve this answer




















            • 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













            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.






            share|improve this answer












            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.







            share|improve this answer












            share|improve this answer



            share|improve this answer










            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

















            • 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













            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.






            share|improve this answer






















            • 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














            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.






            share|improve this answer






















            • 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












            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.






            share|improve this answer














            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.







            share|improve this answer














            share|improve this answer



            share|improve this answer








            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
















            • 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










            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.






            share|improve this answer






















            • 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










            • 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 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














            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.






            share|improve this answer






















            • 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










            • 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 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












            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.






            share|improve this answer














            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.







            share|improve this answer














            share|improve this answer



            share|improve this answer








            edited Jan 28 '11 at 21:45

























            answered Jan 28 '11 at 21:34









            thkala

            63.3k17130173




            63.3k17130173











            • 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










            • 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 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
















            • 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










            • 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 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















            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










            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().






            share|improve this answer




















            • 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














            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().






            share|improve this answer




















            • 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












            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().






            share|improve this answer












            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().







            share|improve this answer












            share|improve this answer



            share|improve this answer










            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
















            • 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










            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!



            1. 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 with sighnd, like sighndInterrupt.

            2. Your function that detects signal handling context would do the following:

              1. Get the backtrace().

              2. Look if any of the functions in it begin with sighnd.... If it does, then congratulations, you're inside a signal handler!

              3. Otherwise, you're not.


            3. Try to avoid working with Jimmy in the same company. "There can be only one", you know.





            share|improve this answer






















            • 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















            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!



            1. 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 with sighnd, like sighndInterrupt.

            2. Your function that detects signal handling context would do the following:

              1. Get the backtrace().

              2. Look if any of the functions in it begin with sighnd.... If it does, then congratulations, you're inside a signal handler!

              3. Otherwise, you're not.


            3. Try to avoid working with Jimmy in the same company. "There can be only one", you know.





            share|improve this answer






















            • 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













            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!



            1. 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 with sighnd, like sighndInterrupt.

            2. Your function that detects signal handling context would do the following:

              1. Get the backtrace().

              2. Look if any of the functions in it begin with sighnd.... If it does, then congratulations, you're inside a signal handler!

              3. Otherwise, you're not.


            3. Try to avoid working with Jimmy in the same company. "There can be only one", you know.





            share|improve this answer














            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!



            1. 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 with sighnd, like sighndInterrupt.

            2. Your function that detects signal handling context would do the following:

              1. Get the backtrace().

              2. Look if any of the functions in it begin with sighnd.... If it does, then congratulations, you're inside a signal handler!

              3. Otherwise, you're not.


            3. Try to avoid working with Jimmy in the same company. "There can be only one", you know.






            share|improve this answer














            share|improve this answer



            share|improve this answer








            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

















            • 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











            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






            share|improve this answer
























              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






              share|improve this answer






















                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






                share|improve this answer












                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







                share|improve this answer












                share|improve this answer



                share|improve this answer










                answered Jan 10 '12 at 22:12









                chaosless

                50348




                50348



























                     

                    draft saved


                    draft discarded















































                     


                    draft saved


                    draft discarded














                    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





















































                    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







                    這個網誌中的熱門文章

                    Barbados

                    How to read a connectionString WITH PROVIDER in .NET Core?

                    Node.js Script on GitHub Pages or Amazon S3