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.

Compiler/MSP430FR5969: GDB launch causing program counter error

Part Number: MSP430FR5969
Other Parts Discussed in Thread: MSP430-GCC-OPENSOURCE

Tool/software: TI C/C++ Compiler

I've spent the past day investigating a very strange error occurring in GDB.

Behavior
- program fails to reach main (usually, not always)
- occurs only on first run after launching gdb, all successive loads are error free

To investigate this issue, I examined the assembly step by step. Immediately after load we seem to be where we should be:

0xe0e8 <__crt0_start>                   mova   #81920, r1      ;0x14000                                                                                 
0xe0ec <__crt0_init_bss>                mova   #7982,  r12     ;0x01f2e                                                                                 
0xe0f0 <__crt0_init_bss+4>              clr    r13             ;                                                                                        
0xe0f2 <__crt0_init_bss+6>              mova   #132,   r14     ;0x00084                                                                                 
0xe0f6 <__crt0_init_bss+10>             clr    r15             ;                                                                                        
0xe0f8 <__crt0_init_bss+12>             calla  #53686          ;0x0d1b6                                                                                 
0xe0fc <__crt0_init_highbss>            mova   #65538, r12     ;0x10002                                                                                 
0xe100 <__crt0_init_highbss+4>          clr    r13             ;                                                                                        
0xe102 <__crt0_init_highbss+6>          mova   #844,   r14     ;0x0034c                                                                                 
0xe106 <__crt0_init_highbss+10>         cmp    #0,     r14     ;r3 As==00                                                                               
0xe108 <__crt0_init_highbss+12>         jz     $+6             ;abs 0xe10e                  

