Author Topic: Debugging with gdb and bare metal target, prevent SE issuing a reset?  (Read 4799 times)

rowbearto

  • Senior Community Member
  • Posts: 2335
  • Hero Points: 132
I'm working with SE using gdb to try to debug my ARM bare metal target using a J-Link debug probe (much faster than openocd which I discussed in a previous post).

Unfortunately SE is issuing a reset to my target after it loads my program, and this is messing up the debug session.

I have configured my gdb to run my custom gdbinit file which does this:

Code: [Select]
set verbose on
# Below connects to a special "gdbserver" which controls my bare-metal target
target extended-remote aaa.bbb.ccc.ddd:2331
monitor reset
monitor halt
load my_program.axf
source post_load.gdb

The problem occurs after this gdbinit is executed, SE is issuing a reset command to my target and this is screwing up the debug session. I already issue the reset before loading the program in my gdbinit.

When I was using openocd (a different debug probe) to debug, I was able to override this reset in the openocd config to not actually perform a reset, and I was able to debug my bare metal target.

But when using the J-Link debugger, I can't find a way to override this reset in the J-Link configuration. Since I can't do that, I would like a way to tell SE not to issue this reset command.

The above I tried using the "Debug" option in my build configuration.

I also tried Debug->Attach Debugger->Attach to running process(GDB)

But this method has some issues:

1) The dialog asks for a PID. My target is not linux, it is a bare metal target with a special gdbserver that is debugging the lone process running on a microcontroller.
2) I did provide my IP and port in "connect via socket" and provided my special gdb config in "gdb configuration", however after clicking "OK", SE locks up for a while before issuing error "Error starting debugger: GDB returned an error attaching to the remote process 'Don't know how to attach. Try 'help target''"

Note that Eclipse for embedded (https://projects.eclipse.org/projects/iot.embed-cdt) provides more control about how gdb runs. I have attached 2 screenshots. It shows that you can tell eclipse to tell gdb to:

1) reset/not reset before loading
2) issue custom gdb commands after the reset
3) load/not load symbols
4) load/not load executable
5) reset/not reset after loading
6) issue custom gdb commands after loading
7) set/not set a breakpoint at main
8) continue or not continue

It would be nice if SE offered this level of control. I'm particularly interested in disabling the reset at 5) above.
« Last Edit: September 13, 2020, 11:42:32 PM by rowbearto »

Dennis

  • Senior Community Member
  • Posts: 3961
  • Hero Points: 517
Re: Debugging with gdb and bare metal target, prevent SE issuing a reset?
« Reply #1 on: September 14, 2020, 02:08:22 PM »
What is in post_load.gdb ?

I am not sure what command you are referring to when you say we are issuing a reset.  Have you tried capturing the interaction by turning on def_debug_logging (the output goes to <config>/logs/debug.log)

rowbearto

  • Senior Community Member
  • Posts: 2335
  • Hero Points: 132
Re: Debugging with gdb and bare metal target, prevent SE issuing a reset?
« Reply #2 on: September 14, 2020, 02:16:32 PM »
post_load.gdb has the following contents:

Code: [Select]
# Set the vector table base address to 0
set *((int *) 0xe000ed08)=0

# Initialize the stack pointer to the first location of the vector table
set $sp=*((int *) 0)
set $msp=*((int *) 0)
set $psp=*((int *) 0)

# Initialize the PC to what is stored at the 2nd entry in the vector table
set $pc=*((int *) 4)

It needs to run after the load in order to set the stack pointer to the contents loaded from address 0 (1st entry in vector table), and also to set the pc register to the 2nd entry in the vector table. So it is required to run after the load so that the 1st and 2nd entries in the vector table are actually there (they get there from loading).

I see that a reset is occurring from the logs in my gdbserver, they are indicating that a reset happens.

I will turn on def_debug_logging (how to do that, set it to 1?). I was not aware of this.
« Last Edit: September 14, 2020, 02:19:18 PM by rowbearto »

Dennis

  • Senior Community Member
  • Posts: 3961
  • Hero Points: 517
Re: Debugging with gdb and bare metal target, prevent SE issuing a reset?
« Reply #3 on: September 14, 2020, 02:18:17 PM »
Macro > Set macro Variable... > def_debug_logging = 1

Remember to turn it off when you are done.

rowbearto

  • Senior Community Member
  • Posts: 2335
  • Hero Points: 132
Re: Debugging with gdb and bare metal target, prevent SE issuing a reset?
« Reply #4 on: September 14, 2020, 02:28:27 PM »
I just uploaded my debug.log to support.

Starting to analyze it now...

Thanks Dennis!

rowbearto

  • Senior Community Member
  • Posts: 2335
  • Hero Points: 132
Re: Debugging with gdb and bare metal target, prevent SE issuing a reset?
« Reply #5 on: September 14, 2020, 02:32:33 PM »
Uploaded a new debug log, debug2.log. In the first one I had the wrong path to my post_load.gdb and gdb didn't find it. That is corrected in debug2.log

