This is the mail archive of the gdb-prs@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

backtrace/2108: arm-elf, problems with backtrace


>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:


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]