Recent

Author Topic: How reusable are the Lazarus components related to debugging ?  (Read 3287 times)

guest58172

  • Guest
How reusable are the Lazarus components related to debugging ?
« on: January 19, 2019, 07:32:15 pm »
I wonder if I could replace Dexed debugger by something using LazDebugger components, esp all the non visual stuff. In a first time this is a general question.

The worst part of it is probably the parsing which I suppose is better in Laz components.

So you, who wrote or participated to LazDebugger development, what do you think ? Any stopper in sight ?

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 9791
  • Debugger - SynEdit - and more
    • wiki
Re: How reusable are the Lazarus components related to debugging ?
« Reply #1 on: January 19, 2019, 08:02:03 pm »
"LazDebugger" is not very specific.

I assume you talk of the backend to the debugger. And about GDB.

So then you probably mean LazDebuggerGDBMI.
Yet there is also LazDebuggerFp (with no need for gdb, and the potential to be adapted for other languages than pascal)

LazDebuggerGDBMI is the interface to gdb. Most of it is tailored for pascal expressions, and some is specific to fpc (such as searching partentfp, which is an fpc implementation detail for nested procedures.

You can probably reuse some parts of LazDebuggerGDBMI.

There is a tool RunGdbmi, in one of the subfolders, that allows to compile a small test app, and run it in many version of gdb, and send a list of gdb commands. You can then (import to excel/calc) compare the results, and find what you look for in gdb responses.

LazDebuggerGDBMI has a system of a command queue. Allowing each command (eg an watch eval) to communicate with gdb, without interruptions of other commands. This is used so a command can set the context (select thread and frame), and then read data in that context.

LazDebuggerLLDB has a first attempt for an alternative queue, which
- is event driven (no Application.ProcessMessages)
- allows to mix communication of several commands. (the context will be handled outside the command/instruction)
  However this is all new, and still needs a bit of tuning.

If you want to stay with gdb, feel free to ask more detailed questions.



You may want to have a look at LazDebuggerFp . (fpdebug)

This is a (almost) generic dwarf debugger. (There may be some refactoring ahead, but it should be ok)
**EDIT: it is NOT case-sensitive

For this you need:
- Your integration into your IDE: See LazDebuggerFp. This is a small package. Easy to adapt.
- In FpDebug, there are 2 file to look at
  FpPascalBuilder: represent the results.
  FpPascalParser: read a pascal expression and get the result
Both should be easy to replace.

Note that the generic dwarf classes have some bits of fpc dyn-array handling left in them. This is supposed to move to the Fpc specific dwarf unit. (Which is only activated if explicitly used)



Changes ahead....

For all debuggers: The ability to deal with more than one breakpoint being hit (2 breakpoints at the same location (watchpoint + break OR address break + source:line break), or 2 threads hitting at the same time)

The general API/Interface may need some tuning as well. But that can be communicated, if it is known that you relay on it.

In FpDebug:
The internal referencing between various dwarf specific classes. (current circular refs should go...)

More details depending on which way you want to go....
« Last Edit: January 19, 2019, 08:15:02 pm by Martin_fr »

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 9791
  • Debugger - SynEdit - and more
    • wiki
Re: How reusable are the Lazarus components related to debugging ?
« Reply #2 on: January 19, 2019, 08:39:36 pm »
If you are looking for gdb parsing stuff. Start with TGDBMINameValueList (assuming you use the MI interface).

Find where it is used, and how the data is processed from there.

guest58172

  • Guest
Re: How reusable are the Lazarus components related to debugging ?
« Reply #3 on: January 21, 2019, 09:29:28 am »
Thanks, your description is rather encouraging. For arrays, the D ones work in GDB since it supports D officially. Otherwise yes it's DWARF debugger... D tooling is a bit inconsistent with that. Under windows that's a mess i don't want to deal with.

Now i also remember that last time i tried to write a correct GDBMI parser the main issue encountered was that my process didn't get full answers from GDB. I've seen that Laz uses a special process derived from TAsyncProcess, probably because of the same problem... gotta look at this as well.

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 9791
  • Debugger - SynEdit - and more
    • wiki
Re: How reusable are the Lazarus components related to debugging ?
« Reply #4 on: January 21, 2019, 04:09:25 pm »
Quote
TAsyncProcess
is actually only used by LLDB (the reasons for that a different) - gdb is accessed by normal TProcess. components\lazdebuggergdbmi\cmdlinedebugger.pp
A normal TProcess means that (unless you use threads) you need Application.ProcessMessages. And that can get messy...

components\lazdebuggers\cmdlinedebuggerbase\debugprocess.pas is the answer to that. TAsyncProcess had some other issues (don't recall), so I wrote my own.

I never had "partial lines" issue. But what should be done with respect to reading lines
Code: Pascal  [Select][+][-]
  1. set width 50000
That should avoid unwanted line breaks, for most situations.

And find PseudoTerminal and use it, and
Code: Pascal  [Select][+][-]
  1. set inferior-tty

That way the programs output, will not interfere with the gdb responses.


Both cmdlinedebugger and debugprocess should be fine for being used as a baseclass.

debugprocess has not yet reached its potential. Lets dive in.

Current GDBMI has a "command object" for everything. For example for evaluating a watch, or locals, or stack.
And while the object is running it has control. It can set the stackframe and thread, and then issue the commands it needs.

Debugprocess, actually DebugInstructions, should change that.
DebugInstructions receives Instruction objects, only containing one gdb (at current lldb) command at a time. But the object has fields for desired thread and frame, and DebugInstructions then sets the frame as desired.
This should in future all DebugInstructions to re-order the received instructions, and issue less stack changes. (improve speed).
But it is a work in process.

For that reason DebugInstructions is an event emitter. The Instruction object does not wait for the result. It gets called again, when the result is available. And that means no ProcessMessages.


Quote
didn't get full answers from GDB
should not happen, except if gdb crashes (you need to first check the errors while reading from the process), or if app-output is mixed in.

You may want to look at TGDBMIDebuggerInstruction.ProcessInputFromGdb


Quote
For arrays, the D ones work in GDB
For arrays with static size, that should always be ok, arrays with dynamic size will probably depend on the dwarf version. dwarf 2 simply had no provisions to encode the length. dwarf3 has (and fpc uses that, and gdb knows how to read it / and so does fpDebug)

Quote
Under windows that's a mess
I guess D-compilers on win do not use dwarf, but PDB. So you need a diff debugger.

guest58172

  • Guest
Re: How reusable are the Lazarus components related to debugging ?
« Reply #5 on: January 22, 2019, 01:58:56 pm »
I'm surprised to learn that you use a simple TProcess.

With TAsyncProcess, I get the GDB responses during the OnReadData event. This event, generally speaking, is called either on manual flush or when a buffer is full (e.g 4096 bytes). This has for effect that responses can come in several chunks. At last a kind of timeout is necessary to detect when the response is complete.

You could do something similar to avoid the use of the infamous Application.ProcessMessages.

Or maybe the opposite, i could try to do like in Laz instead of using an async proc.

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 9791
  • Debugger - SynEdit - and more
    • wiki
Re: How reusable are the Lazarus components related to debugging ?
« Reply #6 on: January 22, 2019, 02:21:11 pm »
With TAsyncProcess, I get the GDB responses during the OnReadData event. This event, generally speaking, is called either on manual flush or when a buffer is full (e.g 4096 bytes). This has for effect that responses can come in several chunks. At last a kind of timeout is necessary to detect when the response is complete.
Well I do not know about the original TAsyncProcess.  But my replacement seems to work (with lldb though, but I do not see how that should make a diff)

I do not have the issue with not getting all the data from gdb. Maybe compare the parameters used, when creating the process. Maybe there is a difference that leads to gdb correctly flushing each line? (gdb must probably be made to believe that it acts on a console, rather than writing to a file)

Code: Pascal  [Select][+][-]
  1.       FDbgProcess.Options:= [poUsePipes, poNoConsole, poStdErrToOutPut, poNewProcessGroup];
  2.  


Quote
You could do something similar to avoid the use of the infamous Application.ProcessMessages.
That is the intention of the new DebugProcess. But it is a lot of work (if done at all) to change the current gdbmi classes to become event driven

 

TinyPortal © 2005-2018