This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Trouble with XDS GDB agent

Other Parts Discussed in Thread: TEST2, HALCOGEN

Hi,

I'm trying to use GDB with XDS GDB agent to debug a program running in RAM on an RM46 LaunchPad. I'm seeing all kinds of weird behavior related to software breakpoints and stepping through the code. I've been trying to come up with a minimal test example. This is what I've got.

I have a simple assembly program loaded that has some instructions in ARM mode, some instructions in THUMB mode:

.syntax unified

  .arm

start:

  b test1

test1:

  blx test2

  .thumb

test2:

  b test3

test3:

  b test2

Note that "test1" is in ARM mode, but "test2" and "test3" are in THUMB mode. Here's a disassembled version of the code:

$ arm-none-eabi-objdump -d main.elf

main.elf:     file format elf32-littlearm

Disassembly of section .text:

08000000 <start>:

 8000000: eaffffff b 8000004 <test1>

08000004 <test1>:

 8000004: faffffff blx 8000008 <test2>

08000008 <test2>:

 8000008: e7ff      b.n 800000a <test3>

0800000a <test3>:

 800000a: e7fd      b.n 8000008 <test2>

I load the assembled program at 0x8000000 (using GDB's "load"). I set a breakpoint on "test2" and try to single step through the program with "stepi". It works for a few steps, but then suddenly I find the PC has jumped ahead. Here's the console log from gdb:

$ arm-none-eabi-gdb -ex 'target remote :55000' -ex 'set confirm off' -ex 'file main.elf'

GNU gdb (GNU Tools for ARM Embedded Processors) 7.10.1.20160923-cvs

Copyright (C) 2015 Free Software Foundation, Inc.

License GPLv3+: GNU GPL version 3 or later <gnu.org/.../gpl.html>

This is free software: you are free to change and redistribute it.

There is NO WARRANTY, to the extent permitted by law.  Type "show copying"

and "show warranty" for details.

This GDB was configured as "--host=x86_64-apple-darwin10 --target=arm-none-eabi".

Type "show configuration" for configuration details.

For bug reporting instructions, please see:

<www.gnu.org/.../>.

Find the GDB manual and other documentation resources online at:

<www.gnu.org/.../>.

For help, type "help".

Type "apropos word" to search for commands related to "word".

Remote debugging using :55000

0x00000020 in ?? ()

Reading symbols from main.elf...done.

(gdb) load

Loading section .text, size 0xc lma 0x8000000

Start address 0x8000000, load size 12

Transfer rate: 363 bytes/sec, 12 bytes/write.

(gdb) break test2

Breakpoint 1 at 0x8000008: file main.S, line 12.

(gdb) stepi

test1 () at main.S:8

8   blx test2

(gdb) stepi

Breakpoint 1, test2 () at main.S:12

12   b test3

(gdb) stepi

test3 () at main.S:15

15   b test2

(gdb) stepi

0x0800024e in ?? ()

(gdb) print $pc

$1 = (void (*)()) 0x800024e

(gdb) disas start

Dump of assembler code for function start:

   0x08000000 <+0>: b 0x8000004 <test1>

End of assembler dump.

(gdb) disas test1

Dump of assembler code for function test1:

   0x08000004 <+0>: blx 0x8000008 <test2>

End of assembler dump.

(gdb) disas test2

Dump of assembler code for function test2:

   0x08000008 <+0>: b.n 0x800000a <test3>

End of assembler dump.

(gdb) disas test3

Dump of assembler code for function test3:

   0x0800000a <+0>: b.n 0x8000008 <test2>

End of assembler dump.

(gdb)

Any ideas what is going on? To me, it looks like XDS GDB agent is setting software breakpoints incorrectly somehow. Perhaps it is not invalidating some instruction cache or pipeline after writing to RAM?

Thanks,

Girts

  • Girts,

    A couple of months ago I recall being able to load and debug code in my RM46 Launchpad using the GDB Agent, therefore something was not entirely clear from your post: were you able to validate your code using the full CCS debugger IDE before trying the GDB Agent?

    This would help identify any possible pitfalls built into the code itself, such as invalid stack pointer initialization or even watchdog timers.

    To help with this you could try to run a very minimal example code from HalCoGen and see if the outcome is different.

    >>To me, it looks like XDS GDB agent is setting software breakpoints incorrectly somehow. Perhaps it is not invalidating some instruction cache or pipeline after writing to RAM?
    The GDB Agent does not have this specific awareness about the hardware to issue cache invalidates or control pipeline streams - these are either built into the hardware or furnished by the application code.

    Hope this helps,
    Rafael
  • Hi Rafael,

    Things that work:
    * I can get code building and running from flash with HalCoGen.
    * Hardware breakpoints seem to work with the XDS GDB agent as well (after fixing the library paths (processors.wiki.ti.com/.../XDS_GDB_Agent only mentions Linux, but Mac has the same issue).

    The problem seems to be with software breakpoints. When stepping through code, GDB asks XDS GDB agent to set a 2 byte software breakpoint. The agent (or probe) is supposed to replace that memory location with some sort of breakpoint instruction. But instead, it seems to replace it with something that jumps couple hundred bytes ahead.

    Since I couldn't tell directly what XDS GDB agent or (XDS 110) does to that memory location, I wrote a small hack: I saved the location that I'm setting the breakpoint to into R2. And then created a long chain of "ldr r1, [r2]". After I triggered the breakpoint and stepping, causing the program to start executing from the wrong location, I looked at the contents of R1. Looks like the agent (or probe?) writes 0xe120 to the memory location (clobbering 4 bytes instead of only 2). That instruction decodes as "b.n 00000244", which explains the jump.

    Here's a snippet from verbose GDB agent output (GDB_AGENT_DISPLAY_LEVEL=6):

    >>>> %$Z0,8000008,2#74
    <<<< $OK#00
    >>>> %$Hc0#db
    <<<< $OK#00
    >>>> %$s#73
    <<<< $T050f:4e020008;#00
    >>>> %$m800024e,4#60
    <<<< $a5bea5be#00
    >>>> %$p19#da
    <<<< $f7010000#00
    >>>> %$m800024e,2#5e
    <<<< $a5be#00
    >>>> %$g#67
    <<<< $e80b467120e10000080000089a389253a05b30d462eb1e6df405a338700c219cf842b0862710690cf040d90f8918607d8ad503982885c581040000084e020008#00
    >>>> %$m8000004,4#29
    <<<< $0ff20002#00
    >>>> %$m8000000,4#25
    <<<< $fffffffa#00
    >>>> %$qfThreadInfo#bb
    <<<< $m0#00
    >>>> %$qsThreadInfo#c8
    <<<< $l#00
    >>>> %$z0,8000008,2#94
    <<<< $OK#00

    You can see GDB requesting a software breakpoint ("Z0,8000008,2") and requesting single stepping ("s"). The next reply shows the target stopping at the "wrong" address ("T050f:4e020008").

    I've uploaded my test sample here: gist.github.com/.../0d05ab51486c51797caf2dd315d4309f

    A sample run of gdb_debugging_test.sh:

    GNU gdb (GNU Tools for ARM Embedded Processors) 7.10.1.20160616-cvs
    Copyright (C) 2015 Free Software Foundation, Inc.
    License GPLv3+: GNU GPL version 3 or later <gnu.org/.../gpl.html>
    This is free software: you are free to change and redistribute it.
    There is NO WARRANTY, to the extent permitted by law. Type "show copying"
    and "show warranty" for details.
    This GDB was configured as "--host=x86_64-apple-darwin10 --target=arm-none-eabi".
    Type "show configuration" for configuration details.
    For bug reporting instructions, please see:
    <www.gnu.org/.../>.
    Find the GDB manual and other documentation resources online at:
    <www.gnu.org/.../>.
    For help, type "help".
    Type "apropos word" to search for commands related to "word".
    Remote debugging using :55000
    0x0000000c in ?? ()
    Reading symbols from main.elf...done.
    Loading section .text, size 0x1ec lma 0x8000000
    Start address 0x8000000, load size 492
    Transfer rate: 10 KB/sec, 492 bytes/write.
    Breakpoint 1 at 0x8000008: file main.S, line 12.
    thumb_start () at main.S:9
    9 adr r2, test2

    Breakpoint 1, test2 () at main.S:12
    12 b test3
    test3 () at main.S:15
    15 b test2
    0x0800024e in ?? ()
    $1 = (void (*)()) 0x800024e

    Girts
  • (It looks like the forum software ate my first reply attempt. In case it did, here's another attempt.)

    Here's what I'm using for reproducing this:
    gist.github.com/.../1bc6f6a97d6a54c0d6d3ee044e74d8f0

    Sample run:
    $ ./gdb_debugging_test.sh
    GNU gdb (GNU Tools for ARM Embedded Processors) 7.10.1.20160616-cvs
    Copyright (C) 2015 Free Software Foundation, Inc.
    License GPLv3+: GNU GPL version 3 or later <gnu.org/.../gpl.html>
    This is free software: you are free to change and redistribute it.
    There is NO WARRANTY, to the extent permitted by law. Type "show copying"
    and "show warranty" for details.
    This GDB was configured as "--host=x86_64-apple-darwin10 --target=arm-none-eabi".
    Type "show configuration" for configuration details.
    For bug reporting instructions, please see:
    <www.gnu.org/.../>.
    Find the GDB manual and other documentation resources online at:
    <www.gnu.org/.../>.
    For help, type "help".
    Type "apropos word" to search for commands related to "word".
    Remote debugging using :55000
    0x0000000c in ?? ()
    Reading symbols from main.elf...done.
    Loading section .text, size 0x8b0 lma 0x8000000
    Start address 0x8000000, load size 2224
    Transfer rate: 17 KB/sec, 741 bytes/write.
    Breakpoint 1 at 0x8000008: file main.S, line 12.
    thumb_start () at main.S:9
    9 adr r2, test2

    Breakpoint 1, test2 () at main.S:12
    12 b test3
    test3 () at main.S:15
    15 b test2
    306 bkpt #3
    $1 = 0x800024e
    $2 = 0xe120
    (gdb) quit

    The test script asks GDB agent to set a sw breakpoint (GDB requests a 2-byte sw breakpoint, as observed in the verbose GDB AGENT logs). This then shows that GDB agent (or XDS110 probe) clobbers 0x8000008 with 0xe120, instead of replacing it with a 2 byte Thumb breakpoint instruction. In thumb mode 20 E1 translates to "b.n 244" which corresponds to the jump I'm seeing.

    Girts