dh, the daemon helper - Unix

This is a discussion on dh, the daemon helper - Unix ; Rainer Weikusat writes: > Indeed. a[n] is defined as being identical to *(a + n), hence &a[n] is > the same as &*(a + n). Put into words: A 'pointer-to-type' value is > derefenced to yield a value of type ...

+ Reply to Thread
Page 2 of 4 FirstFirst 1 2 3 4 LastLast
Results 21 to 40 of 70

Thread: dh, the daemon helper

  1. Re: dh, the daemon helper

    Rainer Weikusat writes:

    > Indeed. a[n] is defined as being identical to *(a + n), hence &a[n] is
    > the same as &*(a + n). Put into words: A 'pointer-to-type' value is
    > derefenced to yield a value of type 'type', the address of which is
    > then taken, resulting in a value of type 'pointer-to-type': & and *
    > are inverse operations in this respect.


    But there is a technicality about &*. & and * cancel out in the sense
    that the standard says that neither is evaluated[1] so any description
    that suggests &* is a de-reference followed by taking the address of
    the result could lead people astray.

    In particular, given T x[N]; the expression &x[N] (== &*(x + N) ==
    x + N) is legal even though *(x + N) is undefined behaviour.

    [1] There are some extra words: the constraints still apply and the
    result is not a lvalue but the key part is that applying & to a *
    expression is defined by removing both operators, not by evaluating
    them.

    --
    Ben.

  2. Re: dh, the daemon helper

    Ben Bacarisse writes:
    > Rainer Weikusat writes:
    >> Indeed. a[n] is defined as being identical to *(a + n), hence &a[n] is
    >> the same as &*(a + n). Put into words: A 'pointer-to-type' value is
    >> derefenced to yield a value of type 'type', the address of which is
    >> then taken, resulting in a value of type 'pointer-to-type': & and *
    >> are inverse operations in this respect.

    >
    > But there is a technicality about &*. & and * cancel out in the sense
    > that the standard says that neither is evaluated[1] so any description
    > that suggests &* is a de-reference followed by taking the address of
    > the result could lead people astray.


    Well, but &* is a de-reference, followed by taking the address of the
    result. Which cancels out, so the sequence is a nop. I explicitly
    intended to imply that any such sequence is killed by the compiler
    because it doesn't mean anything.

    > In particular, given T x[N]; the expression &x[N] (== &*(x + N) ==
    > x + N) is legal even though *(x + N) is undefined behaviour.
    >
    > [1] There are some extra words: the constraints still apply and the
    > result is not a lvalue but the key part is that applying & to a *
    > expression is defined by removing both operators, not by evaluating
    > them.


    In turn, applying & to any valid operand means the operand isn't
    evaluated, but its address is used instead. Consequently, since
    x + N is required to be a valid pointer, &*(x + N) must be valid
    pointer, too. Otherwise, the &* would not be a two letter sequence
    whose combined meaning is 'no effect'.

    Or I completely misunderstand you.

    ?


  3. Re: dh, the daemon helper

    Rainer Weikusat writes:

    > scott@slp53.sl.home (Scott Lurndal) writes:
    >> Rainer Weikusat writes:
    >>> ... last but not
    >>>least - SIGSEGV is sent by the kernel to a process which attempted an
    >>>invalid memory access. The default action usually involves to
    >>>terminate the process and create a core dump of it[*].

    >> [snip]
    >>
    >>> [*] This very handy feature is typically disabled by 'current'
    >>> Linux-distribution, either to conceal the bugginess of the
    >>> software or because nobody wants to (or knows how to) fix it,
    >>> anyway.

    >>
    >> This is done for a very simple reason. A significant majority of
    >> the users of such distributions don't really care for core dumps
    >> filling their filesystem (and a poorly written daemon could quickly
    >> fill a filesystem with fairly useless core files).

    >
    > The problem with this approach is that it is not possible to decide
    > beforehand when core dumps should rather have been enabled. Generally
    > disabling them basically means to voluntarily decide to have no
    > interest in ever fixing a problem which would otherwise have caused
    > one, including to never help with fixing such a problem.
    >
    > This is a 'classic' example of how to remain comfortable in face of
    > (suspected) bad news by proactively shooting the mailman, based on the
    > assumption that these 'bad news' will never have any practical
    > relevance.


    That's a bit extreme, isn't it? A core dump is in general neither
    necessary nor sufficient to help fix problems.

    I myself try to fix bugs that I encounter, but I find that the core file
    generated by a random program crashing unexpectedly is not very useful.
    Generally the program in question has been stripped of debug info, so I
    have to recompile it using -g, at which point it no longer matches the
    core file. So in any case I have to be able to reproduce the bug before
    I can start trying to fix it. And at that point a core file is not
    really necessary; running the program under a debugger and waiting for
    it to crash is better than using a core dump, because I also get
    information about open files, etc.

    If the bug is hard to reproduce, the core file is of limited utility
    even when it does go with an unstripped binary. It contains the state
    of the program itself, but it doesn't contain the state of the rest of
    the system (what do files contain, what other processes are interacting
    with this one), nor the history of the program (what was the input data,
    what branches were taken, etc). These things are, in my experience,
    very often critical in finding a bug, especially an irreproducible one.

    I do keep core dumps enabled on my systems, but mostly out of
    convenience. On most of those few occasions when I really want a core
    dump, I know in advance (e.g. I'm about to run a program that I am
    pretty sure is going to crash), so I could just turn it on at that time,
    but I just leave it on all the time out of laziness. The other reason
    is that the core file serves as a visible reminder that something
    crashed, and that I should investigate it when I have time, but for this
    purpose the contents of the dump are really irrelevant. (An entry in a
    log file would be just as good, though less conspicuous.) So the vast
    majority of core files generated on my systems are deleted without ever
    being examined, and this is entirely consistent with getting things
    fixed.

    If you further discount these advantages for users who do not themselves
    have the knowledge to fix bugs (who are certainly the majority), then
    IMHO it is entirely reasonable for a distribution to disable core dumps
    by default. It isn't my personal preference, as I said above, but
    that's why they're easy to enable again.

  4. Re: dh, the daemon helper

    Rainer Weikusat wrote:
    > [... default suppression of core dumps ...]
    > The problem with this approach is that it is not possible to decide
    > beforehand when core dumps should rather have been enabled. Generally
    > disabling them basically means to voluntarily decide to have no
    > interest in ever fixing a problem which would otherwise have caused
    > one, including to never help with fixing such a problem.
    >
    > This is a 'classic' example of how to remain comfortable in face of
    > (suspected) bad news by proactively shooting the mailman, based on the
    > assumption that these 'bad news' will never have any practical
    > relevance.


    Consider also the security and privacy implications. A
    dump of a crashed program that was manipulating sensitive data
    is likely to reveal the data -- quite possibly in unencrypted
    form -- to anyone who gets a look at the core file. Note that
    the sensitivity of the data is a matter for the application's
    user, not its developer, to decide. An "opt-in" rather than an
    "opt-out" policy seems respectful of that distinction.

    --
    Eric Sosman
    esosman@ieee-dot-org.invalid

  5. Re: dh, the daemon helper

    Rainer Weikusat writes:

    > Ben Bacarisse writes:
    >> Rainer Weikusat writes:
    >>> Indeed. a[n] is defined as being identical to *(a + n), hence &a[n] is
    >>> the same as &*(a + n). Put into words: A 'pointer-to-type' value is
    >>> derefenced to yield a value of type 'type', the address of which is
    >>> then taken, resulting in a value of type 'pointer-to-type': & and *
    >>> are inverse operations in this respect.

    >>
    >> But there is a technicality about &*. & and * cancel out in the sense
    >> that the standard says that neither is evaluated[1] so any description
    >> that suggests &* is a de-reference followed by taking the address of
    >> the result could lead people astray.

    >
    > Well, but &* is a de-reference, followed by taking the address of the
    > result. Which cancels out, so the sequence is a nop. I explicitly
    > intended to imply that any such sequence is killed by the compiler
    > because it doesn't mean anything.


    I can't make those words mean the same as mine, so I think we disagree
    but I am not sure on what. The bit that bothers me is the notion that
    an & can cancel out the effect of an operation that might be undefined.

    &* /looks/ like a de-reference and an address-of operation but it is
    not. There must be no de-reference in a conforming implementation.
    Also, it is not exactly a no-op since &*x is not the same as x, even
    when x is a valid pointer (though they have the same value).

    >> In particular, given T x[N]; the expression &x[N] (== &*(x + N) ==
    >> x + N) is legal even though *(x + N) is undefined behaviour.
    >>
    >> [1] There are some extra words: the constraints still apply and the
    >> result is not a lvalue but the key part is that applying & to a *
    >> expression is defined by removing both operators, not by evaluating
    >> them.

    >
    > In turn, applying & to any valid operand means the operand isn't
    > evaluated, but its address is used instead.


    You must be using "evaluated" or "operand" in some different way to
    me. In an expression like &f()->x the operand of & is evaluated. I
    call f()->x the operand of & in the above. It is evaluated to yield
    an lvalue whose address is the result of the whole expression.

    (Note that -> is not defined in terms of . and * so there is no
    implied &* in the above expression; but if you don't like that
    example, then compound literals provide another: &(int){f()} clearly
    requires that the operand of & be evaluated.)

    > Consequently, since
    > x + N is required to be a valid pointer, &*(x + N) must be valid
    > pointer, too. Otherwise, the &* would not be a two letter sequence
    > whose combined meaning is 'no effect'.
    >
    > Or I completely misunderstand you.


    I don't know. I don't like calling &* a no-op (since it has a small
    effect on the meaning of the expression it is applied to) but I also
    think that explaining it in terms of a de-reference sounds confusing
    since no de-reference happens.

    --
    Ben.

  6. Re: dh, the daemon helper

    Eric Sosman writes:

    > Rainer Weikusat wrote:
    >> [... default suppression of core dumps ...]
    >> The problem with this approach is that it is not possible to decide
    >> beforehand when core dumps should rather have been enabled. Generally
    >> disabling them basically means to voluntarily decide to have no
    >> interest in ever fixing a problem which would otherwise have caused
    >> one, including to never help with fixing such a problem.
    >>
    >> This is a 'classic' example of how to remain comfortable in face of
    >> (suspected) bad news by proactively shooting the mailman, based on the
    >> assumption that these 'bad news' will never have any practical
    >> relevance.

    >
    > Consider also the security and privacy implications. A
    > dump of a crashed program that was manipulating sensitive data
    > is likely to reveal the data -- quite possibly in unencrypted
    > form -- to anyone who gets a look at the core file. Note that
    > the sensitivity of the data is a matter for the application's
    > user, not its developer, to decide. An "opt-in" rather than an
    > "opt-out" policy seems respectful of that distinction.


    Interestingly, on my system (FreeBSD) even pages that were mlock()ed are
    included in a core file. Arguably that's wrong. But I suppose this
    means if you have sensitive data that must not hit the disk, you should
    use not only mlock() but also setrlimit(RLIMIT_CORE, {0, max}).

  7. Re: dh, the daemon helper

    On Nov 2, 12:09 pm, Rainer Weikusat wrote:
    >
    > Well, but &* is a de-reference, followed by taking the address of the
    > result. Which cancels out, so the sequence is a nop. I explicitly
    > intended to imply that any such sequence is killed by the compiler
    > because it doesn't mean anything.


    I added some decoration to the code to quiet splint as much as
    possible. But it's been a while ago, I don't remember all of them ...




  8. Re: dh, the daemon helper

    On Oct 31, 4:31 pm, vipps...@gmail.com wrote:
    >
    > >ftp://ftp.isp2dial.com/users/jak/src/dh/

    >
    > First of all, you use perror/exit a lot. I'd write a function/macro if
    > I were you.


    Replacing two inline statements with one function call has dubious
    value. I tend to use functions when the body is more significant, as
    in logtime().


    > line 43,44 it wouldn't be bad if you had a comment explaining those
    > magic numbers.


    The macro names INTERVAL_ seemed self evident to me. Notice it's used
    with a nanosleep. But why? Good question.

    In an earlier revision of the code, I needed a sleep to make sure the
    parent process had time to die, and the child was adopted by init,
    *before* execing the target deamon. Very important.

    However, in a later revision, I added pipes to synchronize the
    grandparent and the child, so now the sleep should never happen. But
    it's still there, just in case. Now, it primarily serves to alert the
    programmer that something is not working as expected.


    > line 52 I think most C programmers prefer const char [] over char
    > const [] (no actual difference)


    I see that's been discussed later in the thread. As for style, I
    listen to get ideas from other people, but conformity to poplular
    culture holds little appeal for me. I'm too independent for that.


    > line 66,74 that should be isspace((unsigned char)**ts). is* and to*
    > functions expect a positive integer or EOF, and char may be signed.


    I thought EOF was -1. What's the problem?


    > line 62-81 can be replaced with keep = strtok(*ts, " \n\t\v\f\r");
    > if(keep) *ts = keep; strtok(NULL, " \n\t\v\f\r"); with only difference
    > that it won't behave exactly the same if the implementation has more
    > than the minimum characters in the space character class. (see IEEE
    > 1003.1, 2004: 7.3.1 LC_CTYPE). Since I don't like either solution I
    > might've considered to write a map function, and use isspace.


    I don't have time to analyze that now, so no comment.


    > line 143,156 can be replaced with if(lockname[0] == 0). There's no
    > reason to process the whole string. also line 369


    Good catch. I'll fix that up.


    > line 155 IMHO the parentheses in the expression &(argv[optind])
    > should be removed, like: trim(&argv[optind])


    That may have been a decoration for the sake of keeping splint quiet.
    But I don't really remember now ...


    > I'm curious how your code works since in line 161 you exit if usage is
    > non-zero, and at that point it can't have the value 0.
    > I haven't compiled it so I might be missing something.


    Works for me. Please compile and try it out. I provided a makefile.


    > line 177-213 should be replaced with some loop.
    > line 214 the cast is not needed. It'd be better if you just had
    > open_max a long instead of an int though.
    > line 225-226 change the conversion specifier from u to d and remove
    > the (unsigned int) cast. There's no benifit.
    > line 353 you have several memory leaks after this line, since you
    > do not free the return value of strdup on error.
    > line 395,395 can be replaced with a simple free(exectemp); free(NULL)
    > is defined to do nothing.
    > line 473,478 getpid returns a pid_t, which might not be int (it's
    > allowed to be any signed integer type). Use printf("%ld",
    > (long)getpid());
    > (you won't find any systems that have pid_t's with values bigger than
    > 2^31-1 but LONG_MAX at 2^31-1 - and even then, your process must have
    > such process id, which would give you implementation-defined behavior
    > or an implementation-defined signal)


    So many details. I'll try to study them when I have more time.


    > Lastly, I think you're overly verbose with error messages and error
    > checking.


    Failure to check and report every possible error is a great
    programming sin! Most of those errors will never happen under normal
    conditions. But if they do, the error messages are a hint something's
    gone wrong with the system itself.


    ftp://ftp.isp2dial.com/users/jak/src/dh/

    --
    Webmail for Dialup Users
    http://www.isp2dial.com/freeaccounts.html


  9. Re: dh, the daemon helper

    On Nov 3, 1:23 am, John Kelly wrote:
    > On Oct 31, 4:31 pm, vipps...@gmail.com wrote:
    >
    > > >ftp://ftp.isp2dial.com/users/jak/src/dh/

    >
    > > First of all, you use perror/exit a lot. I'd write a function/macro if
    > > I were you.

    >
    > Replacing two inline statements with one function call has dubious
    > value. I tend to use functions when the body is more significant, as
    > in logtime().


    Yeah, you don't win much - it's just what I'd do.

    > > line 43,44 it wouldn't be bad if you had a comment explaining those
    > > magic numbers.

    >
    > The macro names INTERVAL_ seemed self evident to me. Notice it's used
    > with a nanosleep. But why? Good question.


    Of course they are self evident to you, you wrote all that. ;-)

    > > line 66,74 that should be isspace((unsigned char)**ts). is* and to*
    > > functions expect a positive integer or EOF, and char may be signed.

    >
    > I thought EOF was -1. What's the problem?


    Actually the value of EOF is not related. Even if it was, EOF is
    guaranteed to be a negative integer, in the range [INT_MIN, -1]. (ie
    it doesn't need to be -1)
    Whta the problem is, is that the values that can be passed to is* and
    to* functions without breaking them are:

    o EOF
    o [0, UCHAR_MAX]

    The value of a char may not be in that range (ie you might pass -3,
    with EOF being -1)

    What can happend, many things. Depends on your implemenation, but you
    should know this is just incorrect to do. (invokes undefined behavior
    under both POSIX and ISO C)

    > > line 62-81 can be replaced with keep = strtok(*ts, " \n\t\v\f\r");
    > > if(keep) *ts = keep; strtok(NULL, " \n\t\v\f\r"); with only difference
    > > that it won't behave exactly the same if the implementation has more
    > > than the minimum characters in the space character class. (see IEEE
    > > 1003.1, 2004: 7.3.1 LC_CTYPE). Since I don't like either solution I
    > > might've considered to write a map function, and use isspace.

    >
    > I don't have time to analyze that now, so no comment.


    Well, on another look, the last strtok call is not needed.
    It's equivalent to if((keep = strtok(*ts, " \r\n\v\f\t")) != NULL) *ts
    = keep;
    (minus the minute details)

    > > I'm curious how your code works since in line 161 you exit if usage is
    > > non-zero, and at that point it can't have the value 0.
    > > I haven't compiled it so I might be missing something.

    >
    > Works for me. Please compile and try it out. I provided a makefile.


    Will do.

    > > Lastly, I think you're overly verbose with error messages and error
    > > checking.

    >
    > Failure to check and report every possible error is a great
    > programming sin! Most of those errors will never happen under normal
    > conditions. But if they do, the error messages are a hint something's
    > gone wrong with the system itself.


    I agree, but I think some of your error checks are imaginary. I'm not
    sure thought, I haven't really thought of every situation with your
    code.

  10. Re: dh, the daemon helper

    On Nov 2, 7:10 pm, vipps...@gmail.com wrote:

    > > > line 66,74 that should be isspace((unsigned char)**ts). is* and to*
    > > > functions expect a positive integer or EOF, and char may be signed.

    >
    > > I thought EOF was -1. What's the problem?

    >
    > Actually the value of EOF is not related. Even if it was, EOF is
    > guaranteed to be a negative integer, in the range [INT_MIN, -1]. (ie
    > it doesn't need to be -1)
    > Whta the problem is, is that the values that can be passed to is* and
    > to* functions without breaking them are:
    >
    > o EOF
    > o [0, UCHAR_MAX]
    >
    > The value of a char may not be in that range (ie you might pass -3,
    > with EOF being -1)
    >
    > What can happend, many things. Depends on your implemenation, but you
    > should know this is just incorrect to do. (invokes undefined behavior
    > under both POSIX and ISO C)


    I see.

    Earlier in the thread, Rainer said with C it doesn't matter where a
    char comes from, though I don't understand what he meant.
    Nevertheless, if the value violates the isspace() constraint, the
    result is unpredictable. But how is that a defect? Unless my raw
    (int) call to isspace() can crash the OS, or produce confusing output,
    I don't see how casting the value offers any benefit beyond the
    imaginary.

    --
    Webmail for Dialup Users
    http://www.isp2dial.com/freeaccounts.html

  11. Re: dh, the daemon helper

    Eric Sosman writes:
    > Rainer Weikusat wrote:
    >> [... default suppression of core dumps ...]
    >> The problem with this approach is that it is not possible to decide
    >> beforehand when core dumps should rather have been enabled.


    [...]

    > Consider also the security and privacy implications. A
    > dump of a crashed program that was manipulating sensitive data
    > is likely to reveal the data -- quite possibly in unencrypted
    > form -- to anyone who gets a look at the core file.


    Keeping anything 'sensitive' on a time-shared system where
    untrustworthy people have 'superuser access' ('sufficient privileges
    to read arbitrary files belonging to other users') is basically a
    mistake (it is even a mistake when combined with MAC, because the
    software intended to enforce that could have errors).


  12. Re: dh, the daemon helper

    Peter Nilsson wrote:
    > vipps...@gmail.com wrote:
    >> CBFalconer wrote:
    >>> You didn't cross-post and set follow-ups. So the
    >>> originator of the query will never see your answer,
    >>> unless you also committed the sin of multi-posting.

    >> You're possibly right. I don't know how to do that
    >> with googles interface.

    >
    > Same way you would with any other newsreader: enter
    > comma separated list of newsgroups, and add a followup.


    I use Thunderbird as my main newsreader. I'm not sure whether a comma
    delimited list is permitted. I'm using this message as a test by using a
    adding ", comp.unix.programmer" to the Newsgroup box at the top of the
    form. However, even if that works, the usual way I do it in Thunderbird
    is to click on a new header line, select "Newsgroup:" as the header
    type, and type in the second group name in the header value field.
    That's quite different from the way it's done in Google Groups.


    Saying "add a followup" doesn't really address the issue at all - the
    issue is how to actually do that. In Google Groups, you have to select a
    link titled "Add a followup-to", which adds a new box to the form where
    you can fill in multiple group names, separated by commas. In
    Thunderbird, for each group you want to add, you click on a new header
    line, select "Followup-To:" as the header type, and then type in the
    group name.

  13. Re: dh, the daemon helper

    On Nov 3, 6:13 am, John Kelly wrote:
    > On Nov 2, 7:10 pm, vipps...@gmail.com wrote:
    >
    > > > > line 66,74 that should be isspace((unsigned char)**ts). is* and to*
    > > > > functions expect a positive integer or EOF, and char may be signed.

    >
    > > > I thought EOF was -1. What's the problem?

    >
    > > Actually the value of EOF is not related. Even if it was, EOF is
    > > guaranteed to be a negative integer, in the range [INT_MIN, -1]. (ie
    > > it doesn't need to be -1)
    > > Whta the problem is, is that the values that can be passed to is* and
    > > to* functions without breaking them are:

    >
    > > o EOF
    > > o [0, UCHAR_MAX]

    >
    > > The value of a char may not be in that range (ie you might pass -3,
    > > with EOF being -1)

    >
    > > What can happend, many things. Depends on your implemenation, but you
    > > should know this is just incorrect to do. (invokes undefined behavior
    > > under both POSIX and ISO C)

    >
    > I see.
    >
    > Earlier in the thread, Rainer said with C it doesn't matter where a
    > char comes from, though I don't understand what he meant.


    Well Rainer said a lot of things that I didn't understand, and it's
    not because I lack any necessary knowledge.

    > Nevertheless, if the value violates the isspace() constraint, the
    > result is unpredictable. But how is that a defect? Unless my raw
    > (int) call to isspace() can crash the OS, or produce confusing output,
    > I don't see how casting the value offers any benefit beyond the
    > imaginary.


    It's a defect simply because the behavior is undefined.
    Now what could happend? The OS crashing is one thing (if the value at
    __istable[c] is a trap representation)
    Producing confusing output is more likely, since you don't know what
    resides in __istable[c] (note that __istable is the table your
    implementation uses to map characters - that doesn't mean you *do*
    have one)

    You don't have to worry about what will happend if you're a programmer
    - just avoid UB. If you want to take advantage of it, you can look
    into your implementation and see what is possible and what not for
    *your* implementation.


  14. Re: dh, the daemon helper

    On Nov 3, 2:10 am, vipps...@gmail.com wrote:
    > On Nov 3, 1:23 am, John Kelly wrote:
    >
    > > On Oct 31, 4:31 pm, vipps...@gmail.com wrote:
    > >
    > > > line 66,74 that should be isspace((unsigned char)**ts). is* and to*
    > > > functions expect a positive integer or EOF, and char may be signed.

    >
    > > I thought EOF was -1. What's the problem?

    >
    > Actually the value of EOF is not related. Even if it was, EOF is
    > guaranteed to be a negative integer, in the range [INT_MIN, -1]. (ie
    > it doesn't need to be -1)
    > Whta the problem is, is that the values that can be passed to is* and
    > to* functions without breaking them are:
    >
    > o EOF
    > o [0, UCHAR_MAX]
    >
    > The value of a char may not be in that range (ie you might pass -3,
    > with EOF being -1)
    >
    > What can happend, many things. Depends on your implemenation, but you
    > should know this is just incorrect to do. (invokes undefined behavior
    > under both POSIX and ISO C)


    What I wanted to add is that, technically, (unsigned char)**ts is also
    undefined behavior;
    **ts is allowed to be a trap representation.
    It'd be more correct as *(unsigned char *)*ts.

  15. Re: dh, the daemon helper

    Nate Eldredge writes:
    > Rainer Weikusat writes:
    >> scott@slp53.sl.home (Scott Lurndal) writes:


    [supressing coredumps by default]

    >>> This is done for a very simple reason. A significant majority of
    >>> the users of such distributions don't really care for core dumps
    >>> filling their filesystem (and a poorly written daemon could quickly
    >>> fill a filesystem with fairly useless core files).

    >>
    >> The problem with this approach is that it is not possible to decide
    >> beforehand when core dumps should rather have been enabled. Generally
    >> disabling them basically means to voluntarily decide to have no
    >> interest in ever fixing a problem which would otherwise have caused
    >> one, including to never help with fixing such a problem.


    [...]

    > That's a bit extreme, isn't it? A core dump is in general neither
    > necessary nor sufficient to help fix problems.


    And a compiler is in general neither necessary nor sufficient to
    program computers --- using the front-panel switches to enter octal
    numbers would be possible, too. The point was supposed to be that a
    coredump is the only source of accurate information about an
    unexpected 'crash' of some program which happened in the past.

    > I myself try to fix bugs that I encounter, but I find that the core file
    > generated by a random program crashing unexpectedly is not very useful.
    > Generally the program in question has been stripped of debug info, so I
    > have to recompile it using -g, at which point it no longer matches the
    > core file.


    That's a different problem: Debugging tools don't work very well with
    binaries compiled without debugging information. But you could still
    (at least) determine where the program met its untimely death and what
    the contents of the CPU registers where at that time. Digging through
    the contents of the stack do determine the call chain would still be
    possible, too. But generally, I agree with you: Binaries compiled
    without debugging information are too hard to debug to make this worth
    the effort except in special cases. Which would be a good reason to
    not do this.

    > So in any case I have to be able to reproduce the bug before
    > I can start trying to fix it.


    Generally, this is wrong. It is necessary to be able to reproduce the
    bug in order to experimentally verify that a supposed fix for it
    actually works.

    > And at that point a core file is not really necessary; running the
    > program under a debugger and waiting for it to crash is better than
    > using a core dump, because I also get information about open files,
    > etc.


    Well, the program could be using 39 different threads and be running
    on a small multiprocessor, continously interacting with 170 - 200
    'client programs' running on appliances distributed all around the
    world, IOW, the only actual information about the problem could be an
    occasional coredump. This is a real-world example and I have found
    this particular error a while ago (after two years of slowly hunting
    it down).

    > If the bug is hard to reproduce, the core file is of limited utility
    > even when it does go with an unstripped binary. It contains the state
    > of the program itself, but it doesn't contain the state of the rest of
    > the system (what do files contain, what other processes are interacting
    > with this one), nor the history of the program (what was the input data,
    > what branches were taken, etc). These things are, in my experience,
    > very often critical in finding a bug, especially an irreproducible
    > one.


    Incomplete information is a lot more helpful than 'no
    information'. Additionally, (in my experience) most 'crashes' are
    caused by simple errors (like not checking for null pointers before
    derefencing a pointer value) on rarely taken codepaths. And these are
    often extermly simple to fix, provided it is known where the program
    crashed because of which operation.

    > I do keep core dumps enabled on my systems, but mostly out of
    > convenience. On most of those few occasions when I really want a core
    > dump, I know in advance


    [...]

    > The other reason is that the core file serves as a visible reminder
    > that something crashed, and that I should investigate it when I have
    > time, but for this purpose the contents of the dump are really
    > irrelevant. (An entry in a log file would be just as good, though
    > less conspicuous.)


    [...]

    > If you further discount these advantages for users who do not themselves
    > have the knowledge to fix bugs (who are certainly the majority), then
    > IMHO it is entirely reasonable for a distribution to disable core dumps
    > by default.


    Especially for users who do not themselves have this knowledge, having
    a core dump would be an advantage, provided the user was interested in
    getting the issue resolved. "It crashed yesterday, but I do not know
    when, why or where and not even which signal ocurred" is completely
    useless as a bug report: It communicates the fact that some user is
    convinced there would be at least one unknown bug, which lead to the
    program exiting 'somehow' 'somewhen'.

    There is basically no possible reply to that save 'Sorry, but without
    any information, I cannot possibly do anything to help you'.

    NB: I do not claim that 'reasons for disabling coredump' would
    generally be invalid, just trying to demonstrate that this involved a
    tradeoff which can backfire.

  16. Re: dh, the daemon helper

    vippstar@gmail.com wrote:
    > On Nov 3, 2:10 am, vipps...@gmail.com wrote:
    >> On Nov 3, 1:23 am, John Kelly wrote:
    >>
    >>> On Oct 31, 4:31 pm, vipps...@gmail.com wrote:
    >>>
    >>>> line 66,74 that should be isspace((unsigned char)**ts). is* and to*
    >>>> functions expect a positive integer or EOF, and char may be signed.
    >>> I thought EOF was -1. What's the problem?

    >> Actually the value of EOF is not related. Even if it was, EOF is
    >> guaranteed to be a negative integer, in the range [INT_MIN, -1]. (ie
    >> it doesn't need to be -1)
    >> Whta the problem is, is that the values that can be passed to is* and
    >> to* functions without breaking them are:
    >>
    >> o EOF
    >> o [0, UCHAR_MAX]
    >>
    >> The value of a char may not be in that range (ie you might pass -3,
    >> with EOF being -1)
    >>
    >> What can happend, many things. Depends on your implemenation, but you
    >> should know this is just incorrect to do. (invokes undefined behavior
    >> under both POSIX and ISO C)

    >
    > What I wanted to add is that, technically, (unsigned char)**ts is also
    > undefined behavior;
    > **ts is allowed to be a trap representation.
    > It'd be more correct as *(unsigned char *)*ts.


    If you're trying to classify a character that holds a trap
    representation, your program is already in more trouble than a
    few casts can cure. That is, the fact that your program is asking
    about the space-ness or digit-ness of an uninitialized character
    variable is evidence that it's already gone off the rails.

    When you get a char from someplace, whether it be via a pointer
    or just directly from a char variable, the way to handle it with
    the functions is to convert that char value to unsigned
    char and thence to int:

    if (isupper( (unsigned char) the_char )) ...

    This form mimics the C Standard's own description of acceptable
    argument values: an int equal to EOF or equal to the character
    value converted to unsigned char. The formulation you suggest
    is type-punning, made more obvious if we think of an ordinary
    char variable:

    if (isupper( *((unsigned char*) &the_char) )) ...

    Type-punning is a regrettable habit, something we must indulge
    in from time to time but should avoid when it's not necessary. In
    this case it isn't necessary, so I vote to avoid it. Also, there's
    the smug satisfaction of knowing that the form I prefer will still
    work if ones' complement or signed magnitude machines ever make a
    comeback; that's pretty unlikely, but I've been in this industry
    long enough to realize that fashions come and go and return ...

    --
    Eric.Sosman@sun.com

  17. Re: dh, the daemon helper

    Eric Sosman writes:

    [...]

    > Also, there's the smug satisfaction of knowing that the form I
    > prefer will still work if ones' complement or signed magnitude
    > machines ever make a comeback; that's pretty unlikely, but I've been
    > in this industry long enough to realize that fashions come and go
    > and return ...


    The C-standard requires twos' complement for any implementation which
    supports integer with any or all of the widths 8, 16, 32 and 64 (via
    7.18.1.1, 1 & 3).

  18. Re: dh, the daemon helper

    On Nov 3, 5:39 pm, Eric Sosman wrote:
    > vipps...@gmail.com wrote:




    > > What I wanted to add is that, technically, (unsigned char)**ts is also
    > > undefined behavior;
    > > **ts is allowed to be a trap representation.
    > > It'd be more correct as *(unsigned char *)*ts.

    >
    > If you're trying to classify a character that holds a trap
    > representation, your program is already in more trouble than a
    > few casts can cure. That is, the fact that your program is asking
    > about the space-ness or digit-ness of an uninitialized character
    > variable is evidence that it's already gone off the rails.


    You're mistaken, **ts is initialized, from user input.
    I snip the rest since I generally agree.


  19. Re: dh, the daemon helper

    On Nov 3, 6:13 am, vipps...@gmail.com wrote:

    > > Nevertheless, if the value violates the isspace() constraint, the
    > > result is unpredictable. But how is that a defect?

    >
    > It's a defect simply because the behavior is undefined.


    How can you call isspace() with EOF if the value is cast to unsigned?
    The "standard" sounds self contradictory.

    > The isspace() function shall return non-zero if c is a white-space character;
    > otherwise, it shall return 0.
    >
    > ERRORS
    >
    > No errors are defined.


    So the "standard" says be careful with your input, but if you don't,
    we won't say anything. Why follow a self contradictory standard, when
    it makes no sense?

    --
    Webmail for Dialup Users
    http://www.isp2dial.com/freeaccounts.html

  20. Re: dh, the daemon helper

    On Nov 3, 5:52 pm, Rainer Weikusat wrote:
    > Eric Sosman writes:
    >
    > [...]
    >
    > > Also, there's the smug satisfaction of knowing that the form I
    > > prefer will still work if ones' complement or signed magnitude
    > > machines ever make a comeback; that's pretty unlikely, but I've been
    > > in this industry long enough to realize that fashions come and go
    > > and return ...

    >
    > The C-standard requires twos' complement for any implementation which
    > supports integer with any or all of the widths 8, 16, 32 and 64 (via
    > 7.18.1.1, 1 & 3).


    That's clearly wrong since it contradicts 7.18.1.1, p 3:

    > These types are optional. However, if an implementation provides integer types with
    > widths of 8, 16, 32, or 64 bits, no padding bits, and (for the signed types) that have a
    > two’s complement representation, it shall define the corresponding typedef names.


    AFAIK

+ Reply to Thread
Page 2 of 4 FirstFirst 1 2 3 4 LastLast