Hi All,
I don't know if it's the right place to ask some basic questions. I tried to understand dwarf for several weeks. But the progress is very slow. I really need someone to instruct me, so I send this email. If the email disturbed you, I'm so sorry about this. I really hope someone can help me.
My environment is x86_64 linux.
I find a open-source stack unwinding program with libunwind. I use readelf to generate the dwarf to a file.
The unwinding program's result is shown below:
7 [unwind.c, process_stack(), ln 172] INFO: STACK FRAME 0
8 [unwind.c, process_stack(), ln 189] INFO: RIP = 0x00007f86cbd3c7b0 __nanosleep_nocancel+0x0000000000000007
9 [unwind.c, process_stack(), ln 190] INFO: RSP = 0x00007ffd5668f928 RBP = 0x0000000000000000
10 [unwind.c, process_stack(), ln 198] INFO: frame range = (0x00007f86cbd3c7a0 <-> 0x00007f86cbd3c7fa)
11 [unwind.c, process_stack(), ln 199] INFO: handler = 0 lsda = 0
12
13
14 [unwind.c, process_stack(), ln 172] INFO: STACK FRAME 1
15 [unwind.c, process_stack(), ln 189] INFO: RIP = 0x00007f86cbd3c71a sleep+0x000000000000002a
16 [unwind.c, process_stack(), ln 190] INFO: RSP = 0x00007ffd5668f930 RBP = 0x0000000000000000
17 [unwind.c, process_stack(), ln 198] INFO: frame range = (0x00007f86cbd3c6f0 <-> 0x00007f86cbd3c73a)
18 [unwind.c, process_stack(), ln 199] INFO: handler = 0 lsda = 0
19
20
21 [unwind.c, process_stack(), ln 172] INFO: STACK FRAME 2
22 [unwind.c, process_stack(), ln 189] INFO: RIP = 0x00000000004006cf main+0x000000000000002c
23 [unwind.c, process_stack(), ln 190] INFO: RSP = 0x00007ffd5668f960 RBP = 0x00007ffd5668f970
24 [unwind.c, process_stack(), ln 198] INFO: frame range = (0x00000000004006a3 <-> 0x00000000004006d1)
25 [unwind.c, process_stack(), ln 199] INFO: handler = 0 lsda = 0
26
27
28 [unwind.c, process_stack(), ln 172] INFO: STACK FRAME 3
29 [unwind.c, process_stack(), ln 189] INFO: RIP = 0x00007f86cbc90401 __libc_start_main+0x00000000000000f1
30 [unwind.c, process_stack(), ln 190] INFO: RSP = 0x00007ffd5668f980 RBP = 0x00000000004006e0
31 [unwind.c, process_stack(), ln 198] INFO: frame range = (0x00007f86cbc90310 <-> 0x00007f86cbc904da)
32 [unwind.c, process_stack(), ln 199] INFO: handler = 0 lsda = 0
Dwarf info is shown below:
Frame 0: (The absolute address of RIP is 0xcc7a8.)
30189 0000f1f0 0000000000000014 0000f1f4 FDE cie=00000000 pc=00000000000cc7a0..00000000000cc7fa
30190 DW_CFA_advance_loc: 29 to 00000000000cc7bd
30191 DW_CFA_def_cfa_offset: 16
30192 DW_CFA_advance_loc: 35 to 00000000000cc7e0
30193 DW_CFA_def_cfa_offset: 8
30194 DW_CFA_nop
The CFA's value should be $RSP+16 (0x00007ffd5668f938). But in frame 1, the value is 0x00007ffd5668f930. Why the two value is different? I guess there's a alignment rule in CIE?
Frame 1: (The absolute address of RIP is 0xcc71a.)
30152 0000f1a0 0000000000000034 0000f1a4 FDE cie=00000000 pc=00000000000cc6f0..00000000000cc73a
30153 DW_CFA_advance_loc: 1 to 00000000000cc6f1
30154 DW_CFA_def_cfa_offset: 16
30155 DW_CFA_offset: r6 (rbp) at cfa-16
30156 DW_CFA_advance_loc: 1 to 00000000000cc6f2
30157 DW_CFA_def_cfa_offset: 24
30158 DW_CFA_offset: r3 (rbx) at cfa-24
30159 DW_CFA_advance_loc: 6 to 00000000000cc6f8
30160 DW_CFA_def_cfa_offset: 48
30161 DW_CFA_advance_loc: 45 to 00000000000cc725
30162 DW_CFA_remember_state
30163 DW_CFA_def_cfa_offset: 24
30164 DW_CFA_advance_loc: 3 to 00000000000cc728
30165 DW_CFA_def_cfa_offset: 16
30166 DW_CFA_advance_loc: 1 to 00000000000cc729
30167 DW_CFA_def_cfa_offset: 8
30168 DW_CFA_advance_loc: 7 to 00000000000cc730
30169 DW_CFA_restore_state
30170 DW_CFA_advance_loc: 7 to 00000000000cc737
30171 DW_CFA_def_cfa_offset: 24
30172 DW_CFA_advance_loc: 1 to 00000000000cc738
30173 DW_CFA_def_cfa_offset: 16
30174 DW_CFA_advance_loc: 1 to 00000000000cc739
30175 DW_CFA_def_cfa_offset: 8
30176 DW_CFA_nop
30177 DW_CFA_nop
30178 DW_CFA_nop
30179 DW_CFA_nop
30180 DW_CFA_nop
In Frame 2, CFA should be $RSP+24 (0x00007ffd5668f930 + 24 = 0x00007ffd5668f48). However, in frame 2, we can see the $RSP is equal to 0x00007ffd5668f960. I guess DW_CFA_remember_state is the reason. If it's true, why do we need the next line "30163 DW_CFA_def_cfa_offset: 24" in dwarf?
Frame 2: (The absolute address of RIP is .0x4006cf)
83 000000d0 000000000000001c 000000a4 FDE cie=00000030 pc=00000000004006a3..00000000004006d1
84 DW_CFA_advance_loc: 1 to 00000000004006a4
85 DW_CFA_def_cfa_offset: 16
86 DW_CFA_offset: r6 (rbp) at cfa-16
87 DW_CFA_advance_loc: 3 to 00000000004006a7
88 DW_CFA_def_cfa_register: r6 (rbp)
89 DW_CFA_nop
90 DW_CFA_nop
91 DW_CFA_nop
92 DW_CFA_nop
93 DW_CFA_nop
94 DW_CFA_nop
95 DW_CFA_nop
In frame 2, I don't know how to parse this one. How to calculate CFA for this frame? In line 85, CFA=$RSP+16, $RBP=CFA-16. In line 88, CFA=$RBP. I'm really confused about this one.
Looking forward to your reply.
Thanks,
Tim