diff options
author | unknown <knielsen@knielsen-hq.org> | 2012-10-31 12:47:25 +0100 |
---|---|---|
committer | unknown <knielsen@knielsen-hq.org> | 2012-10-31 12:47:25 +0100 |
commit | 27bcea09e5230757071d27b91402647a9e0b4713 (patch) | |
tree | 85e8d59b883a493810148e2245ee421b88c64385 /mysys/my_context.c | |
parent | bc5232a65d395f60fdc46703f30d051a70470382 (diff) | |
download | mariadb-git-27bcea09e5230757071d27b91402647a9e0b4713.tar.gz |
Fix crashes on 32-bit async client lib when -fomit-frame-pointer
- Ensure asm parameters are in registers, so we do not de-reference from
bogus stack pointer.
- Make return address undefined in DWARF unwind info in my_context_spawn,
so DWARF-based unwinders will know this is the end of the call stack
(same as the amd64 fix for the similar issue).
Diffstat (limited to 'mysys/my_context.c')
-rw-r--r-- | mysys/my_context.c | 21 |
1 files changed, 16 insertions, 5 deletions
diff --git a/mysys/my_context.c b/mysys/my_context.c index d2374391a39..9d56b13ecb5 100644 --- a/mysys/my_context.c +++ b/mysys/my_context.c @@ -437,6 +437,8 @@ my_context_destroy(struct my_context *c) int my_context_spawn(struct my_context *c, void (*f)(void *), void *d) { + void (*tmp_f)(void *)= f; + void *tmp_d= d; int ret; DBUG_SWAP_CODE_STATE(&c->dbug_state); @@ -454,6 +456,15 @@ my_context_spawn(struct my_context *c, void (*f)(void *), void *d) ( "movl %%esp, (%[save])\n\t" "movl %[stack], %%esp\n\t" +#if __GNUC__ >= 4 && __GNUC_MINOR__ >= 4 + /* + This emits a DWARF DW_CFA_undefined directive to make the return address + undefined. This indicates that this is the top of the stack frame, and + helps tools that use DWARF stack unwinding to obtain stack traces. + (I use numeric constant to avoid a dependency on libdwarf includes). + */ + ".cfi_escape 0x07, 8\n\t" +#endif /* Push the parameter on the stack. */ "pushl %[d]\n\t" "movl %%ebp, 4(%[save])\n\t" @@ -483,13 +494,13 @@ my_context_spawn(struct my_context *c, void (*f)(void *), void *d) "3:\n\t" "movl $1, %[ret]\n" "4:\n" - : [ret] "=a" (ret) + : [ret] "=a" (ret), + [f] "+c" (tmp_f), + [d] "+d" (tmp_d) : [stack] "a" (c->stack_top), /* Need this in callee-save register to preserve across function call. */ - [save] "D" (&c->save[0]), - [f] "m" (f), - [d] "m" (d) - : "ecx", "edx", "memory", "cc" + [save] "D" (&c->save[0]) + : "memory", "cc" ); DBUG_SWAP_CODE_STATE(&c->dbug_state); |