rowbearto

  • Senior Community Member
  • Posts: 2335
  • Hero Points: 132
Re: Debugging with gdb and bare metal target, prevent SE issuing a reset?
« Reply #6 on: September 14, 2020, 02:41:50 PM »
I suspect it is the "exec-run" command issued from SlickEdit that triggers a reset? At this point I only want to continue, not run, so maybe an "exec-continue" would be more appropriate for my use case?

rowbearto

  • Senior Community Member
  • Posts: 2335
  • Hero Points: 132
Re: Debugging with gdb and bare metal target, prevent SE issuing a reset?
« Reply #7 on: September 14, 2020, 02:47:04 PM »
You can see from my 2nd screenshot of the eclipse debug configuration it offers an option to continue (or not continue). So I think eclipse is using "continue" and not "run" in this case and that is why it works there.

Dennis

  • Senior Community Member
  • Posts: 3961
  • Hero Points: 517
Re: Debugging with gdb and bare metal target, prevent SE issuing a reset?
« Reply #8 on: September 14, 2020, 10:02:38 PM »
Why not attach using Debug > Attach Debugger > Attach to Remote Process..., since that is in essence, exactly what you are doing?

We do have an open feature request to have an option to specify a post-connect GDB script to execute.  In the meantime, you can use the "debug-send-command" command to send a "source" command to GDB to have it run a series of commands.   Example:  After attaching to the remote target, from the SlickEdit command line, "debug-send-command source /home/team/post-connnect.gdb"

Code: [Select]
set verbose on
monitor reset
monitor halt
load my_program.axf
source post_load.gdb

rowbearto

  • Senior Community Member
  • Posts: 2335
  • Hero Points: 132
Re: Debugging with gdb and bare metal target, prevent SE issuing a reset?
« Reply #9 on: September 15, 2020, 01:06:50 AM »
I did initially try "Attach to remote process" as mentioned in my first post. It freezes for a long time and finally comes back with error:

Quote
Error starting debugger: GDB returned an error attaching to the remote process

Don't know how to attach. Try "help target"

And them I am not in the "debugger mode".

I uploaded the log to support as "debug-attach.log".

I did specify my gdb server's IP and port in the "Connect via socket:".

I think the problem is because SlickEdit is sending gdb the command: "target-attach 14241"

The 14241 is the "PID" that I had in the "Attach to remote process" dialog, left over from a previous debug session.

So then I decided maybe I should leave the "PID" field blank.

When I leave PID blank in the dialog that I can connect to the target! I suppose by not providing a PID it does not do the "target-attach 14241".

Is there any way to automate all this in a macro? So 1 macro that does the Debug->Attach Debugger->Attach to remote process, fills in my desired parameters (from the macro) followed by issuing my "debug-send-command source script.gdb"?

Dennis

  • Senior Community Member
  • Posts: 3961
  • Hero Points: 517
Re: Debugging with gdb and bare metal target, prevent SE issuing a reset?
« Reply #10 on: September 15, 2020, 02:09:40 PM »
Debugger > Attach Debugger > Attach to Remote process... supports dialog retrieval, so your previous parameters will be already filled in.  You can also use F7 and F8 for dialog history to swap in previous sets of parameters.

You could write a short macro that calls both commands:

Code: [Select]
_command void debug_remote_gdb_and_source(_str file="")
{
     debug_remote("gdb");
     debug_send_command("source ":+file);
}

rowbearto

  • Senior Community Member
  • Posts: 2335
  • Hero Points: 132
Re: Debugging with gdb and bare metal target, prevent SE issuing a reset?
« Reply #11 on: September 15, 2020, 02:20:58 PM »
Thanks Dennis! I will try that.

I notice that when I do the "Attach to Remote process" that a new window pops up with the output of "say" commands. I attached a screenshot. Probably need to remove "say" in the macros that implement this.

Feature request #1: Would be nice if there was a way to populate the dialog from the debug_remote() macro.

Feature request #2: Would be nice if SlickEdit could support "debug configurations" like eclipse does. In a debug configuration I can fill in all my parameters such as executable, remote gdbserver IP/port, gdb configuration, post_load script (see screenshots in my first post). Then I can start a debug session by launching a "debug configuration".

Stretch feature request #3: In eclipse I can debug multiple cores simultaneously. eclipse has "launch groups" where you can specify multiple "debug configurations" to launch simultaneously. You can get a stack trace for each different core, select which core to step/continue/etc.

Dennis

  • Senior Community Member
  • Posts: 3961
  • Hero Points: 517
Re: Debugging with gdb and bare metal target, prevent SE issuing a reset?
« Reply #12 on: September 15, 2020, 09:36:54 PM »
#0) I'll find and destroy that rogue 'say' statement.

#1) Does the dialog not get re-filled with your last settings?
      Does F7 and F8 not work to get previous settings?

#2) I believe there is an outstanding feature request for that.
       F7 and F8 (dialog history retrieval) is the workaround.
       I would like if we had a clearer GUI mechanism for dialog history retrieval.

