Is it possible to determine exit code in library destructor? - Linux

This is a discussion on Is it possible to determine exit code in library destructor? - Linux ; I have an interesting problem. I'm writing a shared library which is inserted into an alien process via LD_PRELOAD. I have almost everything working beautifully but the library needs to get access to the exit code before quitting. Its destructor ...

+ Reply to Thread
Page 1 of 2 1 2 LastLast
Results 1 to 20 of 31

Thread: Is it possible to determine exit code in library destructor?

  1. Is it possible to determine exit code in library destructor?

    I have an interesting problem. I'm writing a shared library which is
    inserted into an alien process via LD_PRELOAD. I have almost everything
    working beautifully but the library needs to get access to the exit code
    before quitting. Its destructor function is definitely called after
    exit() so the value must be around someplace but I do not know a way to
    get it. Any ideas?

    This is for Linux and Solaris. A simple test case using gcc is below.
    Currently it reports "0" for the exit code but it needs to give the real
    value.

    Thanks,
    Arch Stanton

    % cat ldlab.c
    ---------------------------------------
    #include
    #include
    #include

    static void ldlab_init(void) __attribute__ ((constructor));
    static void ldlab_fini(void) __attribute__ ((destructor));

    static void
    ldlab_init(void)
    {
    write(STDERR_FILENO, "= Starting\n", 11);
    }

    static void
    ldlab_fini(void)
    {
    fprintf(stderr, "= Ending with exit code %d\n", 0); // PROBLEM!
    }
    ---------------------------------------

    % gcc -g -W -Wall -fpic -shared -o ldlab.so ldl>

    % LD_PRELOAD=./ldlab.so date
    = Starting
    Wed Oct 1 10:50:54 EDT 2008
    = Ending with exit code 0

  2. Re: Is it possible to determine exit code in library destructor?

    On Oct 1, 4:02*pm, Arch Stanton wrote:
    > I have an interesting problem. I'm writing a shared library which is
    > inserted into an alien process via LD_PRELOAD. I have almost everything
    > working beautifully but the library needs to get access to the exit code
    > before quitting. Its destructor function is definitely called after
    > exit() so the value must be around someplace but I do not know a way to
    > get it. Any ideas?


    You could interpose _exit() and _Exit() to take a peek at the return
    code and then delegate to real _exit() and _Exit() respectively.

    --
    Max

  3. Re: Is it possible to determine exit code in library destructor?

    On Oct 1, 4:02*pm, Arch Stanton wrote:
    > I have an interesting problem. I'm writing a shared library which is
    > inserted into an alien process via LD_PRELOAD. I have almost everything
    > working beautifully but the library needs to get access to the exit code
    > before quitting. Its destructor function is definitely called after
    > exit() so the value must be around someplace but I do not know a way to
    > get it. Any ideas?


    You could interpose _exit() and _Exit() to take a peek at the return
    code and then delegate to real _exit() and _Exit() respectively.

    --
    Max

  4. Re: Is it possible to determine exit code in library destructor?

    Maxim Yegorushkin wrote:
    > You could interpose _exit() and _Exit() to take a peek at the return
    > code and then delegate to real _exit() and _Exit() respectively.


    Thanks. I should have mentioned that I actually tried that first. The
    problem is the case where the program never makes an explicit exit call
    but just returns from main(), e.g.:

    int main(void) { return 0; )

    In this case the call to _exit() seems to be made within the C library
    and I don't know how to interpose on it. So I guess an alternate version
    of my question would be: does anybody know how to interpose on an
    intra-library call from another library?

    Thanks,
    Arch Stanton

  5. Re: Is it possible to determine exit code in library destructor?

    Maxim Yegorushkin wrote:
    > You could interpose _exit() and _Exit() to take a peek at the return
    > code and then delegate to real _exit() and _Exit() respectively.


    Thanks. I should have mentioned that I actually tried that first. The
    problem is the case where the program never makes an explicit exit call
    but just returns from main(), e.g.:

    int main(void) { return 0; )

    In this case the call to _exit() seems to be made within the C library
    and I don't know how to interpose on it. So I guess an alternate version
    of my question would be: does anybody know how to interpose on an
    intra-library call from another library?

    Thanks,
    Arch Stanton

  6. Re: Is it possible to determine exit code in library destructor?

    Hello,

    Arch Stanton wrote:

    > Maxim Yegorushkin wrote:
    >> You could interpose _exit() and _Exit() to take a peek at the return
    >> code and then delegate to real _exit() and _Exit() respectively.

    >
    > Thanks. I should have mentioned that I actually tried that first. The
    > problem is the case where the program never makes an explicit exit
    > call but just returns from main(), e.g.:
    >
    > int main(void) { return 0; )
    >
    > In this case the call to _exit() seems to be made within the C library
    > and I don't know how to interpose on it. So I guess an alternate
    > version of my question would be: does anybody know how to interpose on
    > an intra-library call from another library?


    I'd try interposing _exit and main? A intra-library call might even be
    inlined, so no chance to interpose.

    Bernd Strieder


  7. Re: Is it possible to determine exit code in library destructor?

    Hello,

    Arch Stanton wrote:

    > Maxim Yegorushkin wrote:
    >> You could interpose _exit() and _Exit() to take a peek at the return
    >> code and then delegate to real _exit() and _Exit() respectively.

    >
    > Thanks. I should have mentioned that I actually tried that first. The
    > problem is the case where the program never makes an explicit exit
    > call but just returns from main(), e.g.:
    >
    > int main(void) { return 0; )
    >
    > In this case the call to _exit() seems to be made within the C library
    > and I don't know how to interpose on it. So I guess an alternate
    > version of my question would be: does anybody know how to interpose on
    > an intra-library call from another library?


    I'd try interposing _exit and main? A intra-library call might even be
    inlined, so no chance to interpose.

    Bernd Strieder


  8. Re: Is it possible to determine exit code in library destructor?

    Arch Stanton wrote:

    > I have an interesting problem. I'm writing a shared library which is
    > inserted into an alien process via LD_PRELOAD. I have almost everything
    > working beautifully but the library needs to get access to the exit code
    > before quitting. Its destructor function is definitely called after
    > exit() so the value must be around someplace but I do not know a way to
    > get it. Any ideas?


    This works under Linux. I had to capture stdout, because date(1) from
    the coreutils closes stdout before returning from main.

    $ cat ldlab.c
    #include
    #include

    static void ldlab_init(void) __attribute__((constructor));
    static FILE *stdout_capture;

    static void
    exit_handler(int exit_code, void *ignore)
    {
    fprintf(stdout_capture, "exit code = %d\n", exit_code);
    }

    static void
    ldlab_init(void)
    {
    stdout_capture = fopen("/dev/stdout", "w");
    on_exit(exit_handler, 0);
    }

    $ gcc -shared -o ldlab.so ldlab.c
    huib@leela:~/tttt> LD_PRELOAD=./ldlab.so date
    wo okt 1 19:56:07 CEST 2008
    exit code = 0
    $ LD_PRELOAD=./t3.so date -onzin
    date: ongeldige optie -- o
    Probeer `date --help' voor meer informatie.
    exit code = 1

    --
    Huibert
    "Hey! HEY! Curious cat, here!" -- Krosp I (GG)

  9. Re: Is it possible to determine exit code in library destructor?

    Arch Stanton wrote:

    > I have an interesting problem. I'm writing a shared library which is
    > inserted into an alien process via LD_PRELOAD. I have almost everything
    > working beautifully but the library needs to get access to the exit code
    > before quitting. Its destructor function is definitely called after
    > exit() so the value must be around someplace but I do not know a way to
    > get it. Any ideas?


    This works under Linux. I had to capture stdout, because date(1) from
    the coreutils closes stdout before returning from main.

    $ cat ldlab.c
    #include
    #include

    static void ldlab_init(void) __attribute__((constructor));
    static FILE *stdout_capture;

    static void
    exit_handler(int exit_code, void *ignore)
    {
    fprintf(stdout_capture, "exit code = %d\n", exit_code);
    }

    static void
    ldlab_init(void)
    {
    stdout_capture = fopen("/dev/stdout", "w");
    on_exit(exit_handler, 0);
    }

    $ gcc -shared -o ldlab.so ldlab.c
    huib@leela:~/tttt> LD_PRELOAD=./ldlab.so date
    wo okt 1 19:56:07 CEST 2008
    exit code = 0
    $ LD_PRELOAD=./t3.so date -onzin
    date: ongeldige optie -- o
    Probeer `date --help' voor meer informatie.
    exit code = 1

    --
    Huibert
    "Hey! HEY! Curious cat, here!" -- Krosp I (GG)

  10. Re: Is it possible to determine exit code in library destructor?

    On 1 Oct, 16:02, Arch Stanton wrote:
    > I have an interesting problem. I'm writing a shared library which is
    > inserted into an alien process via LD_PRELOAD. I have almost everything
    > working beautifully but the library needs to get access to the exit code
    > before quitting. Its destructor function is definitely called after
    > exit() so the value must be around someplace but I do not know a way to
    > get it. Any ideas?
    >


    I haven't had a chance to try it yet, but what about calling main()
    directly from your constructor, storing the return
    value, and then calling exit()? (I suspect there are
    some issues with doing that, but it might be an
    interesting thing to experiment with.) Is there a better
    way to avoid main being called after the constructor?
    Will calling exit() accomplish that cleanly?


  11. Re: Is it possible to determine exit code in library destructor?

    On 1 Oct, 16:02, Arch Stanton wrote:
    > I have an interesting problem. I'm writing a shared library which is
    > inserted into an alien process via LD_PRELOAD. I have almost everything
    > working beautifully but the library needs to get access to the exit code
    > before quitting. Its destructor function is definitely called after
    > exit() so the value must be around someplace but I do not know a way to
    > get it. Any ideas?
    >


    I haven't had a chance to try it yet, but what about calling main()
    directly from your constructor, storing the return
    value, and then calling exit()? (I suspect there are
    some issues with doing that, but it might be an
    interesting thing to experiment with.) Is there a better
    way to avoid main being called after the constructor?
    Will calling exit() accomplish that cleanly?


  12. Re: Is it possible to determine exit code in library destructor?

    Arch Stanton writes:

    > I have an interesting problem. I'm writing a shared library which is
    > inserted into an alien process via LD_PRELOAD. I have almost everything
    > working beautifully but the library needs to get access to the exit code
    > before quitting. Its destructor function is definitely called after
    > exit() so the value must be around someplace but I do not know a way to
    > get it. Any ideas?


    It seems like any approach is likely to be a hack. One idea might be
    to have your destructor function fork(). The child returns, and the
    parent wait()s in order to see what the exit code is.

  13. Re: Is it possible to determine exit code in library destructor?

    Arch Stanton writes:

    > I have an interesting problem. I'm writing a shared library which is
    > inserted into an alien process via LD_PRELOAD. I have almost everything
    > working beautifully but the library needs to get access to the exit code
    > before quitting. Its destructor function is definitely called after
    > exit() so the value must be around someplace but I do not know a way to
    > get it. Any ideas?


    It seems like any approach is likely to be a hack. One idea might be
    to have your destructor function fork(). The child returns, and the
    parent wait()s in order to see what the exit code is.

  14. Re: Is it possible to determine exit code in library destructor?

    Nate Eldredge wrote:
    > Arch Stanton writes:
    >
    >> I have an interesting problem. I'm writing a shared library which is
    >> inserted into an alien process via LD_PRELOAD. I have almost everything
    >> working beautifully but the library needs to get access to the exit code
    >> before quitting. Its destructor function is definitely called after
    >> exit() so the value must be around someplace but I do not know a way to
    >> get it. Any ideas?

    >
    > It seems like any approach is likely to be a hack. One idea might be
    > to have your destructor function fork(). The child returns, and the
    > parent wait()s in order to see what the exit code is.


    Wow! You might call that a hack. I'd call it the most twisted^Wbrilliant
    idea I've seen in a month. I just tried it and it works perfectly. Best
    of all, no kernel hackery, no assembly code to look in some hardwired
    register, no elevated privileges, just standard, elegant, portable Unix
    semantics. Thanks!

    Arch

  15. Re: Is it possible to determine exit code in library destructor?

    Nate Eldredge wrote:
    > Arch Stanton writes:
    >
    >> I have an interesting problem. I'm writing a shared library which is
    >> inserted into an alien process via LD_PRELOAD. I have almost everything
    >> working beautifully but the library needs to get access to the exit code
    >> before quitting. Its destructor function is definitely called after
    >> exit() so the value must be around someplace but I do not know a way to
    >> get it. Any ideas?

    >
    > It seems like any approach is likely to be a hack. One idea might be
    > to have your destructor function fork(). The child returns, and the
    > parent wait()s in order to see what the exit code is.


    Wow! You might call that a hack. I'd call it the most twisted^Wbrilliant
    idea I've seen in a month. I just tried it and it works perfectly. Best
    of all, no kernel hackery, no assembly code to look in some hardwired
    register, no elevated privileges, just standard, elegant, portable Unix
    semantics. Thanks!

    Arch

  16. Re: Is it possible to determine exit code in library destructor?

    William Pursell wrote:
    > On 1 Oct, 16:02, Arch Stanton wrote:
    >> I have an interesting problem. I'm writing a shared library which is
    >> inserted into an alien process via LD_PRELOAD. I have almost everything
    >> working beautifully but the library needs to get access to the exit code
    >> before quitting. Its destructor function is definitely called after
    >> exit() so the value must be around someplace but I do not know a way to
    >> get it. Any ideas?
    >>

    >
    > I haven't had a chance to try it yet, but what about calling main()
    > directly from your constructor, storing the return
    > value, and then calling exit()? (I suspect there are
    > some issues with doing that, but it might be an
    > interesting thing to experiment with.) Is there a better
    > way to avoid main being called after the constructor?
    > Will calling exit() accomplish that cleanly?


    You know, that's an very cute idea and it might be made to work, though
    I think you'll agree Nate Eldredge's idea is less intrusive. But this is
    another one I never thought of. Thanks.

    Arch

  17. Re: Is it possible to determine exit code in library destructor?

    William Pursell wrote:
    > On 1 Oct, 16:02, Arch Stanton wrote:
    >> I have an interesting problem. I'm writing a shared library which is
    >> inserted into an alien process via LD_PRELOAD. I have almost everything
    >> working beautifully but the library needs to get access to the exit code
    >> before quitting. Its destructor function is definitely called after
    >> exit() so the value must be around someplace but I do not know a way to
    >> get it. Any ideas?
    >>

    >
    > I haven't had a chance to try it yet, but what about calling main()
    > directly from your constructor, storing the return
    > value, and then calling exit()? (I suspect there are
    > some issues with doing that, but it might be an
    > interesting thing to experiment with.) Is there a better
    > way to avoid main being called after the constructor?
    > Will calling exit() accomplish that cleanly?


    You know, that's an very cute idea and it might be made to work, though
    I think you'll agree Nate Eldredge's idea is less intrusive. But this is
    another one I never thought of. Thanks.

    Arch

  18. Re: Is it possible to determine exit code in library destructor?

    Huibert Bol wrote:
    > Arch Stanton wrote:
    >
    >> I have an interesting problem. I'm writing a shared library which is
    >> inserted into an alien process via LD_PRELOAD. I have almost everything
    >> working beautifully but the library needs to get access to the exit code
    >> before quitting. Its destructor function is definitely called after
    >> exit() so the value must be around someplace but I do not know a way to
    >> get it. Any ideas?

    >
    > This works under Linux. I had to capture stdout, because date(1) from
    > the coreutils closes stdout before returning from main.


    Very nice, though I'm going to try Nate's fork/wait idea first as it
    seems somewhat simpler.

    Thanks,
    Arch

  19. Re: Is it possible to determine exit code in library destructor?

    Huibert Bol wrote:
    > Arch Stanton wrote:
    >
    >> I have an interesting problem. I'm writing a shared library which is
    >> inserted into an alien process via LD_PRELOAD. I have almost everything
    >> working beautifully but the library needs to get access to the exit code
    >> before quitting. Its destructor function is definitely called after
    >> exit() so the value must be around someplace but I do not know a way to
    >> get it. Any ideas?

    >
    > This works under Linux. I had to capture stdout, because date(1) from
    > the coreutils closes stdout before returning from main.


    Very nice, though I'm going to try Nate's fork/wait idea first as it
    seems somewhat simpler.

    Thanks,
    Arch

  20. Re: Is it possible to determine exit code in library destructor?

    Arch Stanton wrote:
    > William Pursell wrote:
    >> On 1 Oct, 16:02, Arch Stanton wrote:
    >>> I have an interesting problem. I'm writing a shared library which is
    >>> inserted into an alien process via LD_PRELOAD. I have almost everything
    >>> working beautifully but the library needs to get access to the exit code
    >>> before quitting. Its destructor function is definitely called after
    >>> exit() so the value must be around someplace but I do not know a way to
    >>> get it. Any ideas?
    >>>

    >>
    >> I haven't had a chance to try it yet, but what about calling main()
    >> directly from your constructor, storing the return
    >> value, and then calling exit()? (I suspect there are
    >> some issues with doing that, but it might be an
    >> interesting thing to experiment with.) Is there a better
    >> way to avoid main being called after the constructor?
    >> Will calling exit() accomplish that cleanly?

    >
    > You know, that's an very cute idea and it might be made to work, though
    > I think you'll agree Nate Eldredge's idea is less intrusive. But this is
    > another one I never thought of. Thanks.


    As I think further there are two, potentially solvable, problems with
    this one:

    1. The library constructor has no direct access to argv/argc. These can
    often be found via the traditional hack of going to the environ pointer
    and working back but it might not be too robust to depend on that.

    2. The runtime linker ensures that main() is not called until all shared
    libraries are loaded and initialized. If I call it myself I have to find
    some way to make sure all that setup work is done, i.e. to be sure my
    library is loaded last. And there may be other initializations between
    library loading and main(), I haven't looked.

    Arch

+ Reply to Thread
Page 1 of 2 1 2 LastLast