mirror of
https://github.com/tobast/libunwind-eh_elf.git
synced 2024-11-22 15:47:37 +01:00
Fix for failing test-setjmp
On Mon, Nov 14, 2011 at 5:02 PM, Paul Pluzhnikov <ppluzhnikov@google.com> wrote:
> P.S. test-setjmp is failing for me (before or after the patch).
> When I enable assertions (to confirm my new assertions are correct), I see:
>
> lt-test-setjmp: ../../src/dwarf/Gparser.c:754: apply_reg_state: \
> Assertion `rs->reg[17].where == DWARF_WHERE_EXPR' failed.
>
> which likely explains that failure.
The problem is actually two-fold:
First, the loops in {sig,}longjmp.c are "do { ... } while (unw_step() >= 0);"
But unw_step() returns 0 on reaching the end of the chain (_start),
and the loop should stop there.
The second problem is that with this commit:
c67da0b50e
glibc obfuscates value of SP in jmp_buf, so we might as well just give up.
Patch attached.
Thanks,
--
Paul Pluzhnikov
This commit is contained in:
parent
d84e5d5d24
commit
297d9cd07d
2 changed files with 34 additions and 2 deletions
|
@ -35,6 +35,20 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
|||
#include "jmpbuf.h"
|
||||
#include "setjmp_i.h"
|
||||
|
||||
#if defined(__GLIBC__) && __GLIBC_PREREQ(2, 4)
|
||||
|
||||
/* Starting with glibc-2.4, {sig,}setjmp in GLIBC obfuscates the
|
||||
register values in jmp_buf by XORing them with a "random"
|
||||
canary value.
|
||||
|
||||
This makes it impossible to implement longjmp, as we
|
||||
can never match wp[JB_SP], unless we decode the canary first.
|
||||
|
||||
Doing so is possible, but doesn't appear to be worth the trouble,
|
||||
so we simply defer to glibc longjmp here. */
|
||||
|
||||
#else
|
||||
|
||||
void
|
||||
_longjmp (jmp_buf env, int val)
|
||||
{
|
||||
|
@ -75,7 +89,7 @@ _longjmp (jmp_buf env, int val)
|
|||
|
||||
abort ();
|
||||
}
|
||||
while (unw_step (&c) >= 0);
|
||||
while (unw_step (&c) > 0);
|
||||
|
||||
abort ();
|
||||
}
|
||||
|
@ -90,4 +104,6 @@ longjmp (jmp_buf env, int val)
|
|||
_longjmp (env, val);
|
||||
}
|
||||
|
||||
#endif /* __GLIBC__ */
|
||||
|
||||
#endif
|
||||
|
|
|
@ -35,6 +35,20 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
|||
# define _NSIG (_SIG_MAXSIG - 1)
|
||||
#endif
|
||||
|
||||
#if defined(__GLIBC__) && __GLIBC_PREREQ(2, 4)
|
||||
|
||||
/* Starting with glibc-2.4, {sig,}setjmp in GLIBC obfuscates the
|
||||
register values in jmp_buf by XORing them with a "random"
|
||||
canary value.
|
||||
|
||||
This makes it impossible to implement longjmp, as we
|
||||
can never match wp[JB_SP], unless we decode the canary first.
|
||||
|
||||
Doing so is possible, but doesn't appear to be worth the trouble,
|
||||
so we simply defer to glibc siglongjmp here. */
|
||||
|
||||
#else
|
||||
|
||||
void
|
||||
siglongjmp (sigjmp_buf env, int val)
|
||||
{
|
||||
|
@ -96,7 +110,9 @@ siglongjmp (sigjmp_buf env, int val)
|
|||
|
||||
abort ();
|
||||
}
|
||||
while (unw_step (&c) >= 0);
|
||||
while (unw_step (&c) > 0);
|
||||
|
||||
abort ();
|
||||
}
|
||||
|
||||
#endif /* __GLIBC__ */
|
||||
|
|
Loading…
Reference in a new issue