#3) Not a stretch at all.  You can already do that.
       Just Debug > Attach Debugger > Attach to remote process... multiple times
       You get multiple debugger sessions which you can switch between
       using the Debug Sessions tool bar.
       OK, that does not launch them simultaneously.

rowbearto

  • Senior Community Member
  • Posts: 2335
  • Hero Points: 132
Re: Debugging with gdb and bare metal target, prevent SE issuing a reset?
« Reply #13 on: September 15, 2020, 09:50:19 PM »
#0) Thanks

#1) I want more automation such that every time I want to change what I execute I don't have to do the Debug->Attach Debugger->Attach to Remote Process(GDB) and then press F7/F8. That is a manual process, lots of mouse clicks, key presses and potentially error pone. By putting all this into a macro I can simply run 1 macro and perhaps bind it to a key. For different executables/differing macros, I can bind each to a different key such that I simply have to press the specific bound key to run desired executable. This would be much more convenient and less error prone.

#3) That would require many mouse clicks and key presses to launch each different remote process. With eclipse and launch groups I can simply specify a launch group to run and run it without having to keep going to the menu multiple times and redo F7/F8. The "launch group" is pre-saved with all the desired debug configurations so very easy to launch it with minimal mouse-clicks/keypresses.

rowbearto

  • Senior Community Member
  • Posts: 2335
  • Hero Points: 132
Re: Debugging with gdb and bare metal target, prevent SE issuing a reset?
« Reply #14 on: September 16, 2020, 08:39:26 PM »
So I've gone through the exercise of creating macros and trying to automate as much as possible. I found a few annoyances, maybe they can get fixed. Also want to share how I did it for any feedback.

My macro basically does as "debug_remote()" followed by a "debug_send_command()", thank you Dennis for this suggestion!

There are some annoyances to this that could perhaps get changed?

1) Every time I want to debug by running my macro, the debug_remote() always pops up the dialog box for attaching, and I have to either click OK or press <ENTER>. Would be nice if there was a way to not pop up this dialog box and I didn't have to click OK/press <ENTER> every time I want to debug.

2) After I run debug_send_command(), another dialog box comes up with the output of my sourced gdb script. Again I have to either click OK or press <ENTER>. Would be nice if this could be avoided. This output shows up in SE's output tab anyway.

Ideally I'd like to run my macro and next thing I see is my code stopped at my debugged code's main(). But now I have to always 2 times press <ENTER> (or click OK) to get past 2 dialog boxes.

I'm used to in eclipse when I start my debug config that it goes directly to main() and I don't have to press <ENTER> 2x for every debug session.

Another annoyance is automating running 3 different executables in SE. Each time the attach dialog comes up, I don't want to have to F7/F8 to choose the right executable. I found that I can automate this if I add the gdb command "symbol-file my_program.axf" into my gdb script that gets sourced via debug_send_command(). This basically overwrites whatever executable was placed into SE's "attach" dialog. So in my case SE is wasting time loading the symbols that are in the attach dialog as I'm just going to overwrite them anyway. I tried removing the "File:" entry in the attach dialog, but it generates a warning and then there were some debugging issues after that.

For reference, here is how I have automated in SE:

a) I have 3 different executables that I would to run, so I have 3 different macros (bound to 3 different keys). Each macro does debug_remote()/debug_send_command(). The difference between the 3 is the argument that is passed debug_send_command(), I have 3 different gdb scripts depending on the executable, as the "load" (and "symbol-file") gdb commands are in my gdb script.

b) So far the only thing I may have to change in the "attach" dialog box is the IP address of my target. We have several different target systems that can be "reserved" by different developers. So when I arrive each day I may be using a different target system. So maybe once daily I have to enter the IP of my system.

Also for reference, here is how I have automated this in eclipse:

1) I have 1 "template" debug configuration that is stored in a .launch file.
2) I created a python script that takes on the command line the IP of a remote system (or a well known short alias), and it generates 3 different eclipse .launch files (debug configs), with the proper IP address of target and also the path to each executable.

In the debug config, it specifies the executable for both symbols and loading, so eclipse doesn't load the symbols 2x like I do in eclipse.

I'm also able to use an "alias" for my IP address, some short well known names that I supply to my script that converts the debug config template to the actual debug config files that eclipse uses. In the SE attach dialog box, it doesn't know anything about my aliases, so when I need to change IPs I need to find the actual IP address corresponding to the alias. I don't have the IP addresses memorized (I use some host names that are rather long), but I do have the aliases memorized.

So if SE were to implement debug configs, would be nice if they were individual files (similar to an eclipse .launch file) with all the debug parameters so I could script having a template and generating the actual debug configs that SE would use. The script would overwrite the template with proper IP address and executable.

Eclipse's debug configs allow to specify gdb commands (including sourcing a script) before/after loading. Would be nice if a future SE debug config could do that.
« Last Edit: September 16, 2020, 10:38:15 PM by rowbearto »