The registers also appear to be correct (though I suspect these don't get updated before running) :

(gdb) info registers
pc             0xe0e8	0xe0e8 <__crt0_start>
sp             0x14000	81920
sr             0x0	0
cg             0x0	0
r4             0xffff	65535
r5             0xffff	65535
r6             0xffff	65535
r7             0xa55a	42330
r8             0xffff	65535
r9             0x112	274
r10            0x1af8	6904
r11            0xffff	65535
r12            0x4	4
r13            0x1113	4371
r14            0x1a1a	6682
r15            0x4400	17408

Then after entering a single "stepi" instruction, the $pc is suddenly pointing at the beginning of HIFRAM:

(gdb) stepi
0x00010004 in cosmosStrP.2845 ()

Instructions at this address:
0x10004 <cosmosStrP.2845+2>     and.b  @r15+,  -1(r15) ; 0xffff
0x10008 <cosmosStrP.2845+6>     and.b  @r15+,  -1(r15) ; 0xffff                                                                                         
0x1000c <cosmosStrP.2845+10>    and.b  @r15+,  -1(r15) ; 0xffff                                                                                         
0x10010 <cosmosStrP.2845+14>    and.b  @r15+,  -1(r15) ; 0xffff                                                                                         
0x10014 <cosmosStrP.2845+18>    and.b  @r15+,  -1(r15) ; 0xffff                                                                                         
.
.
.

As you can see, the program counter is in the weeds:

(gdb) info registers 
pc             0x10004	0x10004 <cosmosStrP.2845+2>
sp             0x14000	81920
sr             0x101	257
cg             0x0	0
r4             0xffff	65535
r5             0xffff	65535
r6             0xffff	65535
r7             0xa55a	42330
r8             0xffff	65535
r9             0x112	274
r10            0x1af8	6904
r11            0xffff	65535
r12            0x4	4
r13            0x1113	4371
r14            0x1a1a	6682
r15            0x4400	17408

According to the map file, this is the location of upper.data:

.upper.data     0x0000000000010000        0x2 load address 0x00000000000058de
                0x00000000000058de                __upper_data_init = LOADADDR (.upper.data)
                0x0000000000010000        0x2 SHORT 0x1
                0x0000000000010002                __high_datastart = .
*(.upper.data.* .upper.data)                  
                0x0000000000010002                __high_dataend = .
                0x0000000000000000                __rom_highdatacopysize = (SIZEOF (.upper.data) - 0x2)
                0x00000000000058e0                __rom_highdatastart = (LOADADDR (.upper.data) + 0x2)

So that's very strange and I don't see how $pc can be set to 0x10000 on the initial load. I was unable to find clear information on how the CPU registers are set. Now if we do a "load" the registers appear to be back to normal:

(gdb) info registers 
pc             0xe0e8	0xe0e8 <__crt0_start>
sp             0x14000	81920
sr             0x101	257
cg             0x0	0
r4             0xffff	65535
r5             0xffff	65535
r6             0xffff	65535
r7             0xa55a	42330
r8             0xffff	65535
r9             0x112	274
r10            0x1af8	6904
r11            0xffff	65535
r12            0x4	4
r13            0x1113	4371
r14            0x1a1a	6682
r15            0x4400	17408

And indeed, we can run with no issues:

(gdb) stepi
0x0000e0ec in __crt0_init_bss ()
0x0000e0f0 in __crt0_init_bss ()
0x0000e0f2 in __crt0_init_bss ()
0x0000e0f6 in __crt0_init_bss ()
(gdb) b	main
Breakpoint 1 at 0x5a32: file src/main.c, line 13.
(gdb) c
Continuing.

Breakpoint 1, main (argc=0, argv=0x0) at src/main.c:13

Debugging

  • This behavior is repeatable
  • I've been using the same debug stack for the past two weeks and the problem only started yesterday, so I assumed this was a code problem
  • The most likely cause seemed to be the linker file. I pointed the stack at the top of HIFRAM and changed the length of HIFRAM to be 0x4000 instead of 0x3FFF to align $sp. Even though this is technically 1 address past the end of the allowable address range, my understanding is that $sp is always decremented (into an allowable address) before being used. This has been working for days but just to be safe I tried restoring the linker to its original configuration
  • I used old code that never encountered this problem and is also ~12kB smaller
  • When I power cycle the board without gdb running, the board restarts and the code executes normally
  • I tried disconnecting my analog ADC signals
  • I tried using another MSP device
  • I restarted the lab machine it's running on

Without knowing more about how the core CPU registers are set and how to probe them before executing, I'm out of debugging ideas

  • Hey Mike,

    Thanks for the detailed post, lots of info to dig through.  I'm not very familiar with the GBD tool, so let me dig in and I might have to loop someone else in.

    I'll try and get back to you later today. 

    Thank,

    JD    

  • Hi JD,

    Is there any update on this? I know there's a lot to work through here but I'm curious to know what's going on.

    Cheers,
    EM

  • The MSP430 will load the program counter from the reset vector at 0xFFFE on reset. What gdb will do is another question. It could look at the .elf file for the starting point (after a load command) or do something else.

  • Hello Mike,

    Very sorry, I got pulled away and haven't been able to look into this.  I wanted to check in.  Are you still having this issue with GBD somehow corrupting the PC? 

    Was this is only after the very initial flashing of the device and after either a software or hardware reset it worked as expected?  

    Thanks,

    JD

  • Thanks for checking in. Somehow, the issue seems to have disappeared.

    The problem was occurring only after the initial flash when launching gdb. After gdb was running, I could reload the code (without killing gdb) consistently with no issue.

  • Of course after I made this comment the problem is back. Pretty strange because it had been working without issue for the past week or so.

  • I discovered that the problem seems at least partially dependent on the image being flashed for some reason. While I was debugging a watchdog problem, I commented out a single line of code, rebuilt, launched gdb, and noticed that the first launch problem did not occur. I tried this several more times to confirm.

    I then uncommented that line of code and the problem returned, but this time the $pc problem occurs on every other launch. I tried this several more times to confirm as well. Note that this behavior has been observed before as well.

    The line of code in question: while(REFCTL0 & REFGENBUSY);

    I do not believe that this line of code is causing the problem. This line has been included in my application for some time and was present both when the problem was occurring and when it was not. If anything, this seems like a problem with the way the image is flashed in certain cases. 

  • Hey Mike,

    This does seem like a very strange issue.  I've never heard of anything like it before.  

    What does you full setup look like?  What compiler and tools are you using? Can you provide version numbers for compiler and gdb?  

    We're getting beyond my scope of knowledge here, so I might send this info over to the compiler team and see if they have any ideas.  

    Thanks,

    JD


      

  • I've tried everything I can think of to debug this issue. On launches where the $pc is wild, the very first "stepi" is off in the weeds so the code never has a chance. My best guess is that the $pc is never properly initialized but I couldn't find any info on how or why that might be the case.

    As for my setup, I'm using the MSP430-GCC Standalone Debug Stack. Version info:

    Component versions

    • GCC 7.3.2.154
    • GDB 8.1
    • binutils 2.26.0
    • Newlib 2.4.0
    • MSPDebugStack 3.14.0.000
    • MSP430 header and support files 1.207
    • MSP430 GDB Agent 8.0.809.0

     

    Link to download page: http://software-dl.ti.com/msp430/msp430_public_sw/mcu/msp430/MSPGCC/6_1_1_0/index_FDS.html

  • I wonder if this is a manifestation of an issue we've seen where GDB fails to flash large executables properly: http://e2e.ti.com/support/tools/ccs/f/81/p/801858/2971415#2971415

    Is executing the "load" command again the only thing that fixes it when you experience the bad execution?

    The default timeout in GDB for communication with the gdb_agent_console is only 2s in 7.3.2.154. You can increase the timeout using "set remotetimeout 10".

    There is now an installer available for the latest MSP430-GCC release 8.3.0.16, so if you want to try that release, this higher timeout is set by default.

    P.S.

    Make sure to use the tag "MSP430-GCC-OPENSOURCE" when posting about the MSP430-GCC toolchain, I'll see the post a lot quicker.

    Regards,

  • Unfortunately, increasing the timeout with "set remotetimeout 10" didn't fix the problem. I also never saw the packet error shown in the linked thread.

    Using the "load" command does consistently fix the problem but only after I start and stop the program. Launching GDB and then immediately reloading the program does not fix the problem. Another way to fix it is by manually setting the $pc back to the start of the text section. In situations where I run my application and then stop it and see that the $pc is wild, I can use "set $pc = <start of .text section>" and it will run normally without requiring another "load" command.

    Thanks for the heads up about the tag, I'll be sure to include that next time.

  • I tried looking at the source code for the msp430 specific gdb code but that didn't help at all. Then I enabled  some debugging information in mspdebug which prints information on the gdb packets. Several of which mspdebug didn't know what to do with.

    (mspdebug) gdb
    Bound to port 2000. Now waiting for connection...
    Client connected from 127.0.0.1:57024
    Clearing all breakpoints...
    starting GDB reader loop...
    process_gdb_command: qSupported:multiprocess+;swbreak+;hwbreak+;qRelocInsn+;fork-events+;vfork-events+;exec-events+;vContSupported+;QThreadEvents+;no-resumed+
    process_gdb_command: vMustReplyEmpty
    process_gdb_command: unknown command vMustReplyEmpty
    process_gdb_command: Hg0
    process_gdb_command: unknown command Hg0
    process_gdb_command: qTStatus
    process_gdb_command: unknown command qTStatus
    process_gdb_command: ?
    process_gdb_command: qfThreadInfo
    process_gdb_command: Hc-1
    process_gdb_command: unknown command Hc-1
    process_gdb_command: qC
    process_gdb_command: unknown command qC
    process_gdb_command: qAttached
    process_gdb_command: unknown command qAttached
    process_gdb_command: qOffsets
    process_gdb_command: unknown command qOffsets
    process_gdb_command: g
    Reading registers
    process_gdb_command: qfThreadInfo
    process_gdb_command: qSymbol::
    process_gdb_command: unknown command qSymbol::
    process_gdb_command: qfThreadInfo
    process_gdb_command: vCont?
    process_gdb_command: unknown command vCont?
    process_gdb_command: Hc0
    process_gdb_command: unknown command Hc0
    process_gdb_command: c
    Running
    

    I don't see anything there that would alter the program counter. But when I use gdb to load a program I do see that it writes the registers, including the program counter, once it is done.

  • Hey All,

    Great discussion here.  Unfortunately,  I've found out that TI does not actively support this product.  I'm going to go ahead and click "TI thinks resolved" for this post for our tracking purposes, but please continue to use this thread for further discussion. 

    Thanks,

    JD 

  • Does this mean no one is actively working on the gdb agent? There are some significant limitations that I'm hoping can be resolved.

  • Hi Mike,

    As you know I'm providing support for the MSP430 GNU tools such as GDB.

    With regards to the GDB Agent I am in contact with the team at TI who maintain it so I can confirm it is being worked on.

    Regards,

  • Your support here and on other questions has been excellent and is much appreciated.

    I'm hopeful that TI will be responsive to the gdb agent issues as I've had a pretty positive experience with the MSP430 and associated software so far.

  • Thanks!

    We've got a ticket filed for the GDB Agent watchpoint issue now, I've posted a tracking link to it in the other thread.

    If you end up trying to use mspdebug for the GDB server, it would be interesting to know if you still encounter this issue. We might then be able to work out where the bug is in the tools.

**Attention** This is a public forum