setjmp,longjmp, sigsetjmp implementation

Discussion in 'C Programming' started by Borneq, Dec 11, 2012.

  1. Borneq

    Borneq Guest

    Where I can find setjmp,longjmp, sigsetjmp implementation? In GCC source I
    can't find.
     
    Borneq, Dec 11, 2012
    #1
    1. Advertising

  2. Borneq

    Borneq Guest

    Borneq, Dec 11, 2012
    #2
    1. Advertising

  3. Borneq

    Borneq Guest

    Borneq, Dec 11, 2012
    #3
  4. Borneq

    Noob Guest

    Noob, Dec 11, 2012
    #4
  5. Borneq

    Borneq Guest

    Uzytkownik "Noob" <root@127.0.0.1> napisal w wiadomosci
    news:ka7744$178$...
    >> Where I can find setjmp, longjmp, sigsetjmp implementation?

    >
    > e.g. http://sourceware.org/git/?p=glibc.git;a=tree;f=setjmp


    This call low level functions, longjmp.c :

    #include <setjmp.h>
    void
    __libc_siglongjmp (sigjmp_buf env, int val)
    {
    /* Perform any cleanups needed by the frames being unwound. */
    _longjmp_unwind (env, val);

    if (env[0].__mask_was_saved)
    /* Restore the saved signal mask. */
    (void) __sigprocmask (SIG_SETMASK, &env[0].__saved_mask,
    (sigset_t *) NULL);

    /* Call the machine-dependent function to restore machine state. */
    __longjmp (env[0].__jmpbuf, val ?: 1);
    }

    longjmp_unwind ,__sigprocmask, __longjmp are in other library? In assembly?
     
    Borneq, Dec 11, 2012
    #5
  6. Borneq

    Noob Guest

    Noob, Dec 11, 2012
    #6
  7. Borneq

    Borneq Guest

    Borneq, Dec 11, 2012
    #7
  8. Borneq

    BartC Guest

    "Noob" <root@127.0.0.1> wrote in message news:ka7b08$n4m$...
    > Borneq wrote:
    >
    >> longjmp_unwind, __sigprocmask, __longjmp are in other library?

    >
    > 1) tar xjf glibc-2.16.0.tar.bz2
    > 2) grep -rn __longjmp glibc-2.16.0
    >
    > e.g.
    > http://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/i386/__longjmp.S


    This is not C. In that case why does it need to be that complicated? I used
    to do this in just 3 instructions:

    mov esp,[spsave]
    mov ebp,[bpsave]
    jmp [....]

    It worked.

    --
    Bartc
     
    BartC, Dec 12, 2012
    #8
  9. BartC wrote:
    >
    >
    > "Noob" <root@127.0.0.1> wrote in message news:ka7b08$n4m$...
    >> Borneq wrote:
    >>
    >>> longjmp_unwind, __sigprocmask, __longjmp are in other library?

    >>
    >> 1) tar xjf glibc-2.16.0.tar.bz2
    >> 2) grep -rn __longjmp glibc-2.16.0
    >>
    >> e.g.
    >> http://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/i386/__longjmp.S

    >
    > This is not C. In that case why does it need to be that complicated? I
    > used to do this in just 3 instructions:
    >
    > mov esp,[spsave]
    > mov ebp,[bpsave]
    > jmp [....]
    >
    > It worked.
    >


    Doesn't the whole machine state have to be
    saved/restored(registers/Fp/SSE/flags etc)? What if the calling function
    was using some regs for local vars etc ?!...
     
    Johann Klammer, Dec 12, 2012
    #9
  10. Borneq

    Nobody Guest

    On Wed, 12 Dec 2012 15:19:57 +0100, Johann Klammer wrote:

    > Doesn't the whole machine state have to be
    > saved/restored(registers/Fp/SSE/flags etc)?


    No.

    > What if the calling function was using some regs for local vars etc ?!...


    7.13.2.1p3:

    All accessible objects have values as of the time longjmp was
    called, except that the values of objects of automatic storage
    duration that are local to the function containing the
    invocation of the corresponding setjmp macro that do not have
    volatile-qualified type and have been changed between the
    setjmp invocation and longjmp call are indeterminate.

    gcc will warn about such cases with e.g.:

    warning: variable ‘foo’ might be clobbered by ‘longjmp’ or ‘vfork’

    Typically, only the "essential" registers (program counter, stack pointer,
    frame pointer) are preserved. Registers holding local variables or
    intermediate results aren't required to be preserved (and usually aren't).
    "Global" state isn't modified by longjmp and, AIUI, that includes the FP
    environment (<fenv.h>).
     
    Nobody, Dec 12, 2012
    #10
  11. Nobody wrote:
    > 7.13.2.1p3:
    >
    > All accessible objects have values as of the time longjmp was
    > called, except that the values of objects of automatic storage
    > duration that are local to the function containing the
    > invocation of the corresponding setjmp macro that do not have
    > volatile-qualified type and have been changed between the
    > setjmp invocation and longjmp call are indeterminate.
    >
    > gcc will warn about such cases with e.g.:
    >
    > warning: variable ‘foo’ might be clobbered by ‘longjmp’ or ‘vfork’
    >
    > Typically, only the "essential" registers (program counter, stack pointer,
    > frame pointer) are preserved. Registers holding local variables or
    > intermediate results aren't required to be preserved (and usually aren't).
    > "Global" state isn't modified by longjmp and, AIUI, that includes the FP
    > environment (<fenv.h>).
    >


    That is Interesting, as I do remember that the gcc variant for atmel's
    avr uCs _did_ save/restore all 32 general purpose registers in addition
    to SP/PC. At that time I was wondering why the jmp_buf thingy would take
    up so much memory. But then, avr-gcc does allow the user to reserve
    registers for global variables which would make this behavior necessary
    to preserve global objects...
     
    Johann Klammer, Dec 12, 2012
    #11
  12. Borneq

    Eric Sosman Guest

    On 12/12/2012 9:38 AM, Nobody wrote:
    > On Wed, 12 Dec 2012 15:19:57 +0100, Johann Klammer wrote:
    >
    >> Doesn't the whole machine state have to be
    >> saved/restored(registers/Fp/SSE/flags etc)?

    >
    > No.


    s/No/Maybe/

    >> What if the calling function was using some regs for local vars etc ?!...

    >
    > 7.13.2.1p3:
    >
    > All accessible objects have values as of the time longjmp was
    > called, except that the values of objects of automatic storage
    > duration that are local to the function containing the
    > invocation of the corresponding setjmp macro that do not have
    > volatile-qualified type and have been changed between the
    > setjmp invocation and longjmp call are indeterminate.
    >
    > gcc will warn about such cases with e.g.:
    >
    > warning: variable ‘foo’ might be clobbered by ‘longjmp’ or ‘vfork’
    >
    > Typically, only the "essential" registers (program counter, stack pointer,
    > frame pointer) are preserved. Registers holding local variables or
    > intermediate results aren't required to be preserved (and usually aren't).
    > "Global" state isn't modified by longjmp and, AIUI, that includes the FP
    > environment (<fenv.h>).


    The "essential" state may also include "general-purpose"
    registers designated by function linkage conventions. For example,
    if the rule is that a function is free to clobber R0-R7 but must
    return with R8-RF unchanged (i.e., it must save and restore R8-RF
    if it wants to use them), then R8-RF are "essential" from the point
    of view of the calling convention:

    f1(): Saves R8, puts 42 in it, calls f2()

    f2(): Doesn't use R8, calls setjmp(), calls f3()

    f3(): Saves R8, puts -137 in it, calls longjmp()

    f2(): On setjmp()'s second return, returns to f1()

    f1(): "Gee, I hope R8 still holds 42 ..."

    f3() would have restored R8, but longjmp() blew right past that
    code. f2() never touched R8, and so has no reason to restore it.
    The upshot is that f1() -- a function that never called either
    setjmp() or longjmp(), nor even knew anybody else was using
    them! -- gets trashed if setjmp()/longjmp() fail to save and
    restore R8-RF.

    --
    Eric Sosman
    d
     
    Eric Sosman, Dec 12, 2012
    #12
  13. Borneq

    BartC Guest

    "Johann Klammer" <1.net> wrote in message
    news:50c89288$0$1577$...
    > BartC wrote:


    >> "Noob" <root@127.0.0.1> wrote in message
    >> news:ka7b08$n4m$...


    >>> http://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/i386/__longjmp.S

    >>
    >> This is not C. In that case why does it need to be that complicated? I
    >> used to do this in just 3 instructions:
    >>
    >> mov esp,[spsave]
    >> mov ebp,[bpsave]
    >> jmp [....]
    >>
    >> It worked.
    >>

    >
    > Doesn't the whole machine state have to be
    > saved/restored(registers/Fp/SSE/flags etc)? What if the calling function
    > was using some regs for local vars etc ?!...


    I assume by 'calling function' you mean the one executing the 'longjmp'.

    That function will have just bailed out (due to an exception, error
    condition, whatever). Would it really be expected to resume exactly where it
    left off later on? This isn't implementing an interrupt handler.

    If you mean the function executing the 'setjmp': how many of those things
    you mentioned are actually saved and restored during a routine function
    call? Possibly the registers if in the middle of a calculation. But when you
    come back after longjmp, you're no longer in the middle of that calculation!
    Anyway I knew exactly what was going on in my hardware, and presumably the
    OP will know his.

    (I've never used C's setjmp/longjmp; this inline code was what I sometimes
    used to achieve the same thing. This only implements one exception level,
    but I can't see it being difficult to do several levels. It would be set up
    like this.

    mov [spsave],esp
    mov [bpsave],ebp
    mov dword [irecovery],recoverypoint

    ....Start doing stuff
    ....Normal termination

    recoverypoint: # somewhere in the same function
    .... only get to here when something's gone wrong (unless you want to
    fall-through to here from a normal finish)

    Code used to return from an error (as shown above):
    mov esp,[spsave]
    mov ebp,[bpsave]
    jmp [irecovery] )


    --
    Bartc
     
    BartC, Dec 12, 2012
    #13
  14. BartC wrote:
    [snip]
    > If you mean the function executing the 'setjmp': how many of those things
    > you mentioned are actually saved and restored during a routine function
    > call? Possibly the registers if in the middle of a calculation. But when
    > you
    > come back after longjmp, you're no longer in the middle of that
    > calculation!

    Yes, I meant the latter... to the compiler the setjmp is just a function
    call, nothing else. It has been some time since I read up on calling
    conventions, but I believe that the compiler is _not_ required to save
    and restore _all_ of the registers on entry/exit of every function
    call...? How does the compiler know you're not in 'the middle' of a
    calculation anymore. Are you in 'the middle' if you are using some local
    further down again after the return from setjmp?

    > Anyway I knew exactly what was going on in my hardware, and presumably the
    > OP will know his.


    He might not know what his compiler does with it..(no one really does)
    They do funny things for speed gain.
     
    Johann Klammer, Dec 13, 2012
    #14
  15. Johann Klammer <1.net> wrote:
    > BartC wrote:

    [snip]
    >> If you mean the function executing the 'setjmp': how many of those
    >> things you mentioned are actually saved and restored during a
    >> routine function call?


    >> Possibly the registers if in the middle of a calculation. But when
    >> you come back after longjmp, you're no longer in the middle of that
    >> calculation!


    > Yes, I meant the latter... to the compiler the setjmp is just a function
    > call, nothing else.


    Is that really true? Seems to me that compilers can optimize stdlib
    functions anyway they want, and that might include special case for
    setjmp if needed.

    > It has been some time since I read up on calling conventions,
    > but I believe that the compiler is _not_ required to save
    > and restore _all_ of the registers on entry/exit of every function
    > call...? How does the compiler know you're not in 'the middle' of a
    > calculation anymore. Are you in 'the middle' if you are using some local
    > further down again after the return from setjmp?


    Register save convention is pretty much system (usually OS) dependent.
    Seems to me that setjmp() has to follow the system convention.

    >> Anyway I knew exactly what was going on in my hardware, and
    >> presumably the OP will know his.


    > He might not know what his compiler does with it..(no one really does)
    > They do funny things for speed gain.


    They do.

    Also, on some the caller saves registers that it needs saved, and
    others the callee saves registers that it will change.

    -- glen
     
    glen herrmannsfeldt, Dec 13, 2012
    #15
  16. On Wednesday, December 12, 2012 8:13:05 PM UTC-6, Johann Klammer wrote:
    > BartC wrote:
    >
    > [snip]
    >
    > > If you mean the function executing the 'setjmp': how many of those things

    >
    > > you mentioned are actually saved and restored during a routine function

    >
    > > call? Possibly the registers if in the middle of a calculation. But when

    >
    > > you

    >
    > > come back after longjmp, you're no longer in the middle of that

    >
    > > calculation!

    >
    > Yes, I meant the latter... to the compiler the setjmp is just a function
    >
    > call, nothing else. It has been some time since I read up on calling
    >
    > conventions, but I believe that the compiler is _not_ required to save
    >
    > and restore _all_ of the registers on entry/exit of every function
    >
    > call...? How does the compiler know you're not in 'the middle' of a
    >
    > calculation anymore. Are you in 'the middle' if you are using some local
    >
    > further down again after the return from setjmp?
    >


    But isn't setjmp() only allowed within a condition (if, switch, etc.)? It's *not* just a function call.
     
    luser- -droog, Dec 13, 2012
    #16
  17. Borneq

    Noob Guest

    luser- -droog wrote:

    > But isn't setjmp() only allowed within a condition (if, switch, etc.)?
    > It's *not* just a function call.


    For C89

    4.6.1.1 The setjmp macro

    Synopsis

    #include <setjmp.h>
    int setjmp(jmp_buf env);

    Description

    The setjmp macro saves its calling environment in its jmp_buf
    argument for later use by the longjmp function.

    Returns

    If the return is from a direct invocation, the setjmp macro returns
    the value zero. If the return is from a call to the longjmp function,
    the setjmp macro returns a nonzero value.

    "Environmental constraint"

    An invocation of the setjmp macro shall appear only in one of the
    following contexts:

    * the entire controlling expression of a selection or iteration statement;

    * one operand of a relational or equality operator with the other
    operand an integral constant expression, with the resulting expression
    being the entire controlling expression of a selection or iteration
    statement;

    * the operand of a unary ! operator with the resulting expression
    being the entire controlling expression of a selection or iteration
    statement; or

    * the entire expression of an expression statement (possibly cast to void).
     
    Noob, Dec 13, 2012
    #17
  18. Borneq

    Nobody Guest

    On Thu, 13 Dec 2012 03:13:05 +0100, Johann Klammer wrote:

    > Yes, I meant the latter... to the compiler the setjmp is just a function
    > call, nothing else.


    7.13p3:
    It is unspecified whether setjmp is a macro or an identifier
    declared with external linkage. If a macro definition is
    suppressed in order to access an actual function, or a program
    defines an external identifier with the name setjmp, the
    behavior is undefined.
     
    Nobody, Dec 13, 2012
    #18
  19. On 2012-12-12, Nobody <> wrote:
    > On Wed, 12 Dec 2012 15:19:57 +0100, Johann Klammer wrote:
    >
    >> Doesn't the whole machine state have to be
    >> saved/restored(registers/Fp/SSE/flags etc)?

    >
    > No.
    >
    >> What if the calling function was using some regs for local vars etc ?!...

    >
    > 7.13.2.1p3:
    >
    > All accessible objects have values as of the time longjmp was
    > called, except that the values of objects of automatic storage
    > duration that are local to the function containing the
    > invocation of the corresponding setjmp macro that do not have
    > volatile-qualified type and have been changed between the
    > setjmp invocation and longjmp call are indeterminate.


    Note the "have been changed" constraint. By my reading, that means that
    in code such as

    void f(void) {
    int i;
    ...;
    i = g(); /* [1] */
    if (setjmp(...)) { /* [2] */
    h(i); /* [3] */
    ...
    }
    ...
    }

    the value of "i", assuming the assignment [1] is the only statement
    modifying it, when passed to h on line [3], must be the value that was
    returned by g(), even after a later longjmp back to line [2]: the
    variable is local to the function and does not have volatile-qualified
    type, but it has not been changed between the setjmp and longjmp. To me
    this does seem to imply that the implementation needs to either restore
    also any caller-saved registers on longjmp, or handle setjmp(...) with
    rather more care than a regular function call, and not expect a
    caller-saved register to be able to hold g()'s result across the setjmp
    call.

    (Elsewhere in this thread there is also a different argument about
    having to restore any caller-saved registers in any case.)

    --
    Heikki Kallasjoki
     
    Heikki Kallasjoki, Dec 13, 2012
    #19
  20. Borneq

    Eric Sosman Guest

    On 12/13/2012 12:13 AM, glen herrmannsfeldt wrote:
    > Johann Klammer <1.net> wrote:
    >> BartC wrote:

    > [snip]
    >>> If you mean the function executing the 'setjmp': how many of those
    >>> things you mentioned are actually saved and restored during a
    >>> routine function call?

    >
    >>> Possibly the registers if in the middle of a calculation. But when
    >>> you come back after longjmp, you're no longer in the middle of that
    >>> calculation!

    >
    >> Yes, I meant the latter... to the compiler the setjmp is just a function
    >> call, nothing else.

    >
    > Is that really true? Seems to me that compilers can optimize stdlib
    > functions anyway they want, and that might include special case for
    > setjmp if needed.


    Yes, indeed. In the first place, compilers are just part
    of "the implementation," along with the library and other stuff,
    and the various parts of the implementation are allowed to have
    and use private knowledge about each other. That's why sqrt()
    might produce an in-line FSQRT instruction instead of a function
    call, for example.

    In the second place, setjmp() is specifically described as
    a macro, not as a function (although a setjmp() function may
    lurk somewhere in the background). The <setjmp.h> header might
    well use something like

    #define setjmp(x) __builtin_compiler_magic__(x)

    as its implementation, and this could open an easy route for
    all manner of special-casing.

    >> It has been some time since I read up on calling conventions,
    >> but I believe that the compiler is _not_ required to save
    >> and restore _all_ of the registers on entry/exit of every function
    >> call...? How does the compiler know you're not in 'the middle' of a
    >> calculation anymore. Are you in 'the middle' if you are using some local
    >> further down again after the return from setjmp?

    >
    > Register save convention is pretty much system (usually OS) dependent.
    > Seems to me that setjmp() has to follow the system convention.


    The system will surely define conventions to be used when
    calling upon the system's services, and when the system calls
    back into the program (signal handlers, for example). However,
    these conventions need not obtain within the program, when it's
    calling its own code. Things like gcc's -fomit-frame-pointer
    ask the compiler to take un-conventional shortcuts when it can
    see that they're safe.

    Even if the system's conventions are followed faithfully,
    it may be the case that they just don't cover all the cases C
    needs. For example, how should a struct-valued function return
    its value? The compiler may well need to establish conventions
    of its own for matters the system's conventions don't touch on.

    >[...]
    > Also, on some the caller saves registers that it needs saved, and
    > others the callee saves registers that it will change.


    And on yet others, there's a hardware assist in the form
    of a "register window turn" or similar mechanism.

    --
    Eric Sosman
    d
     
    Eric Sosman, Dec 13, 2012
    #20
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Thomas Baruchel

    How dirty is setjmp+fopen+longjmp ?

    Thomas Baruchel, Oct 2, 2003, in forum: C Programming
    Replies:
    2
    Views:
    458
    Eric Sosman
    Oct 2, 2003
  2. Mantorok Redgormor

    setjmp, longjmp

    Mantorok Redgormor, Nov 12, 2003, in forum: C Programming
    Replies:
    2
    Views:
    432
    Ian Woods
    Nov 12, 2003
  3. someone
    Replies:
    5
    Views:
    3,470
    SM Ryan
    May 1, 2004
  4. Michael B Allen

    Is setjmp/longjmp ok?

    Michael B Allen, May 1, 2004, in forum: C Programming
    Replies:
    11
    Views:
    2,260
    -wombat-
    May 4, 2004
  5. Ravi Uday

    setjmp/longjmp

    Ravi Uday, Aug 3, 2004, in forum: C Programming
    Replies:
    2
    Views:
    549
    Dave Vandervies
    Aug 6, 2004
Loading...

Share This Page