From: peter g. <pga...@li...> - 2005-05-23 07:13:23
|
Hi, I encountered some gdb frame problems that I have no doubt sub-optimally ad= dressed. So I am dumping it on the group in the hope of fishing out possible impovem= ents. I am using gdb version 6.3 but this also applies to 6.0 at least. I have an embedded cross-debugging setup using gdbserver, with shared libra= ries,=20 and linuxthreads, targetting the sh4 cpu, running linuxsh 2.6.3 at the mome= nt. With respect to the testsuite program break.c, I found the following proble= ms. 1) Break at main. Go next once, then a second time. gdb segfaults. 2) Break at the recursive factorial function. Continue twice. Go backtrace. An infinite backtrace results. 3) Break at main. Go "until 100". The program exits without hitting a tempo= rary breakpoint. These are all frame problems, because they are simply fixed by editing out = the call to frame_unwind_append_sniffer (gdb_arch, dwarf2_frame_sniffer) at line 270= 0 or so of sh-tdep.c. That is the simplistic fix. The deep question is, why doesnt = the dwarf2 code work correctly? My current hypothesis is that while the dwarf2 frame code is used to unwind the program counter, the dwarf2 information emitted by both compiler versions I have looked at (3.0.4 and 3.2.2) do not contain information adequate to track the PR register. On the 386, the function return address is always stored on the s= tack immediately when a function call is made, but for the SH4 the PR register i= s stored=20 at some later point not at top of frame with an explicit push.=20 The following is the dissassembly of the prolog for main. (from objdump -d) 00000000 <main>: 0: 86 2f mov.l r8,@-r15 2: e6 2f mov.l r14,@-r15 4: 22 4f sts.l pr,@-r15 !(PR is now on the stack.) 6: f0 7f add #-16,r15 8: f3 6e mov r15,r14 a: 42 2e mov.l r4,@r14 c: 51 1e mov.l r5,@(4,r14) e: 62 1e mov.l r6,@(8,r14) 10: e2 62 mov.l @r14,r2 12: 47 91 mov.w a4 <main+0xa4>,r1 ! 0x3039 14: 10 32 cmp/eq r1,r2 16: 13 8b bf 40 <main+0x40> 18: 23 d1 mov.l a8 <main+0xa8>,r1 ! 0x0 1a: 24 d2 mov.l ac <main+0xac>,r2 ! 0x0 1c: 12 64 mov.l @r1,r4 1e: 23 65 mov r2,r5 20: 23 d1 mov.l b0 <main+0xb0>,r1 ! 0x0 22: 0b 41 jsr @r1 24: 09 00 nop=09 26: 01 e1 mov #1,r1 28: 13 1e mov.l r1,@(12,r14) 2a: 33 a0 bra 94 <main+0x94> 2c: 09 00 nop=09 2e: 09 00 nop=09 30: 09 00 nop=09 And this is its corresponding dwarf frame debugging info (from readelf -wf) 00000000 0000000c ffffffff CIE Version: 1 Augmentation: "" Code alignment factor: 1 Data alignment factor: -4 Return address column: 17 DW_CFA_def_cfa: r15 ofs 0 00000010 00000028 00000000 FDE cie=3D00000000 pc=3D00000000..000000e4 DW_CFA_advance_loc: 2 to 00000002 DW_CFA_def_cfa_offset: 4 DW_CFA_GNU_args_size: 4 DW_CFA_advance_loc: 2 to 00000004 DW_CFA_def_cfa_offset: 8 DW_CFA_GNU_args_size: 8 DW_CFA_advance_loc: 2 to 00000006 !(Have location of frame, but no= record of PR save) DW_CFA_def_cfa_offset: 12 DW_CFA_GNU_args_size: 12 DW_CFA_advance_loc: 2 to 00000008 DW_CFA_def_cfa_offset: 28 DW_CFA_GNU_args_size: 28 DW_CFA_advance_loc: 26 to 00000022 DW_CFA_GNU_args_size: 0 DW_CFA_advance_loc: 12 to 0000002e DW_CFA_def_cfa_offset: 0 DW_CFA_nop DW_CFA_nop It seems to me that to function properly,=20 the dwarf2 debugging info should track the PR as the return address, but it doesnt, so stepping, backtrace-ing, and until-ing are stuffed. After disabling dwarf2 frame sniffing in gdb, the previous bugs disappeared to be replaced by new bugs.=20 1) The sh_analyze_prologue function in gdb/sh-tdep.c is very out of date wr= t the compiler. It needs to emulate all registers for calculating stack array sizes, instea= d of just the "last" register. Also I added a check so that it doesn't analyze past the c= urrent PC. The question here is why analyze the prologue and go past the current PC? 2) Backtrace termination for threads. In glibc/sysdeps/unix/sysv/linux/sh/clone.S and linuxsh/arch/sh/kernel/sign= al.c:setup_frame clear the frame pointer r14 before launching threads and signal handlers. This allows gdb to terminate its backtrace. I could find no mention of the = initial frame pointer value in the hitachi ABI so I do wonder what the correct procedure is. Actually it is now cleared in glibc as of about five months ago. I could actually do it myself in signal.c, unless someone objects. After this I gained a reasonable gdb with stepping and threads and backtrac= ing working. I also applied Paul Mundt's patch for getting a gnu/linux ABI. If this isn't the "wrong" thing to do, I will post patches. Otherwise, please point me to patches that address these issues. Cheers, Peter Garrone --=20 _______________________________________________ Check out the latest SMS services @ http://www.linuxmail.org This allows you to send and receive SMS through your mailbox. Powered by Outblaze |