From: "Juraj Oršulić" <juraj.orsulic@fer.hr>
To: gcc-help@gcc.gnu.org
Subject: Incorrect unwind when throwing exceptions - possible cause?
Date: Thu, 3 Feb 2022 01:43:48 +0100 [thread overview]
Message-ID: <CAEPqvowsVMLJ4uLBUfX-KH_rKQHP_ERjxyFy2e39Je2r9tiBtg@mail.gmail.com> (raw)
I have a hair-tearing problem with x86_64 gcc 9.3.0 (Ubuntu 20.04),
-O2 and the following "minimal" example
(the real minimal example also links in a bunch of 3rd party libraries
and is a part of a big project, so I can't really provide a minimal example,
but I slimmed it down to basically this):
class Application() {
public:
Application(int argc, char **argv) {}
int process() {
if (argc > 1) { throw std::runtime_error("Exception"); }
// do some processing here
return 0;
}
int main(int argc, char **argv) {
Application app(argc, argv);
int result = 0;
try {
result = app.process();
} catch (const std::exception &e) {
result = 1;
puts(e.what());
}
return result;
}
I get crashes if I throw and there's some more core after the if() in process().
This is an excerpt of how .eh_frame looks like when it works (90% code
in process() commented out):
00014c84 000000000000002c 00000000 CIE
Version: 1
Augmentation: "zPLR"
Code alignment factor: 1
Data alignment factor: -8
Return address column: 16
Augmentation data: 9b 49 4f 3c 00 1b 1b
DW_CFA_def_cfa: r7 (rsp) ofs 8
DW_CFA_offset: r16 (rip) at cfa-8
DW_CFA_def_cfa: r6 (rbp) ofs 16
DW_CFA_offset: r3 (rbx) at cfa-56
DW_CFA_offset: r6 (rbp) at cfa-16
DW_CFA_offset: r12 (r12) at cfa-48
DW_CFA_offset: r13 (r13) at cfa-40
DW_CFA_offset: r14 (r14) at cfa-32
DW_CFA_offset: r15 (r15) at cfa-24
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
00014cb4 0000000000000014 00000034 FDE cie=00014c84
pc=000000000025081e..00000000002508d6
Augmentation data: d4 7e 20 00
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
However, if I put just a bit more stuff inside process() after that
throwing if(), gcc changes the process function prologue a bit
and the unwind table looks like this:
0001ce38 0000000000000034 00013428 FDE cie=00009a14
pc=0000000000252534..0000000000256376
Augmentation data: ab 34 20 00
DW_CFA_def_cfa_expression (DW_OP_breg6 (rbp): -40; DW_OP_deref)
DW_CFA_expression: r3 (rbx) (DW_OP_breg6 (rbp): -48)
DW_CFA_expression: r6 (rbp) (DW_OP_breg6 (rbp): 0)
DW_CFA_expression: r12 (r12) (DW_OP_breg6 (rbp): -32)
DW_CFA_expression: r13 (r13) (DW_OP_breg6 (rbp): -24)
DW_CFA_expression: r14 (r14) (DW_OP_breg6 (rbp): -16)
DW_CFA_expression: r15 (r15) (DW_OP_breg6 (rbp): -8)
So it basically references everything against rbp instead of against
the cfa, great. Here are the libunwind debug prints.
Notice how after processing the expression OP_breg(r6,0x0), thus
calculating the new value for r6 (rbp) by dereferencing itself with
offset zero, the change is reflected in the calculations for subsequent
registers r12-r15 which are wrong.
`apply_reg_state` in libunwind writes the new address for the value of
r6. However, the offsets for r12-r15 are supposed to be calculated
against the inner stack frame's value of rbp (0x7fffffffca70), not against
the new one (0x7fffffffcab0)!
>_ULx86_64_reuse_frame: reuse frame ip=0x5555557a9d46
cfa=0x7fffffff6cc0 format=0 addr=0x0 offset=+0
>_ULx86_64_dwarf_eval_expr: len=3, pushing cfa=0x7fffffff6cc0
>_ULx86_64_dwarf_eval_expr: OP_breg(r6,0xffffffffffffffd8)
>access_mem: mem[00007fffffff6c90] -> 7fffffffca70
>_ULx86_64_dwarf_eval_expr: OP_deref
>_ULx86_64_dwarf_eval_expr: final value = 0x7fffffffca90
>_ULx86_64_dwarf_eval_expr: len=2, pushing cfa=0x7fffffff6cc0
>_ULx86_64_dwarf_eval_expr: OP_breg(r6,0xffffffffffffffd0)
>access_mem: mem[00007fffffff6c90] -> 7fffffffca70
>_ULx86_64_dwarf_eval_expr: final value = 0x7fffffffca40
>_ULx86_64_dwarf_eval_expr: len=2, pushing cfa=0x7fffffff6cc0
>_ULx86_64_dwarf_eval_expr: OP_breg(r6,0x0)
>access_mem: mem[00007fffffff6c90] -> 7fffffffca70
>_ULx86_64_dwarf_eval_expr: final value = 0x7fffffffca70
>_ULx86_64_dwarf_eval_expr: len=2, pushing cfa=0x7fffffff6cc0
>_ULx86_64_dwarf_eval_expr: OP_breg(r6,0xffffffffffffffe0)
>access_mem: mem[00007fffffffca70] -> 7fffffffcab0
>_ULx86_64_dwarf_eval_expr: final value = 0x7fffffffca90
>_ULx86_64_dwarf_eval_expr: len=2, pushing cfa=0x7fffffff6cc0
>_ULx86_64_dwarf_eval_expr: OP_breg(r6,0xffffffffffffffe8)
>access_mem: mem[00007fffffffca70] -> 7fffffffcab0
>_ULx86_64_dwarf_eval_expr: final value = 0x7fffffffca98
>_ULx86_64_dwarf_eval_expr: len=2, pushing cfa=0x7fffffff6cc0
>_ULx86_64_dwarf_eval_expr: OP_breg(r6,0xfffffffffffffff0)
>access_mem: mem[00007fffffffca70] -> 7fffffffcab0
>_ULx86_64_dwarf_eval_expr: final value = 0x7fffffffcaa0
>_ULx86_64_dwarf_eval_expr: len=2, pushing cfa=0x7fffffff6cc0
>_ULx86_64_dwarf_eval_expr: OP_breg(r6,0xfffffffffffffff8)
>access_mem: mem[00007fffffffca70] -> 7fffffffcab0
>_ULx86_64_dwarf_eval_expr: final value = 0x7fffffffcaa8
>access_mem: mem[00007fffffffca88] -> 5555558b67a9
>_ULx86_64_dwarf_step: returning 1
>_ULx86_64_step: returning 1
>_ULx86_64_dwarf_find_proc_info: looking for IP=0x5555558b67a8
>_ULx86_64_dwarf_callback: checking , base=0x555555554000)
>_ULx86_64_dwarf_callback: found table `':
segbase=0x555557215230, len=57926, gp=0x5555576567e8,
table_data=0x55555721523c
>lookup: e->start_ip_offset = fffffffffebc5730
...........
>lookup: e->start_ip_offset = fffffffffe6a1410
>_ULx86_64_dwarf_search_unwind_table:
ip=0x5555558b67a8, start_ip=0xfffffffffe6a1410
>_ULx86_64_dwarf_search_unwind_table: e->fde_offset = 8e0b0, segbase
= 555557215230, debug_frame_base = 0, fde_addr = 5555572a32e0
>_ULx86_64_dwarf_extract_proc_info_from_fde: FDE @ 0x5555572a32e0
>_ULx86_64_dwarf_extract_proc_info_from_fde: looking
for CIE at address 55555728fe84
>parse_cie: CIE parsed OK, augmentation = "zPLR",
handler=0x7fffeeaf3a80
>_ULx86_64_dwarf_extract_proc_info_from_fde: FDE covers
IP 0x5555558b6640-0x5555558b6867, LSDA=0x5555574a67ec
>_ULx86_64_fetch_frame: fetch frame ip=0x5555558b67a9
cfa=0x7fffffffca90 format=0
>access_mem: mem[00007fffffffca88] <- 5555558b67e9
>_ULx86_64_resume: (cursor=0x7fffffff6870)
>establish_machine_state: copying out cursor state
>establish_machine_state: copying RBP 6
>access_mem: mem[00007fffffffca70] -> 7fffffffcab0
>access_reg: RBP <- 0x00007fffffffcab0
>establish_machine_state: copying RSP 7
>access_reg: RSP <- 0x00007fffffffca90
>establish_machine_state: copying R8 8
>access_mem: mem[00007fffffff64c8] -> 555557ced700
... All of these are wrong and cause a crash after landing in the
exception handler in main():
>access_reg: R12 <- 0x73746e6f662f6269
>establish_machine_state: copying R13 13
>access_mem: mem[00007fffffffca98] -> 257c32600
>access_reg: R13 <- 0x0000000257c32600
>establish_machine_state: copying R14 14
>access_mem: mem[00007fffffffcaa0] -> 555557c325d0
>access_reg: R14 <- 0x0000555557c325d0
>establish_machine_state: copying R15 15
>access_mem: mem[00007fffffffcaa8] -> 17ebc2371241f
>access_reg: R15 <- 0x00017ebc2371241f
>establish_machine_state: copying RIP 16
>access_mem: mem[00007fffffffca88] -> 5555558b67e9
>access_reg: RIP <- 0x00005555558b67e9
Does anyone have any ideas? What could be causing this?
I'm tearing my hair out. Thanks a lot!
next reply other threads:[~2022-02-03 0:44 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-02-03 0:43 Juraj Oršulić [this message]
2022-02-03 1:06 ` Sam Varshavchik
2022-02-03 1:36 ` Juraj Oršulić
2022-02-03 2:15 ` Juraj Oršulić
2022-02-03 11:39 ` Florian Weimer
[not found] ` <CAEPqvowbo+iH4dazsfub3Vjc1D_zFGgKv2tg92Kv32vGVTq-2w@mail.gmail.com>
[not found] ` <87wnict9uz.fsf@oldenburg.str.redhat.com>
2022-02-03 13:40 ` Juraj Oršulić
2022-02-03 15:38 ` Juraj Oršulić
2022-02-04 10:37 ` Andrew Haley
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=CAEPqvowsVMLJ4uLBUfX-KH_rKQHP_ERjxyFy2e39Je2r9tiBtg@mail.gmail.com \
--to=juraj.orsulic@fer.hr \
--cc=gcc-help@gcc.gnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).