summaryrefslogtreecommitdiff
path: root/mysys/my_context.c
diff options
context:
space:
mode:
authorunknown <knielsen@knielsen-hq.org>2012-10-31 12:47:25 +0100
committerunknown <knielsen@knielsen-hq.org>2012-10-31 12:47:25 +0100
commit27bcea09e5230757071d27b91402647a9e0b4713 (patch)
tree85e8d59b883a493810148e2245ee421b88c64385 /mysys/my_context.c
parentbc5232a65d395f60fdc46703f30d051a70470382 (diff)
downloadmariadb-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.c21
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);