summaryrefslogtreecommitdiff
path: root/vm_dump.c
diff options
context:
space:
mode:
authornagachika <nagachika@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2016-09-26 14:13:28 +0000
committernagachika <nagachika@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2016-09-26 14:13:28 +0000
commit6ccadbafcd86fd236beb9bc3390d13ccf8fb9be0 (patch)
tree75a91c2440512e3bc5a23055c2478f13a70b8fb6 /vm_dump.c
parentded336e9fbfdf4ea52a33b483e4e72ce59d36899 (diff)
merge revision(s) 56030,56035: [Backport #12711]
* vm_dump.c (backtrace): use rip in the saved context for the case the SIGSEGV is received when the process is in userland. Note that ip in the stack should be used if the signal is received when it is in kernel (when it is calling syscall) [Bug #12711] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_2_3@56257 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'vm_dump.c')
-rw-r--r--vm_dump.c10
1 files changed, 7 insertions, 3 deletions
diff --git a/vm_dump.c b/vm_dump.c
index df0d2413c9..01d15062fc 100644
--- a/vm_dump.c
+++ b/vm_dump.c
@@ -482,10 +482,14 @@ darwin_sigtramp:
unw_set_reg(&cursor, UNW_X86_64_R13, uctx->uc_mcontext->__ss.__r13);
unw_set_reg(&cursor, UNW_X86_64_R14, uctx->uc_mcontext->__ss.__r14);
unw_set_reg(&cursor, UNW_X86_64_R15, uctx->uc_mcontext->__ss.__r15);
- ip = *(unw_word_t*)uctx->uc_mcontext->__ss.__rsp;
- unw_set_reg(&cursor, UNW_REG_IP, ip);
- trace[n++] = (void *)uctx->uc_mcontext->__ss.__rip;
+ ip = uctx->uc_mcontext->__ss.__rip;
+ if (((char*)ip)[-2] == 0x0f && ((char*)ip)[-1] == 5) {
+ /* signal received in syscall */
+ trace[n++] = (void *)ip;
+ ip = *(unw_word_t*)uctx->uc_mcontext->__ss.__rsp;
+ }
trace[n++] = (void *)ip;
+ unw_set_reg(&cursor, UNW_REG_IP, ip);
}
while (unw_step(&cursor) > 0) {
unw_get_reg(&cursor, UNW_REG_IP, &ip);