Hello together! I am running into a problem while performing a stack trace of x86 code. The assembly code I am running has been generated by mingw from C++ code and looks like this:
6c9c1210 <__ZN7my_class9my_methodEs>: 6c9c1210: sub $0x1c,%esp 6c9c1213: mov 0x20(%esp),%edx 6c9c1217: mov %edx,%eax 6c9c1219: test %dx,%dx 6c9c121c: jle 6c9c1221 <__ZN7my_class9my_methodEs+0x11> 6c9c121e: lea 0x1(%edx),%eax 6c9c1221: cwtl 6c9c1222: mov %eax,(%esp) 6c9c1225: call 6c9c1190 <__Z12my_dummy_functions> 6c9c122a: add $0x1c,%esp 6c9c122d: ret $0x4 6c9c1230 <__ZN8my_struct9my_methodEv>: 6c9c1230: sub $0x1c,%esp 6c9c1233: movzwl 0x4(%ecx),%eax 6c9c1237: test %ax,%ax 6c9c123a: jle 6c9c1241 <__ZN8my_struct9my_methodEv+0x11> 6c9c123c: add $0x1,%eax 6c9c123f: jmp 6c9c1246 <__ZN8my_struct9my_methodEv+0x16> 6c9c1241: mov $0x0,%eax 6c9c1246: cwtl 6c9c1247: add $0x8,%ecx 6c9c124a: mov %eax,(%esp) 6c9c124d: call 6c9c1210 <__ZN7my_class9my_methodEs> 6c9c1252: sub $0x4,%esp 6c9c1255: add $0x1c,%esp 6c9c1258: ret 6c9c1259: nop 6c9c125a: lea 0x0(%esi),%esi The problem manifests itself, when the instruction pointer is inside " __ZN7my_class9my_methodEs" (called at 0x6c9c124d). In order to perform the stack trace, I use the DWARF frame information for calculating the previous instruction pointer. This is done by assuming the return address is the instruction pointer of the previous frame. This is obviously not entirely correct, since the return address points to a location AFTER the previous call. Nevertheless, this assumption seems to be standard for other stack tracers. I am having a problem with this though: The address where I start is 0x6c9c121e. Frame information tells me the following: 00000144 0000001c 00000000 FDE cie=00000000 pc=6c9c1210...6c9c1230 DW_CFA_advance_loc4: 3 DW_CFA_def_cfa_offset: +32 DW_CFA_advance_loc4: 26 DW_CFA_def_cfa_offset: +4 DW_CFA_nop: DW_CFA_nop: So the CFA offset is 32. There I find the next return address 0x6c9c124d. Frame information tells me the following: 00000164 00000028 00000000 FDE cie=00000000 pc=6c9c1230...6c9c1259 DW_CFA_advance_loc4: 3 DW_CFA_def_cfa_offset: +32 DW_CFA_advance_loc4: 31 DW_CFA_def_cfa_offset: +28 DW_CFA_advance_loc4: 3 DW_CFA_def_cfa_offset: +32 DW_CFA_advance_loc4: 3 DW_CFA_def_cfa_offset: +4 And here the problem arises. Due to 0x6c9c124d being the return address, the CFA offset I read is invalid. By assuming an instruction pointer of 0x6c9c124d I also assume that the "ret $0x4" instruction from 0x6c9c122d has been executed and the stack is 4 bytes shorter. This is however not the case. The return has not been executed yet. So my question here is, how shall the stack tracer solve this issue? My first Idea is to decrement the instruction pointer when looking through the frame information (except for the deepest frame, where the instruction pointer is correct). Would that be an approach that works always? How do other consumers solve this issue? Best regards Jayvee
_______________________________________________ Dwarf-Discuss mailing list Dwarf-Discuss@lists.dwarfstd.org http://lists.dwarfstd.org/listinfo.cgi/dwarf-discuss-dwarfstd.org