-
-
Notifications
You must be signed in to change notification settings - Fork 5.5k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Fix misunwind during Profile test under rr (#39553)
Libunwind improperly aliases RSP and CFA, which are separate concepts. Fix that. (cherry picked from commit bbf7f97)
- Loading branch information
1 parent
28061f3
commit 5dd5da4
Showing
4 changed files
with
207 additions
and
25 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,26 +1,26 @@ | ||
LibOSXUnwind.v0.0.6+1.x86_64-apple-darwin.tar.gz/md5/fd98df2005d13aa16341c5aecba1af70 | ||
LibOSXUnwind.v0.0.6+1.x86_64-apple-darwin.tar.gz/sha512/2d2263c3e5f095ad9eba7fea7cb882a19fece8a10486489d0a15b8e81ea0f8626804c4822b8c92a26a608d568c0ff1a4e976ea6d746be47ac1a70891455162a6 | ||
LibUnwind.v1.3.2+0.aarch64-linux-gnu.tar.gz/md5/36281b8ba75cab684c843585dc949b72 | ||
LibUnwind.v1.3.2+0.aarch64-linux-gnu.tar.gz/sha512/7f5224fe3bfd9dd579fa2efb40b65ca785da3f7ddee1bd41e072f7f5be1ce8fa24c2eab71a1233406ce532ba9f900d1f0e288f84631684b3cbc8a0f3a8347e41 | ||
LibUnwind.v1.3.2+0.aarch64-linux-musl.tar.gz/md5/ba21435b80f4f50fbb13cf4653e3fac3 | ||
LibUnwind.v1.3.2+0.aarch64-linux-musl.tar.gz/sha512/25cfe1f1cbfe2b9ee748348e2b0df0fba3607dedbcf88f864e88a15544bfe0781de502157353915b62387abdb467c40e51b08e847f0d2cc096a3d2d13f061559 | ||
LibUnwind.v1.3.2+0.armv6l-linux-gnueabihf.tar.gz/md5/81fc18e166b8de9de171ca202ee43816 | ||
LibUnwind.v1.3.2+0.armv6l-linux-gnueabihf.tar.gz/sha512/e41f0224d79dc5725b327ad7f24eb09aef0fc687842d43eecc8ac60c4dcdc1d2877d45c88015d0e32014f8bef38712f540c27093d135dd0bc7e7eafb6bd64b18 | ||
LibUnwind.v1.3.2+0.armv6l-linux-musleabihf.tar.gz/md5/69da77d1e7124dee0c60d4fc15cf0040 | ||
LibUnwind.v1.3.2+0.armv6l-linux-musleabihf.tar.gz/sha512/a1c6d70971a7375c26ce761039f06a940db140b06028534557f3b608363af0da9d7ef570d5f3b388f84d9649d378293bb6b59d44cf34ebf24f0a260a6824f142 | ||
LibUnwind.v1.3.2+0.armv7l-linux-gnueabihf.tar.gz/md5/b7a6b251f30cd6d1fc890a8be4a19476 | ||
LibUnwind.v1.3.2+0.armv7l-linux-gnueabihf.tar.gz/sha512/d143588edb96b31de4d1347ddc867e5982ccee8a39a35f705114f6fa12aca054f14a05a24ca0850be26c62a92a4c52837e898765b3fa8fa6e5259e45eebbe281 | ||
LibUnwind.v1.3.2+0.armv7l-linux-musleabihf.tar.gz/md5/bdfa9757e7631387cb64f3897e1847fc | ||
LibUnwind.v1.3.2+0.armv7l-linux-musleabihf.tar.gz/sha512/54f8529bb836cddff61e0112294ae3165eb6498b0c881b59047a40e180785f63c01e4ad82bcffb045b783e015c255c7b0e2f8ec43411ff647f860ef25551f540 | ||
LibUnwind.v1.3.2+0.i686-linux-gnu.tar.gz/md5/17b1c29c3387dc3b685e75ce402caad6 | ||
LibUnwind.v1.3.2+0.i686-linux-gnu.tar.gz/sha512/e8551b4771acf7eb31fc5db3423905b17c545aa0895b5e5369c56186841631f188186e585f0384cfca62269e1b2fffe9d9b24274d51e1ccad9bc89c3dbf6072b | ||
LibUnwind.v1.3.2+0.i686-linux-musl.tar.gz/md5/df7e34217c1dc931c88e573179218cf6 | ||
LibUnwind.v1.3.2+0.i686-linux-musl.tar.gz/sha512/995318e65520eae55647b2d1065f5ac5bb15cdf7b4980000b17338c59e1657e408ba711c622b450df96712a5c1c75c85c03d7952a1fd7f0b65712fa9ac6ffbab | ||
LibUnwind.v1.3.2+0.powerpc64le-linux-gnu.tar.gz/md5/775e9c77ff9de48d40b2a2f18e5f081e | ||
LibUnwind.v1.3.2+0.powerpc64le-linux-gnu.tar.gz/sha512/3f4d12ba171227c11ad0e774e003742c1cd69d7e0e8ae571accea561ff930ae6aec119fc8b539caf52960886cde3978912e03d663aa7fb6416978e304767dde8 | ||
LibUnwind.v1.3.2+0.x86_64-linux-gnu.tar.gz/md5/d63ca2bc34d4bc87498d28b47e530f54 | ||
LibUnwind.v1.3.2+0.x86_64-linux-gnu.tar.gz/sha512/2e95d1648414fa9bccf6012a9f6690cf3c209dbb138bf59da76be538793c5caca319eed3b063f18725212844e21bd67157da2aec49ec9424e38664c23dde9f45 | ||
LibUnwind.v1.3.2+0.x86_64-linux-musl.tar.gz/md5/56a9c951e75e38bf5787c928862924cf | ||
LibUnwind.v1.3.2+0.x86_64-linux-musl.tar.gz/sha512/8ea0c4d0e412a3792c6d33fe6dab6ae9f4c4103341842e42a9ae7efcb31c29d977970caa383373c6694d6cd8736ce75c727fa2af8f59bc3eff8d8f93ac0b9c89 | ||
LibUnwind.v1.3.2+0.x86_64-unknown-freebsd.tar.gz/md5/10507e55604be0137c4531b5e35fbafc | ||
LibUnwind.v1.3.2+0.x86_64-unknown-freebsd.tar.gz/sha512/a795c02b48a3b44d6b7df0b07ed31f44c3c1e189b0732a5a41ce6f2eac952da4cc376eefab17c283a20a84aae4c3dc6618e58ca86003390b4ab396d085fa83c4 | ||
LibUnwind.v1.3.2+3.aarch64-linux-gnu.tar.gz/md5/fba1f405a3a7c8bc4f68c17d771100b0 | ||
LibUnwind.v1.3.2+3.aarch64-linux-gnu.tar.gz/sha512/a37d3f9da9a133bb270cc1046c7018579731897fed0ef6ab1fbeb0dde38e7be294a4e2abf41096c7edde617e266f1acc95777b34e22b6a8ced0e27b2228b0ec5 | ||
LibUnwind.v1.3.2+3.aarch64-linux-musl.tar.gz/md5/587de98245251124c0d29b0b478374ec | ||
LibUnwind.v1.3.2+3.aarch64-linux-musl.tar.gz/sha512/9f10eee8e4f5117dfc4689378c93ba16e205aaa89eec5681e0b1e34e7c2d334717b327cae8d5024db6a1f6a2633454cb77b577112a0a03a3282e566705c1a81e | ||
LibUnwind.v1.3.2+3.armv6l-linux-gnueabihf.tar.gz/md5/953bfa931cb8e44d39ae22d7ccab1f22 | ||
LibUnwind.v1.3.2+3.armv6l-linux-gnueabihf.tar.gz/sha512/54ee57c35895cbaed2160d451ca33ac9e8adf157b7f825853f7e92f8304f799f2671f5361dae7d2e7d111a3ab1f749cddb96a2c04b7b8fc7844b1e021dbc443f | ||
LibUnwind.v1.3.2+3.armv6l-linux-musleabihf.tar.gz/md5/5d16fd194ec5a7e46e1e1679072cec0f | ||
LibUnwind.v1.3.2+3.armv6l-linux-musleabihf.tar.gz/sha512/1ae68a77eadaf73de9de266bb3e2f61457faae6b2f971988363d2d1bebf855bdbc55ad848266335a9b3c040308e0bd3e3b66d5b66fe8807e0fb774c22bac928d | ||
LibUnwind.v1.3.2+3.armv7l-linux-gnueabihf.tar.gz/md5/569da138256de02784ba81b01e08a3db | ||
LibUnwind.v1.3.2+3.armv7l-linux-gnueabihf.tar.gz/sha512/264636b57ca49feb005752636671fe1c24264b15d1caca0c0808e89966a7683e7821a56e41b89cde9e32b688cf94647ae61de74f0428b7b1f92be2bed6674114 | ||
LibUnwind.v1.3.2+3.armv7l-linux-musleabihf.tar.gz/md5/c9d2f634a742d71e471dd7ff691bf39d | ||
LibUnwind.v1.3.2+3.armv7l-linux-musleabihf.tar.gz/sha512/01c2085d49390ace5c128507a86d23b99d746cce080cc7b6415e1c75e63082d01b047b2cf98f3f76768fb49423c5524f53d253858d82864f09e8182a86be57ad | ||
LibUnwind.v1.3.2+3.i686-linux-gnu.tar.gz/md5/92e075574e65c735f6202cc49ec51593 | ||
LibUnwind.v1.3.2+3.i686-linux-gnu.tar.gz/sha512/03f9a71b1b1b0752a835201248cdb2d17f076a82b0928e20f45fc2b8db0914128028c0d589ff94a97847265c216420240b2369af83c4a343d3ca37c58fdcf35a | ||
LibUnwind.v1.3.2+3.i686-linux-musl.tar.gz/md5/fa506359a72ffdf2c3713b5724ad4413 | ||
LibUnwind.v1.3.2+3.i686-linux-musl.tar.gz/sha512/0558e871e838e6ce265c73fd7335bd0a486722ce9a710957b2e67731c494c5781a3a37176ba758f74fee37d48ee43acf02aac5092e24230523dd537610b58720 | ||
LibUnwind.v1.3.2+3.powerpc64le-linux-gnu.tar.gz/md5/3f76849a52550e169d6f47ef95ca3d75 | ||
LibUnwind.v1.3.2+3.powerpc64le-linux-gnu.tar.gz/sha512/2f3a119ccf1fffa8460e2350b66bf2303d11d636e649e144750e362d2e08f61d076adda71b5441b4337eaee6fb1e95049aac87de89be1415ca80f1b69c77f310 | ||
LibUnwind.v1.3.2+3.x86_64-linux-gnu.tar.gz/md5/624779c4bc930ae2ba5f6a5d25c73aeb | ||
LibUnwind.v1.3.2+3.x86_64-linux-gnu.tar.gz/sha512/2eb467537e5f2acee7d5b2a5939c712ca96195584c37606d1ff1bcc0683514decefcae042f566633905472c177115c1467c1503bf331d8d7293b3026628bc138 | ||
LibUnwind.v1.3.2+3.x86_64-linux-musl.tar.gz/md5/7ddcbe93c8bdb1edde0ffab23db3ced7 | ||
LibUnwind.v1.3.2+3.x86_64-linux-musl.tar.gz/sha512/06901d074c15c34002957122897b6b9c449f9c64745363f6fe2886c862197cc6848ca17c3d777eac315fd1d8d90fe236a223167b0aa9fd3b625fd80e3db97655 | ||
LibUnwind.v1.3.2+3.x86_64-unknown-freebsd.tar.gz/md5/ca388d44a8ca365b66999e4b4d1853a2 | ||
LibUnwind.v1.3.2+3.x86_64-unknown-freebsd.tar.gz/sha512/dfbe0a6b5835b51ebea181bb996ffc8fcd8b08acf71243e171c59edb655fd65b6ba59291c10af923f75b7cbb2f52b46adf65ebdca3eee172d279ae357a35205c |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,177 @@ | ||
commit 66f68ab50d35bb17a7ae3ac47f17e1ba5913760c | ||
Author: Keno Fischer <[email protected]> | ||
Date: Sat Feb 6 18:13:16 2021 -0500 | ||
|
||
x86_64: Stop aliasing RSP and CFA | ||
|
||
RSP and CFA are different concepts. RSP refers to the physical | ||
register, CFA is a virtual register that serves as the base | ||
address for various other saved registers. It is true that | ||
in many frames these are set to alias, however this is not | ||
a requirement. For example, a function that performs a stack | ||
switch would likely change the rsp in the middle of the function, | ||
but would keep the CFA at the original RSP such that saved registers | ||
may be appropriately recovered. | ||
|
||
We are seeing incorrect unwinds in the Julia runtime when running | ||
julia under rr. This is because injects code (with correct CFI) | ||
that performs just such a stack switch [1]. GDB manages to unwind | ||
this correctly, but libunwind incorrectly sets the rsp to the CFA | ||
address, causing a misunwind. | ||
|
||
Tested on x86_64, patches for other architectures are ported, but | ||
not tested. | ||
|
||
[1] https://github.com/rr-debugger/rr/blob/469c22059a4a1798d33a8a224457faf22b2c178c/src/preload/syscall_hook.S#L454 | ||
|
||
diff --git a/include/dwarf.h b/include/dwarf.h | ||
index fab93c61..b845e2eb 100644 | ||
--- a/include/dwarf.h | ||
+++ b/include/dwarf.h | ||
@@ -227,6 +227,7 @@ typedef enum | ||
DWARF_WHERE_REG, /* register saved in another register */ | ||
DWARF_WHERE_EXPR, /* register saved */ | ||
DWARF_WHERE_VAL_EXPR, /* register has computed value */ | ||
+ DWARF_WHERE_CFA, /* register is set to the computed cfa value */ | ||
} | ||
dwarf_where_t; | ||
|
||
@@ -309,7 +310,7 @@ typedef struct dwarf_cursor | ||
void *as_arg; /* argument to address-space callbacks */ | ||
unw_addr_space_t as; /* reference to per-address-space info */ | ||
|
||
- unw_word_t cfa; /* canonical frame address; aka frame-/stack-pointer */ | ||
+ unw_word_t cfa; /* canonical frame address; aka frame-pointer */ | ||
unw_word_t ip; /* instruction pointer */ | ||
unw_word_t args_size; /* size of arguments */ | ||
unw_word_t eh_args[UNW_TDEP_NUM_EH_REGS]; | ||
diff --git a/src/dwarf/Gparser.c b/src/dwarf/Gparser.c | ||
index 7d255aee..986c4a89 100644 | ||
--- a/src/dwarf/Gparser.c | ||
+++ b/src/dwarf/Gparser.c | ||
@@ -500,6 +500,8 @@ setup_fde (struct dwarf_cursor *c, dwarf_state_record_t *sr) | ||
memset (sr, 0, sizeof (*sr)); | ||
for (i = 0; i < DWARF_NUM_PRESERVED_REGS + 2; ++i) | ||
set_reg (sr, i, DWARF_WHERE_SAME, 0); | ||
+ // SP defaults to CFA (but is overridable) | ||
+ set_reg (sr, UNW_TDEP_SP, DWARF_WHERE_CFA, 0); | ||
|
||
struct dwarf_cie_info *dci = c->pi.unwind_info; | ||
sr->rs_current.ret_addr_column = dci->ret_addr_column; | ||
@@ -826,6 +828,10 @@ apply_reg_state (struct dwarf_cursor *c, struct dwarf_reg_state *rs) | ||
case DWARF_WHERE_SAME: | ||
break; | ||
|
||
+ case DWARF_WHERE_CFA: | ||
+ new_loc[i] = DWARF_VAL_LOC (c, cfa); | ||
+ break; | ||
+ | ||
case DWARF_WHERE_CFAREL: | ||
new_loc[i] = DWARF_MEM_LOC (c, cfa + rs->reg.val[i]); | ||
break; | ||
diff --git a/src/x86/Gos-freebsd.c b/src/x86/Gos-freebsd.c | ||
index 7dd01404..1b251d02 100644 | ||
--- a/src/x86/Gos-freebsd.c | ||
+++ b/src/x86/Gos-freebsd.c | ||
@@ -138,6 +138,7 @@ x86_handle_signal_frame (unw_cursor_t *cursor) | ||
c->dwarf.loc[ST0] = DWARF_NULL_LOC; | ||
} else if (c->sigcontext_format == X86_SCF_FREEBSD_SYSCALL) { | ||
c->dwarf.loc[EIP] = DWARF_LOC (c->dwarf.cfa, 0); | ||
+ c->dwarf.loc[ESP] = DWARF_VAL_LOC (c, c->dwarf.cfa + 4); | ||
c->dwarf.loc[EAX] = DWARF_NULL_LOC; | ||
c->dwarf.cfa += 4; | ||
c->dwarf.use_prev_instr = 1; | ||
diff --git a/src/x86/Gregs.c b/src/x86/Gregs.c | ||
index 4a959261..9446d6c6 100644 | ||
--- a/src/x86/Gregs.c | ||
+++ b/src/x86/Gregs.c | ||
@@ -53,7 +53,6 @@ tdep_access_reg (struct cursor *c, unw_regnum_t reg, unw_word_t *valp, | ||
break; | ||
|
||
case UNW_X86_CFA: | ||
- case UNW_X86_ESP: | ||
if (write) | ||
return -UNW_EREADONLYREG; | ||
*valp = c->dwarf.cfa; | ||
@@ -81,6 +80,7 @@ tdep_access_reg (struct cursor *c, unw_regnum_t reg, unw_word_t *valp, | ||
case UNW_X86_ECX: loc = c->dwarf.loc[ECX]; break; | ||
case UNW_X86_EBX: loc = c->dwarf.loc[EBX]; break; | ||
|
||
+ case UNW_X86_ESP: loc = c->dwarf.loc[ESP]; break; | ||
case UNW_X86_EBP: loc = c->dwarf.loc[EBP]; break; | ||
case UNW_X86_ESI: loc = c->dwarf.loc[ESI]; break; | ||
case UNW_X86_EDI: loc = c->dwarf.loc[EDI]; break; | ||
diff --git a/src/x86/Gstep.c b/src/x86/Gstep.c | ||
index 129b739a..061dcbaa 100644 | ||
--- a/src/x86/Gstep.c | ||
+++ b/src/x86/Gstep.c | ||
@@ -47,7 +47,7 @@ unw_step (unw_cursor_t *cursor) | ||
{ | ||
/* DWARF failed, let's see if we can follow the frame-chain | ||
or skip over the signal trampoline. */ | ||
- struct dwarf_loc ebp_loc, eip_loc; | ||
+ struct dwarf_loc ebp_loc, eip_loc, esp_loc; | ||
|
||
/* We could get here because of missing/bad unwind information. | ||
Validate all addresses before dereferencing. */ | ||
@@ -77,6 +77,7 @@ unw_step (unw_cursor_t *cursor) | ||
c->dwarf.cfa); | ||
|
||
ebp_loc = DWARF_LOC (c->dwarf.cfa, 0); | ||
+ esp_loc = DWARF_VAL_LOC (c, c->dwarf.cfa + 8); | ||
eip_loc = DWARF_LOC (c->dwarf.cfa + 4, 0); | ||
c->dwarf.cfa += 8; | ||
|
||
@@ -87,6 +88,7 @@ unw_step (unw_cursor_t *cursor) | ||
c->dwarf.loc[i] = DWARF_NULL_LOC; | ||
|
||
c->dwarf.loc[EBP] = ebp_loc; | ||
+ c->dwarf.loc[ESP] = esp_loc; | ||
c->dwarf.loc[EIP] = eip_loc; | ||
c->dwarf.use_prev_instr = 1; | ||
} | ||
diff --git a/src/x86_64/Gos-freebsd.c b/src/x86_64/Gos-freebsd.c | ||
index 883025c8..8bb101ea 100644 | ||
--- a/src/x86_64/Gos-freebsd.c | ||
+++ b/src/x86_64/Gos-freebsd.c | ||
@@ -133,6 +133,7 @@ x86_64_handle_signal_frame (unw_cursor_t *cursor) | ||
c->dwarf.loc[RCX] = c->dwarf.loc[R10]; | ||
/* rsp_loc = DWARF_LOC(c->dwarf.cfa - 8, 0); */ | ||
/* rbp_loc = c->dwarf.loc[RBP]; */ | ||
+ c->dwarf.loc[RSP] = DWARF_VAL_LOC (c, c->dwarf.cfa + 8); | ||
c->dwarf.loc[RIP] = DWARF_LOC (c->dwarf.cfa, 0); | ||
ret = dwarf_get (&c->dwarf, c->dwarf.loc[RIP], &c->dwarf.ip); | ||
Debug (1, "Frame Chain [RIP=0x%Lx] = 0x%Lx\n", | ||
diff --git a/src/x86_64/Gregs.c b/src/x86_64/Gregs.c | ||
index baf8a24f..dff5bcbe 100644 | ||
--- a/src/x86_64/Gregs.c | ||
+++ b/src/x86_64/Gregs.c | ||
@@ -79,7 +79,6 @@ tdep_access_reg (struct cursor *c, unw_regnum_t reg, unw_word_t *valp, | ||
break; | ||
|
||
case UNW_X86_64_CFA: | ||
- case UNW_X86_64_RSP: | ||
if (write) | ||
return -UNW_EREADONLYREG; | ||
*valp = c->dwarf.cfa; | ||
@@ -107,6 +106,7 @@ tdep_access_reg (struct cursor *c, unw_regnum_t reg, unw_word_t *valp, | ||
case UNW_X86_64_RCX: loc = c->dwarf.loc[RCX]; break; | ||
case UNW_X86_64_RBX: loc = c->dwarf.loc[RBX]; break; | ||
|
||
+ case UNW_X86_64_RSP: loc = c->dwarf.loc[RSP]; break; | ||
case UNW_X86_64_RBP: loc = c->dwarf.loc[RBP]; break; | ||
case UNW_X86_64_RSI: loc = c->dwarf.loc[RSI]; break; | ||
case UNW_X86_64_RDI: loc = c->dwarf.loc[RDI]; break; | ||
diff --git a/src/x86_64/Gstep.c b/src/x86_64/Gstep.c | ||
index 10498170..5425e3db 100644 | ||
--- a/src/x86_64/Gstep.c | ||
+++ b/src/x86_64/Gstep.c | ||
@@ -160,7 +160,7 @@ unw_step (unw_cursor_t *cursor) | ||
{ | ||
unw_word_t rbp1 = 0; | ||
rbp_loc = DWARF_LOC(rbp, 0); | ||
- rsp_loc = DWARF_NULL_LOC; | ||
+ rsp_loc = DWARF_VAL_LOC(c, rbp + 16); | ||
rip_loc = DWARF_LOC (rbp + 8, 0); | ||
ret = dwarf_get (&c->dwarf, rbp_loc, &rbp1); | ||
Debug (1, "[RBP=0x%lx] = 0x%lx (cfa = 0x%lx) -> 0x%lx\n", |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters