daemonizing not quite working - Linux

This is a discussion on daemonizing not quite working - Linux ; Hi, I have an application featuring a verbose mode and a daemon mode. It's working just fine in verbose mode but in daemon mode it doesn't quite seem to be functioning properly (doesn't send off signalss over TCP/IP or write ...

+ Reply to Thread
Results 1 to 15 of 15

Thread: daemonizing not quite working

  1. daemonizing not quite working

    Hi,

    I have an application featuring a verbose mode and a daemon mode.
    It's working just fine in verbose mode but in daemon mode it doesn't quite
    seem to be functioning properly (doesn't send off signalss over TCP/IP or
    write anything to the GPIOs - that's why i belive exit() is
    terminating "too much"),
    I get into Daemon mode with a fork command followed by exit() to be
    specific, it looks like:
    [C++]
    pid = fork();
    if (pid < 0)
    {
    exit(EXIT_FAILURE);
    }
    else if (pid > 0)
    {
    exit(EXIT_SUCCESS);
    }

    umask(0);

    sid = setsid();
    [/C++]
    Is there a problem with this? Do I miss anything?
    Thanks,
    Ron
    --
    weeks of software enineering safe hours of planing

  2. Re: daemonizing not quite working

    On Wed, 30 Apr 2008 23:17:36 GMT, Ron Eggler wrote:
    > Is there a problem with this? Do I miss anything?


    Have a look at http://www.developerweb.net/forum/showthread.php?t=3025

    BTW, exit will call all registered atexit handlers (including global object
    destructors) which might not be what you want...


    Christof

    --
    http://cmeerw.org sip:cmeerw at cmeerw.org
    mailto:cmeerw at cmeerw.org xmpp:cmeerw at cmeerw.org

  3. Re: daemonizing not quite working

    Christof Meerwald wrote:

    > On Wed, 30 Apr 2008 23:17:36 GMT, Ron Eggler wrote:
    >> Is there a problem with this? Do I miss anything?

    >
    > Have a look at http://www.developerweb.net/forum/showthread.php?t=3025


    Hm I think my code pretty much mirrors what it says there in the
    example...

    > BTW, exit will call all registered atexit handlers (including global
    > object destructors) which might not be what you want...


    I actually thought "yeSS! That must be it!" But a "grep atexit *" didn't
    return anything so i guess no luck with that one either
    Any other ideas?

    Thanks!
    Ron
    --
    weeks of software enineering safe hours of planing

  4. Re: daemonizing not quite working

    Ron Eggler wrote in
    newspmSj.3606$XI1.1678@edtnps91:

    > Christof Meerwald wrote:
    >
    >> On Wed, 30 Apr 2008 23:17:36 GMT, Ron Eggler wrote:
    >>> Is there a problem with this? Do I miss anything?

    >>
    >> Have a look at
    >> http://www.developerweb.net/forum/showthread.php?t=3025

    >
    > Hm I think my code pretty much mirrors what it says there in
    > the example...


    How so? The example terminates the original process by calling
    _exit(), your code calls exit(), which is incorrect.

    >
    >> BTW, exit will call all registered atexit handlers
    >> (including global object destructors) which might not be
    >> what you want...

    >
    > I actually thought "yeSS! That must be it!" But a "grep
    > atexit *" didn't return anything so i guess no luck with that
    > one either Any other ideas?


    I'm not clear on just what code you were grepping for atexit.
    There could be code in libraries (for example) that registers
    atexit handlers.

    MV

    --
    I do not want replies; please follow-up to the group.

  5. Re: daemonizing not quite working

    On Apr 30, 4:17 pm, Ron Eggler wrote:

    > (doesn't send off signalss over TCP/IP or
    > write anything to the GPIOs - that's why i belive exit() is
    > terminating "too much"),


    Exactly. The parent should not call 'exit', it should call '_exit'.
    Calling 'exit' may clean up things the child is still using.

    DS

  6. Re: daemonizing not quite working

    David Schwartz writes:
    > On Apr 30, 4:17 pm, Ron Eggler wrote:
    >> (doesn't send off signalss over TCP/IP or
    >> write anything to the GPIOs - that's why i belive exit() is
    >> terminating "too much"),

    >
    > Exactly. The parent should not call 'exit', it should call '_exit'.
    > Calling 'exit' may clean up things the child is still using.


    It may cause unpleasant side effects, eg printing still-buffered
    stdio output twice, but a subroutine call in one process cannot
    generally affect something in a another process. Assuming the 'deaf'
    process is running, it should be possible to attach to it with gdb (or
    strace) and determine what it is (or isn't) doing.

  7. Re: daemonizing not quite working

    On May 1, 11:20 pm, Rainer Weikusat wrote:

    > > Exactly. The parent should not call 'exit', it should call '_exit'.
    > > Calling 'exit' may clean up things the child is still using.


    > It may cause unpleasant side effects, eg printing still-buffered
    > stdio output twice, but a subroutine call in one process cannot
    > generally affect something in a another process.


    They share an awful lot of things that are not very shareable. If one
    process writes to a file, the other process' file pointer is moved. If
    one process calls 'shutdown' on a TCP connection, the other process
    loses that connection. It is common for programs to clean things up
    when 'exit' is called. These cleanups might include sending an "I'm
    terminating" message to a server over a TCP connection or flushing
    cached data to a file, moving the pointer.

    The first post's talk about TCP and I/O seem to point this way.

    DS

  8. Re: daemonizing not quite working

    David Schwartz writes:
    > On May 1, 11:20 pm, Rainer Weikusat wrote:
    >> > Exactly. The parent should not call 'exit', it should call '_exit'.
    >> > Calling 'exit' may clean up things the child is still using.

    >
    >> It may cause unpleasant side effects, eg printing still-buffered
    >> stdio output twice, but a subroutine call in one process cannot
    >> generally affect something in a another process.

    >
    > They share an awful lot of things that are not very shareable. If one
    > process writes to a file, the other process' file pointer is moved. If
    > one process calls 'shutdown' on a TCP connection, the other process
    > loses that connection.


    They share a few, well-defined things (memory mappings, file
    descriptions and message queue descriptions).

    > It is common for programs to clean things up when 'exit' is
    > called. These cleanups might include sending an "I'm
    > terminating" message to a server over a TCP connection or flushing
    > cached data to a file, moving the pointer.


    Minus flushing of stdio-streams and removing tmpfile-create files,
    these aren't effects of calling 'exit' but could only be caused by
    registered exit-handlers.

  9. Re: daemonizing not quite working

    David Schwartz wrote:

    > On Apr 30, 4:17 pm, Ron Eggler wrote:
    >
    >> (doesn't send off signalss over TCP/IP or
    >> write anything to the GPIOs - that's why i belive exit() is
    >> terminating "too much"),

    >
    > Exactly. The parent should not call 'exit', it should call '_exit'.
    > Calling 'exit' may clean up things the child is still using.


    well yes, instead of fork and _exit i now use the function:
    daemon(0,0); which is doing the same i belive but correctly
    but my problems are still existent, it would work fine in verbose mode but
    noit in daemon mode.
    Anyways, I'm thinking to just run it in verbose mode insteead but then the
    problem is that i use the funcxtion setsid() to creatre a pid file and it
    only seems to return a valid number if fork was called before... That' what
    makes me being stuck in this approach. So i need to get either or resolved.

    Thanks for any help, tips and comments!

    Ron

    --
    weeks of software enineering safe hours of planing

  10. Re: daemonizing not quite working

    unknown@example.com writes:
    > David Schwartz wrote:
    >> On Apr 30, 4:17 pm, Ron Eggler wrote:
    >>
    >>> (doesn't send off signalss over TCP/IP or
    >>> write anything to the GPIOs - that's why i belive exit() is
    >>> terminating "too much"),

    >>
    >> Exactly. The parent should not call 'exit', it should call '_exit'.
    >> Calling 'exit' may clean up things the child is still using.

    >
    > well yes, instead of fork and _exit i now use the function:
    > daemon(0,0); which is doing the same i belive but correctly
    > but my problems are still existent, it would work fine in verbose mode but
    > noit in daemon mode.


    As I already have tried to point out: It is unlikely that your problem
    is really related to the particular exit call. Instead of trying
    random hypothesises, you should try to DEBUG the issue. This means
    'determine what the daemonized process is doing' (as opposed to what
    it should be doing). There are a variety of options for doing so,
    ranging from inserting syslog or fprintf calls into the code to
    attaching a debugger to the running process and inspect what it is
    doing.

  11. Re: daemonizing not quite working

    Rainer Weikusat wrote:

    > unknown@example.com writes:
    >> David Schwartz wrote:
    >>> On Apr 30, 4:17 pm, Ron Eggler wrote:
    >>>
    >>>> (doesn't send off signalss over TCP/IP or
    >>>> write anything to the GPIOs - that's why i belive exit() is
    >>>> terminating "too much"),
    >>>
    >>> Exactly. The parent should not call 'exit', it should call '_exit'.
    >>> Calling 'exit' may clean up things the child is still using.

    >>
    >> well yes, instead of fork and _exit i now use the function:
    >> daemon(0,0); which is doing the same i belive but correctly
    >> but my problems are still existent, it would work fine in verbose mode
    >> but noit in daemon mode.

    >
    > As I already have tried to point out: It is unlikely that your problem
    > is really related to the particular exit call. Instead of trying
    > random hypothesises, you should try to DEBUG the issue. This means
    > 'determine what the daemonized process is doing' (as opposed to what
    > it should be doing). There are a variety of options for doing so,
    > ranging from inserting syslog or fprintf calls into the code to
    > attaching a debugger to the running process and inspect what it is
    > doing.

    I have tried to syslog things but didn't get very far . Debugger doesn't
    quite work since it's on an embedded system and we can not get gdb to
    work because of the microClib.
    --
    weeks of software enineering safe hours of planing

  12. Re: daemonizing not quite working


    Rainer Weikusat wrote:

    > Minus flushing of stdio-streams and removing tmpfile-create files,
    > these aren't effects of calling 'exit' but could only be caused by
    > registered exit-handlers.


    The effect of calling 'exit' is to run all registered exit-handlers.
    In the typical case, you call 'fork', and if you call 'exit' in the
    child, you have no idea what it's going to do. The effects depend on
    every piece of code, including system libraries.

    Suppose, for example, the system resolver opens up a TCP connection to
    the local resolver on the first resolve and closes it in an 'at exit'
    handler. If your code goes on to open up a TCP connection, it might
    get the same descriptor and then if it tries to do DNS, it will wind
    up sending arbitrary (potentially sensitive) data to a random
    (possibly hostile) network destination.

    DS

  13. Re: daemonizing not quite working

    David Schwartz writes:
    > Rainer Weikusat wrote:
    >
    >> Minus flushing of stdio-streams and removing tmpfile-create files,
    >> these aren't effects of calling 'exit' but could only be caused by
    >> registered exit-handlers.

    >
    > The effect of calling 'exit' is to run all registered exit-handlers.


    That's indeed its documented functionality.

    > In the typical case, you call 'fork', and if you call 'exit' in the
    > child, you have no idea what it's going to do.


    It is going to terminate the process after having done the documented
    'exit processing' and after any registered exit handlers have been
    executed.

    > The effects depend on every piece of code, including system
    > libraries.


    The effects depend on possibly registered exit handlers, not on the
    exit subroutine itself.

    > Suppose, for example, the system resolver opens up a TCP connection to
    > the local resolver on the first resolve and closes it in an 'at exit'
    > handler.


    That would be really uncommon for the C-library included 'stub
    resolver' and a fairly stupid implementation (why explicitly close a
    connection the kernel is going to close anyway.

    > If your code goes on to open up a TCP connection, it might
    > get the same descriptor and then if it tries to do DNS, it will wind
    > up sending arbitrary (potentially sensitive) data to a random
    > (possibly hostile) network destination.


    As long as descriptor in the child isn't closed (which an exit handler
    running in the context of the parent cannot do), this cannot happen:
    While the TCP 'virtual circuit' would be dead after the parent called
    shutdown (for whatever reasons), the 'socket file description',
    including the descriptor refering to it in the child will remain 'in
    use' until the descriptors in the child and in the parent (and any
    others that may refer to it) have been destroyed.

  14. Re: daemonizing not quite working

    Ron Eggler writes:
    > Rainer Weikusat wrote:


    [...]

    >> As I already have tried to point out: It is unlikely that your problem
    >> is really related to the particular exit call. Instead of trying
    >> random hypothesises, you should try to DEBUG the issue. This means
    >> 'determine what the daemonized process is doing' (as opposed to what
    >> it should be doing). There are a variety of options for doing so,
    >> ranging from inserting syslog or fprintf calls into the code to
    >> attaching a debugger to the running process and inspect what it is
    >> doing.

    > I have tried to syslog things but didn't get very far .


    Use it more liberally, then. Don't assume that you know what the
    code is doing (if you knew, it should be working, right?) but
    write code which tests any such assumption and 'makes a noise'
    otherwise (because I don't have a debugger on 'my' device platform,
    either, that's how I do nearly all of my debugging. It works quite
    well).

    > Debugger doesn't quite work since it's on an embedded system and we
    > can not get gdb to work because of the microClib.


    Possibly, you could use a local 'gdb stub' (see gdb documentation)
    and run gdb on the host platform, attaching to the stub
    (over serial, TCP etc).

  15. Re: daemonizing not quite working

    On May 5, 10:43*am, Rainer Weikusat wrote:

    > That would be really uncommon for the C-library included 'stub
    > resolver' and a fairly stupid implementation (why explicitly close a
    > connection the kernel is going to close anyway.


    Suppose the protocol requires some kind of signoff message to be sent.
    Not sending that message might be interpreted as a violation. In a
    secure computing environment, it might even be investigated.

    > > If your code goes on to open up a TCP connection, it might
    > > get the same descriptor and then if it tries to do DNS, it will wind
    > > up sending arbitrary (potentially sensitive) data to a random
    > > (possibly hostile) network destination.


    > As long as descriptor in the child isn't closed (which an exit handler
    > running in the context of the parent cannot do), this cannot happen:
    > While the TCP 'virtual circuit' would be dead after the parent called
    > shutdown (for whatever reasons), the 'socket file description',
    > including the descriptor refering to it in the child will remain 'in
    > use' until the descriptors in the child and in the parent (and any
    > others that may refer to it) have been destroyed.


    You are correct.

    The most serious concern, IMO, is data being written to files that
    shouldn't be written to files.

    DS

+ Reply to Thread