exit, signals and exceptions

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Siemel Naran

    exit, signals and exceptions

    (1) About std::exit. If I call this function, will the system call the
    destructors of all objects in the call stack. Eg.

    void f() { std::exit(1); }
    void g() { X x; f(); }

    Does the call in f() to std::exit invoke x.~X() in scope g()?


    (2) About signals and exceptions. Is it possible to throw an exception from
    a signal handler. On my compiler the program ends with the error in a
    dialog box:

    Project.exe faulted with message "applicatio n-defined exception". Process
    Stopped. Use Step or Run to continue.


    (3) So assuming that we can throw exceptions in signal handlers and that
    exit does cleanup, is the following a good way to invoke cleanup when
    either we exit normally, or throw an exception, or have a signal? My
    instinct says something is wrong here:


    int global_s = -1;


    void closesockets(in t sig)
    {
    if (global_s != -1)
    {
    closesocket(glo bal_s);
    global_s = -1;
    }
    if (sig) std::exit(sig);
    }

    class CloseSockets
    {
    public:
    CloseSockets() { }
    ~CloseSockets() { closesockets(0) ; }
    private:
    CloseSockets(co nst CloseSockets&); // not implemented
    CloseSockets& operator=(const CloseSockets&); // not implemented
    };


    void server()
    {
    CloseSockets _closesockets;

    int s = socket(AF_INET, SOCK_STREAM, 0);
    if (s == -1) throw std::runtime_er ror("fail socket");

    global_s = s;
    std::signal(SIG INT , &closesocket s); // are these even necessary?
    std::signal(SIG TERM, &closesocket s);
    std::signal(SIG ABRT, &closesocket s);

    sockaddr_in my_address;
    my_address.sin_ family = AF_INET;
    my_address.sin_ port = htons(1972);
    my_address.sin_ addr.s_addr = htonl(INADDR_LO OPBACK);
    std::memset(my_ address.sin_zer o, 0, sizeof(my_addre ss.sin_zero));

    int b = bind(s, convert(&my_add ress), sizeof(sockaddr ));
    if (b == -1) throw std::runtime_er ror("fail bind"); // will call
    _closesocket's destructor

    int l = listen(s, 10);
    if (l == -1) throw std::runtime_er ror("fail listen"); // will call
    _closesocket's destructor

    while (true)
    {
    ...
    }

    // will call _closesocket's destructor
    }



  • Fraser Ross

    #2
    Re: exit, signals and exceptions

    > (1) About std::exit. If I call this function, will the system call the[color=blue]
    > destructors of all objects in the call stack. Eg.
    >
    > void f() { std::exit(1); }
    > void g() { X x; f(); }
    >
    > Does the call in f() to std::exit invoke x.~X() in scope g()?[/color]

    std::exit does not do stack unwinding.

    Fraser.


    Comment

    • tom_usenet

      #3
      Re: exit, signals and exceptions

      On Fri, 07 May 2004 07:39:44 GMT, "Siemel Naran"
      <SiemelNaran@RE MOVE.att.net> wrote:
      [color=blue]
      >(1) About std::exit. If I call this function, will the system call the
      >destructors of all objects in the call stack. Eg.
      >
      >void f() { std::exit(1); }
      >void g() { X x; f(); }
      >
      >Does the call in f() to std::exit invoke x.~X() in scope g()?[/color]

      No. Objects of static storage duration are destructed ok, but those of
      automatic storage duration are not. (3.6.1/4)
      [color=blue]
      >(2) About signals and exceptions. Is it possible to throw an exception from
      >a signal handler. On my compiler the program ends with the error in a
      >dialog box:
      >
      >Project.exe faulted with message "applicatio n-defined exception". Process
      >Stopped. Use Step or Run to continue.[/color]

      It's implementation defined. You can use common C/C++ subset stuff in
      signal handlers, but if you try to use any C++ features such as RTTI
      and exceptions, you're at the mercy of your implementation. (18.7/5)

      Tom
      --
      C++ FAQ: http://www.parashift.com/c++-faq-lite/
      C FAQ: http://www.eskimo.com/~scs/C-faq/top.html

      Comment

      • Denis Remezov

        #4
        Re: exit, signals and exceptions

        Siemel Naran wrote:[color=blue]
        >
        >[/color]
        [snip]
        [color=blue]
        > (2) About signals and exceptions. Is it possible to throw an exception from
        > a signal handler. On my compiler the program ends with the error in a
        > dialog box:
        >
        > Project.exe faulted with message "applicatio n-defined exception". Process
        > Stopped. Use Step or Run to continue.[/color]
        [snip]

        If some implementation allowed that in principle (or perhaps some does?),
        all functions during whose execution an interrupt could occur, and which are
        also called by any destructor for automatic objects from the point of an
        interrupt up to the exception handler, would need to be reentrant.
        That would probably be quite inconvenient to enforce. Memory management
        functions, for example, are usually not reentrant.

        Denis

        Comment

        • Siemel Naran

          #5
          Re: exit, signals and exceptions

          "tom_usenet " <tom_usenet@hot mail.com> wrote in message[color=blue]
          > On Fri, 07 May 2004 07:39:44 GMT, "Siemel Naran"[/color]
          [color=blue][color=green]
          > >(1) About std::exit. If I call this function, will the system call the
          > >destructors of all objects in the call stack. Eg.[/color][/color]
          [color=blue]
          > No. Objects of static storage duration are destructed ok, but those of
          > automatic storage duration are not. (3.6.1/4)[/color]

          [color=blue][color=green]
          > >(2) About signals and exceptions. Is it possible to throw an exception[/color][/color]
          from[color=blue][color=green]
          > >a signal handler. On my compiler the program ends with the error in a
          > >dialog box:
          > >
          > >Project.exe faulted with message "applicatio n-defined exception". Process
          > >Stopped. Use Step or Run to continue.[/color]
          >
          > It's implementation defined. You can use common C/C++ subset stuff in
          > signal handlers, but if you try to use any C++ features such as RTTI
          > and exceptions, you're at the mercy of your implementation. (18.7/5)[/color]

          OK. So how do I solve my problem? I want it so that when the user presses
          Ctrl-C or eds the task from task manager (or the kill command in UNIX) then
          the system should shutdown gracefully. This means it should call the
          destructors of all objects, which means freeing dynamic memory, closing
          sockets, closing file handles, close SQL connections, etc.

          My feeling was to establish a signal handler. If the signal handler does
          nothing it seems the program resumes execution at the point where the signal
          was raised (kind of like the RESUME command in basic). So one of my
          thoughts was to throw an exception in the signal handler, and after
          returning control to the point in the function where the signal was raised,
          the program would detect the exception and perform stack unwinding. But as
          you point out, this does not work.

          In my code posted for point (3) I assumed std::exit calls destructors of
          local objects in all stacks, but this is also incorrect.

          So what else can we do? This seems to be a common problem, and I'm sure
          people have put much thought into it.


          Comment

          • Denis Remezov

            #6
            Re: exit, signals and exceptions

            Siemel Naran wrote:[color=blue]
            >
            > "tom_usenet " <tom_usenet@hot mail.com> wrote in message[color=green]
            > > On Fri, 07 May 2004 07:39:44 GMT, "Siemel Naran"[/color]
            >[color=green][color=darkred]
            > > >(1) About std::exit. If I call this function, will the system call the
            > > >destructors of all objects in the call stack. Eg.[/color][/color]
            >[color=green]
            > > No. Objects of static storage duration are destructed ok, but those of
            > > automatic storage duration are not. (3.6.1/4)[/color]
            >[color=green][color=darkred]
            > > >(2) About signals and exceptions. Is it possible to throw an exception[/color][/color]
            > from[color=green][color=darkred]
            > > >a signal handler. On my compiler the program ends with the error in a
            > > >dialog box:
            > > >
            > > >Project.exe faulted with message "applicatio n-defined exception". Process
            > > >Stopped. Use Step or Run to continue.[/color]
            > >
            > > It's implementation defined. You can use common C/C++ subset stuff in
            > > signal handlers, but if you try to use any C++ features such as RTTI
            > > and exceptions, you're at the mercy of your implementation. (18.7/5)[/color]
            >
            > OK. So how do I solve my problem? I want it so that when the user presses
            > Ctrl-C or eds the task from task manager (or the kill command in UNIX) then
            > the system should shutdown gracefully. This means it should call the
            > destructors of all objects, which means freeing dynamic memory, closing
            > sockets, closing file handles, close SQL connections, etc.
            >
            > My feeling was to establish a signal handler. If the signal handler does
            > nothing it seems the program resumes execution at the point where the signal
            > was raised (kind of like the RESUME command in basic). So one of my
            > thoughts was to throw an exception in the signal handler, and after
            > returning control to the point in the function where the signal was raised,
            > the program would detect the exception and perform stack unwinding. But as
            > you point out, this does not work.
            >
            > In my code posted for point (3) I assumed std::exit calls destructors of
            > local objects in all stacks, but this is also incorrect.
            >
            > So what else can we do? This seems to be a common problem, and I'm sure
            > people have put much thought into it.[/color]

            I would try to limit myself to simple things within a signal handler, such
            as, for example, setting a global flag to indicate that a particular interrupt
            has occured. This flag can be examined later in a synchronous way, within a
            normal execution flow, when it is safe to throw an exception.
            Granted, you could do more in some cases. For instance, there are a number
            of POSIX functions that can be called asynchronously.

            Denis

            Comment

            • Siemel Naran

              #7
              Re: exit, signals and exceptions

              "Denis Remezov" <REMOVETHISdeni s_remezov@yahoo .removethis.ca> wrote in
              message[color=blue]
              > Siemel Naran wrote:[/color]
              [color=blue][color=green]
              > > (2) About signals and exceptions. Is it possible to throw an exception[/color][/color]
              from[color=blue][color=green]
              > > a signal handler. On my compiler the program ends with the error in a
              > > dialog box:
              > >
              > > Project.exe faulted with message "applicatio n-defined exception".[/color][/color]
              Process[color=blue][color=green]
              > > Stopped. Use Step or Run to continue.[/color]
              > [snip]
              >
              > If some implementation allowed that in principle (or perhaps some does?),
              > all functions during whose execution an interrupt could occur, and which[/color]
              are[color=blue]
              > also called by any destructor for automatic objects from the point of an
              > interrupt up to the exception handler, would need to be reentrant.
              > That would probably be quite inconvenient to enforce. Memory management
              > functions, for example, are usually not reentrant.[/color]

              Sorry, I'm not too familiar with this concept of re-entrant. Did a search
              on google, and found statements about it like it allows two processes to
              call the same function. But you can do this anyway! Do they mean that the
              function instances share the same local variables?

              So assuming these re-entrant functions were to become standard in C++, how
              would you write the code using re-entrant functions, and satisying the
              conditions in my response to tom_usenet?

              OK. So how do I solve my problem? I want it so that when the user presses
              Ctrl-C or eds the task from task manager (or the kill command in UNIX) then
              the system should shutdown gracefully. This means it should call the
              destructors of all objects, which means freeing dynamic memory, closing
              sockets, closing file handles, close SQL connections, etc.

              ....

              Thanks.


              Comment

              • Siemel Naran

                #8
                Re: exit, signals and exceptions

                "Denis Remezov" <REMOVETHISdeni s_remezov@yahoo .removethis.ca> wrote in
                message[color=blue]
                > Siemel Naran wrote:[/color]
                [color=blue][color=green]
                > > OK. So how do I solve my problem? I want it so that when the user[/color][/color]
                presses[color=blue][color=green]
                > > Ctrl-C or eds the task from task manager (or the kill command in UNIX)[/color][/color]
                then[color=blue][color=green]
                > > the system should shutdown gracefully. This means it should call the
                > > destructors of all objects, which means freeing dynamic memory, closing
                > > sockets, closing file handles, close SQL connections, etc.[/color][/color]
                [color=blue]
                > I would try to limit myself to simple things within a signal handler, such
                > as, for example, setting a global flag to indicate that a particular[/color]
                interrupt[color=blue]
                > has occured. This flag can be examined later in a synchronous way, within[/color]
                a[color=blue]
                > normal execution flow, when it is safe to throw an exception.
                > Granted, you could do more in some cases. For instance, there are a[/color]
                number[color=blue]
                > of POSIX functions that can be called asynchronously.[/color]

                Yes, this came to mind too, but it means that in the main code I have to
                have these if statements all over the place to check if the global flag is
                set. Like in the code

                connect;
                while (true) {
                receive from socket;
                }
                return;

                that might have to become

                connect;
                while (true) {
                if (g_sigint) throw SigInt();
                receive from socket;
                }
                if (g_sigint) throw SigInt();
                return;

                etc, etc. Maybe need even more throw SigInt expressions.

                Perhaps there is some longjmp thing that can do it for me?


                Comment

                • Denis Remezov

                  #9
                  Re: exit, signals and exceptions

                  Siemel Naran wrote:[color=blue]
                  >
                  > "Denis Remezov" <REMOVETHISdeni s_remezov@yahoo .removethis.ca> wrote in
                  > message[color=green]
                  > > Siemel Naran wrote:[/color]
                  >[color=green][color=darkred]
                  > > > (2) About signals and exceptions. Is it possible to throw an exception[/color][/color]
                  > from[color=green][color=darkred]
                  > > > a signal handler. On my compiler the program ends with the error in a
                  > > > dialog box:
                  > > >
                  > > > Project.exe faulted with message "applicatio n-defined exception".[/color][/color]
                  > Process[color=green][color=darkred]
                  > > > Stopped. Use Step or Run to continue.[/color]
                  > > [snip]
                  > >
                  > > If some implementation allowed that in principle (or perhaps some does?),
                  > > all functions during whose execution an interrupt could occur, and which[/color]
                  > are[color=green]
                  > > also called by any destructor for automatic objects from the point of an
                  > > interrupt up to the exception handler, would need to be reentrant.
                  > > That would probably be quite inconvenient to enforce. Memory management
                  > > functions, for example, are usually not reentrant.[/color]
                  >
                  > Sorry, I'm not too familiar with this concept of re-entrant. Did a search
                  > on google, and found statements about it like it allows two processes to
                  > call the same function. But you can do this anyway! Do they mean that the
                  > function instances share the same local variables?
                  >[/color]

                  What I meant was well-definedness of concurrent invocations within one process.
                  A pure function will be reentrant (i.e. on the systems that you are probably
                  interested in).
                  A function that uses a global variable, obviously, may well not be (but still
                  can in specific cases).

                  The term is often used in regards to multithreading. There, reentrancy can
                  often be achieved by associating a required global state with a thread.

                  Signal handling [back on topic] is different. On the system that I'm working
                  with, a handler will have the context of the thread in which it was registered.
                  I am under the impression that functions that use a per-thread global state
                  (e.g. malloc()) are often not reentrant in regards to asynchronous signal
                  handler invocations.

                  Denis

                  Comment

                  • Paavo Helde

                    #10
                    Re: exit, signals and exceptions

                    "Siemel Naran" <SiemelNaran@RE MOVE.att.net> wrote in message news:<uR8nc.329 77$Ut1.945330@b gtnsc05-news.ops.worldn et.att.net>...[color=blue]
                    > OK. So how do I solve my problem? I want it so that when the user presses
                    > Ctrl-C or eds the task from task manager (or the kill command in UNIX) then
                    > the system should shutdown gracefully. This means it should call the
                    > destructors of all objects, which means freeing dynamic memory, closing
                    > sockets, closing file handles, close SQL connections, etc.[/color]

                    Have you considered to use _exit() instead of exit()? The exit()
                    function will call destructors for static objects (and other
                    atexit/onexit things), which might lead to errors if the program state
                    is not what these destructors expect. _exit() does not call anything
                    and shuts down your program very gracefully and very fast. The
                    operating system (MS-DOS not counted ;-) will release the dynamic
                    memory, close sockets, close file handles (buffers not flushed) and
                    other OS-allocated resources, so that's about what you asked for :-)

                    If you need a specific cleanup for some sort of resource (SQL
                    connections?) then you can't use _exit(). But you can register these
                    resources (and only these!) by some static manager object and rely on
                    exit() to call it's dtor.

                    Regards
                    Paavo

                    Comment

                    • Siemel Naran

                      #11
                      Re: exit, signals and exceptions

                      "Paavo Helde" <paavo@ebi.ee > wrote in message[color=blue]
                      > "Siemel Naran" <SiemelNaran@RE MOVE.att.net> wrote in message[/color]
                      news:<uR8nc.329 77
                      [color=blue]
                      > Have you considered to use _exit() instead of exit()? The exit()[/color]

                      Is this in the standard? Since it begins with an underscore, probably not.



                      Comment

                      • tom_usenet

                        #12
                        Re: exit, signals and exceptions

                        On Sat, 08 May 2004 17:33:14 GMT, "Siemel Naran"
                        <SiemelNaran@RE MOVE.att.net> wrote:
                        [color=blue]
                        >OK. So how do I solve my problem? I want it so that when the user presses
                        >Ctrl-C or eds the task from task manager (or the kill command in UNIX) then
                        >the system should shutdown gracefully. This means it should call the
                        >destructors of all objects, which means freeing dynamic memory, closing
                        >sockets, closing file handles, close SQL connections, etc.[/color]

                        I think you need to register some cleanup handlers with atexit, or use
                        objects of static storage duration (such as singletons). It's a pain,
                        but it works. Remember, the OS will release almost everything for you
                        on a modern OS, so you only need handlers for certain things.

                        Tom
                        --
                        C++ FAQ: http://www.parashift.com/c++-faq-lite/
                        C FAQ: http://www.eskimo.com/~scs/C-faq/top.html

                        Comment

                        • Paavo Helde

                          #13
                          Re: exit, signals and exceptions

                          "Siemel Naran" <SiemelNaran@RE MOVE.att.net> wrote in message news:<6RZoc.291 5$hH.68139@bgtn sc04-news.ops.worldn et.att.net>...[color=blue]
                          > "Paavo Helde" <paavo@ebi.ee > wrote in message[color=green]
                          > > "Siemel Naran" <SiemelNaran@RE MOVE.att.net> wrote in message[/color]
                          > news:<uR8nc.329 77
                          >[color=green]
                          > > Have you considered to use _exit() instead of exit()? The exit()[/color]
                          >
                          > Is this in the standard? Since it begins with an underscore, probably not.[/color]

                          You are right, _exit() is not in ANSI/ISO C, but it's in POSIX which
                          for most applications is portable enough IMHO. Of course your mileage
                          may vary.

                          Regards
                          Paavo

                          Comment

                          Working...