This is the mail archive of the
gdb-prs@sourceware.org
mailing list for the GDB project.
backtrace/2108: arm-elf, problems with backtrace
- From: gotmada at yahoo dot com
- To: gdb-gnats at sources dot redhat dot com
- Date: 4 Apr 2006 08:49:49 -0000
- Subject: backtrace/2108: arm-elf, problems with backtrace
- Reply-to: gotmada at yahoo dot com
>Number: 2108
>Category: backtrace
>Synopsis: arm-elf, problems with backtrace
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: unassigned
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Tue Apr 04 08:58:01 GMT 2006
>Closed-Date:
>Last-Modified:
>Originator: Martin Dahlberg
>Release: arm-elf-gcc 3.4.3 and arm-elf-gdb 6.0
>Organization:
>Environment:
Debian linux
Linux localhost 2.4.27-2-686 #1 Wed Nov 30 21:55:37 JST 2005 i686 GNU/Linux
Remote debugging with MAJIC/EPI.
Code is statically linked and runs on embedded device.
>Description:
I have problem with this on an NetSilicon arm9-processor.
When the compiler generates jumptables that change $PC for e.g. switch-statements, the backtrace lose track and claims the call was from $a.
(0x00049328 <do_switch+28>: ldrls pc, [pc, r3, lsl #2])
(majic-gdb)b applicationStart
Breakpoint 3 at 0x496bc: file ../root.c, line 431.
(majic-gdb)c
Continuing.
Breakpoint 3, applicationStart () at ../root.c:431
(majic-gdb)s
do_switch (a=1) at ../root.c:262
(majic-gdb)bt
#0 do_switch (a=1) at ../root.c:262
#1 0x000496c4 in applicationStart () at ../root.c:431
#2 0x00230a2c in netosStartup () at ./common/reset.s:111
#3 0x001d1470 in _tx_thread_shell_entry () at ./common/reset.s:111
(majic-gdb)n
(majic-gdb)bt
#0 $a () at ../root.c:269
#1 0x000496c4 in applicationStart () at ../root.c:431
#2 0x00230a2c in netosStartup () at ./common/reset.s:111
#3 0x001d1470 in _tx_thread_shell_entry () at ./common/reset.s:111
(majic-gdb)s
oneCall () at ../root.c:249
(majic-gdb)bt
#0 oneCall () at ../root.c:249
#1 0x000493e8 in $a () at ../root.c:269
(majic-gdb)
A related (same?) problem shows when do_switch is disassembled. $d instead of do_switch+0xNNN.
(majic-gdb)disassemble do_switch
Dump of assembler code for function do_switch:
0x0004930c <do_switch+0>: mov r12, sp
0x00049310 <do_switch+4>: stmdb sp!, {r11, r12, lr, pc}
0x00049314 <do_switch+8>: sub r11, r12, #4 ; 0x4
0x00049318 <do_switch+12>: sub sp, sp, #4 ; 0x4
0x0004931c <do_switch+16>: str r0, [r11, -#16]
0x00049320 <do_switch+20>: ldr r3, [r11, -#16]
0x00049324 <do_switch+24>: cmp r3, #39 ; 0x27
0x00049328 <do_switch+28>: ldrls pc, [pc, r3, lsl #2]
0x0004932c <do_switch+32>: b 0x4967c <$a+684>
0x00049330 <$d+0>: ldreqd r9, [r4], -r0
0x00049334 <$d+4>: andeq r9, r4, r4, ror #7
>How-To-Repeat:
Create a C-program with a switch large enough that it is solved by a jumptable.
static short zero,one,two,three,four;
static int five,six,seven,eight,nine;
static int call, onfiltered;
static void
zeroCall(void)
{
call++;
}
static void
oneCall(void)
{
zeroCall();
}
static void
twoCall(void)
{
oneCall();
}
/* Large switch-statement to generate $PC-relative addressing */
static int
do_switch(int a)
{
switch(a)
{
case 0:
zeroCall();
zero = 0;
break;
case 1:
oneCall();
onfiltered= 1;
break;
case 2:
twoCall();
two = 2;
break;
case 3:
three = 3;
break;
case 4:
four = 4;
break;
case 5:
five = 5;
break;
case 6:
six = 6;
break;
case 7:
seven = 7;
break;
case 8:
eight = 8;
break;
case 9:
nine = 9;
break;
case 10:
zeroCall();
zero = 10;
break;
case 11:
oneCall();
onfiltered= 11;
break;
case 12:
twoCall();
two = 12;
break;
case 13:
three = 13;
break;
case 14:
four = 14;
break;
case 15:
five = 15;
break;
case 16:
six = 16;
break;
case 17:
seven = 17;
break;
case 18:
eight = 18;
break;
case 19:
nine = 19;
break;
case 20:
zeroCall();
zero = 20;
break;
case 21:
oneCall();
onfiltered= 21;
break;
case 22:
twoCall();
two = 22;
break;
case 23:
three = 23;
break;
case 24:
four = 24;
break;
case 25:
five = 25;
break;
case 26:
six = 26;
break;
case 27:
seven = 27;
break;
case 28:
eight = 28;
break;
case 29:
nine = 29;
break;
case 30:
zeroCall();
zero = 30;
break;
case 31:
oneCall();
onfiltered= 31;
break;
case 32:
twoCall();
two = 32;
break;
case 33:
three = 33;
break;
case 34:
four = 34;
break;
case 35:
five = 35;
break;
case 36:
six = 36;
break;
case 37:
seven = 37;
break;
case 38:
eight = 38;
break;
case 39:
nine = 39;
break;
default:
;
}
return 0;
}
void
applicationStart(void)
{
do_switch(1);
do_switch(2);
do_switch(3);
tx_thread_suspend(tx_thread_identify());
}
>Fix:
>Release-Note:
>Audit-Trail:
>Unformatted: