Recent

Author Topic: Remote debugging using simavr or simulavr  (Read 7286 times)

ccrause

  • Hero Member
  • *****
  • Posts: 845
Remote debugging using simavr or simulavr
« on: June 28, 2017, 06:53:11 am »
I am trying to debug AVR code from inside Lazarus 1.8.0 RC2 (Linux Mint 64 bit) using either simavr or simulavr to simulate the processor. The simulator is started first and runs in the background:
Code: [Select]
~/simavr/simavr/run_avr -g -m atmega328p -v -f 16000000 -t -v  ~/fpc/fpc-avr/src/examples/intmath/intmathtest.elf
The setup I've tried in Lazarus is as follows:
Change debugger type to GDB remote debugger.
Enter path to avr-gdb executable.
Set Debugger_Remote_Port as 1234 (default for simavr).
Pass a file to avr-gdb to load elf by setting Debugger_Startup-Options to -x gdbinitfile (couldn't get Lazarus to pass the elf file to avr-gdb in a different way).

Content of gdbinit file:
file ~/fpc/fpc-avr/src/examples/intmath/intmathtest.elf
target remote :1234


When I press run in Lazarus I get an initialization message (see attachment Lazarus init message 1.png] indicating that avr-gdb started OK.  If I then click OK, an error message pops up saying GDB doesn't support async mode.  I can debug outside Lazarus using avr-gdb, either in normal or mi-async mode without issues.  I've also used ddd as debugger with avr-gdb and it worked.

Any help on how to configure the debugger in Lazarus to use remote debugging with avr-gdb?

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 9794
  • Debugger - SynEdit - and more
    • wiki
Re: Remote debugging using simavr or simulavr
« Reply #1 on: June 28, 2017, 10:46:24 pm »
Well, if gdb for your platform does not support this, then there is a problem.
Maybe a newer gdb will support this.

Without gdb async mode, Lazarus can not talk to gdb, while your app runs.

So if you try to change a breakpoint, or stop/pause the app, or any other debug action, while your app runs (not already stopped at a breakpoint) then the debugger will fail.

-----------------
No guarantee, but you can try this:
components\lazdebuggergdbmi\gdbmiserverdebugger.pas
line 120 TGDBMIServerDebuggerCommandInitDebugger.DoExecute
Code: Pascal  [Select][+][-]
  1.   if not TGDBMIDebugger(FTheDebugger).AsyncModeEnabled then begin
  2.     SetDebuggerErrorState(GDBMiSNoAsyncMode);
  3.     FSuccess := False;
  4.     exit;
  5.   end;
  6.  
comment that block of code. and rebuild the IDE.

This will disable the check, but I am not sure if the debugger will work.

If it does, see above, it will break, if you toggle breakpoints.

So if it does work, you must
- set all breakpoint, before you run your app (or while stopped at a breakpoint, or stopped after stepping)
- never use the pause or stop button
- disable the debugger hint, or never trigger it, while the app is running

ccrause

  • Hero Member
  • *****
  • Posts: 845
Re: Remote debugging using simavr or simulavr
« Reply #2 on: June 29, 2017, 07:14:07 am »
Thanks for the hint of where to look Martin.  I can manually change the async mode in avr-gdb, but it has to happen before connecting to the remote target.  Will look into the initialize sequence in the Lazarus debug manager at a later stage.

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 9794
  • Debugger - SynEdit - and more
    • wiki
Re: Remote debugging using simavr or simulavr
« Reply #3 on: June 29, 2017, 12:48:43 pm »
In the debugger opts, you can give command-line-args for gdb.

Also in the "debug output" window you can monitor the communication with gdb, and then search the source where the command is issued.

You can also compile the IDE with and of those defines
Code: [Select]
DBG_WARNINGS
DBG_VERBOSE
DBG_DISASSEMBLER
DBG_VERBOSE_BRKPOINT
DBG_STATE
DBG_EVENTS
DBG_DATA_MONITORS
DBG_LOCATION_INFO
DBG_BREAKPOINT
DBG_CMD_ECHO
DBG_CMD_ECHO_FULL
DBGMI_QUEUE_DEBUG
DBGMI_TYPE_INFO
DBGMI_WITH_DISASS_OVERFLOW
DBG_WITH_DEBUGGER_DEBUG
DBG_WITH_GDB_WATCHES
DBG_THREAD_AND_FRAME
DBGMI_TIMEOUT_DEBUG

Then you either need to run the IDE with --debug=logfile and tail the logfile.
Or compile the IDE with -WC so it will have a console (DOS) window, and you can watch the output.

I recommend
DBG_CMD_ECHO  and DBGMI_QUEUE_DEBUG

The latter gives you the classname of the class sending instructions

ccrause

  • Hero Member
  • *****
  • Posts: 845
Re: Remote debugging using simavr or simulavr
« Reply #4 on: June 29, 2017, 05:56:37 pm »
It seems as if I'm making some progress.  Previously I tried to connect to the target and load the executable in a gdb init file, which first loaded the symbols and connected to the remote target, before the Lazarus debug manager has issued the async mode commands.

I've now removed all the custom commands I've used before and and the debugger gets farther with the initialization process.  The next issue I've encountered is that Lazarus apparently assume the elf file has no extension, while ppcrossavr seems to automatically add the .elf file extension, as can be seen by the last message in the debug output:
Code: [Select]
(gdb)
<-file-exec-and-symbols "/home/christo/fpc/fpc-avr/src/examples/intmath/intmathtest">
^error,msg="/home/christo/fpc/fpc-avr/src/examples/intmath/intmathtest: No such file or directory."
(gdb)
<kill>
Tried changing the target file name under project options to intmathtest.elf, but then the compiler names the elf intmeathtest.elf.elf.  My work-around for now is to rename the produced elf file by hand after compiling in Lazarus project.  This way the debugger proceeded further, but then couldn't find a PID:
Code: [Select]
(gdb)
<info pid>
&"info pid\n"
&"Undefined info command: \"pid\".  Try \"help info\".\n"
^error,msg="Undefined info command: \"pid\".  Try \"help info\"."
(gdb)
<info proc>
&"info proc\n"
&"Not supported on this target.\n"
^error,msg="Not supported on this target."
(gdb)
<info threads>
&"info threads\n"
~"  Id   Target Id         Frame \n"
~"* 1    Thread <main>     main () at ../intmathtest.pp:31\n"
^done
(gdb)
<kill>
This kind of make sense on an embedded target, but on line 5013 in gdbmidebugger.pp it sets an error if no PID is found. Perhaps the PID check should be ignored for embedded targets?

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 9794
  • Debugger - SynEdit - and more
    • wiki
Re: Remote debugging using simavr or simulavr
« Reply #5 on: June 29, 2017, 08:22:30 pm »
Indeed the remote debugger should not need a pid.

So the PID finding code could be refactored to
public TGDBMIDebuggerCommandStartDebugging.DetectPID(): boolean; virtual;

and be overwritten in remote debugger.

The boolean value indicates success, so the error code stays in place, but depends on the result.


ccrause

  • Hero Member
  • *****
  • Posts: 845
Re: Remote debugging using simavr or simulavr
« Reply #6 on: June 29, 2017, 10:30:09 pm »
So the PID finding code could be refactored to
public TGDBMIDebuggerCommandStartDebugging.DetectPID(): boolean; virtual;

and be overwritten in remote debugger.
Thanks for the tip Martin.  I followed the approach you described, and had to also assign a value to TargetInfo^.TargetPID because it gets checked at a later stage again for a 0 value:
Code: Pascal  [Select][+][-]
  1.   // no PID found
  2.   if DetectPID then
  3.     SetDebuggerErrorState(Format(gdbmiCommandStartMainRunNoPIDError, [LineEnding]))
  4.   else
  5.     TargetInfo^.TargetPID := -1;
This gets the debugger running, although there are some other issues I have noticed.  At least I can do basic debugging now.

Thanks for the help.

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 9794
  • Debugger - SynEdit - and more
    • wiki
Re: Remote debugging using simavr or simulavr
« Reply #7 on: June 29, 2017, 10:56:11 pm »
When/If you got a patch, please report it to the bugtracker.

About TargetPID :=-1

How many <>0 checks are there?

The one in line 5122 is not needed, it is 15 lines after RunToMain, and that is where the TargetPID was checked already.
[1]

The check in TGDBMIDebugger.InterruptTarget actually should see a 0. InterruptTarget must not use the TargetPID, if it is not set.

Couldn't find any other.


---
[1]
Actually it can be reached, if FDidKillNow is true and state not dsStop.
Not sure that can happen.
So for this case the check can be replaced in 5122
if FDidKillNow then setError.... exit;

ccrause

  • Hero Member
  • *****
  • Posts: 845
Re: Remote debugging using simavr or simulavr
« Reply #8 on: June 30, 2017, 09:41:08 am »
When/If you got a patch, please report it to the bugtracker.

I will do some more checking this weekend before submitting a patch.  The checks you have mentioned may solve some of the other problems I have noticed.

Thanks for the assistance.

ccrause

  • Hero Member
  • *****
  • Posts: 845
Re: Remote debugging using simavr or simulavr
« Reply #9 on: July 01, 2017, 02:52:48 pm »

 

TinyPortal © 2005-2018