I’m not sure 

> On Jun 25, 2020, at 5:08 AM, Pavel Labath <pa...@labath.sk> wrote:
> 
> On 24/06/2020 18:55, Jim Ingham wrote:
>> 
>>> On Jun 22, 2020, at 5:52 AM, Pavel Labath via Phabricator via lldb-commits 
>>> <lldb-commits@lists.llvm.org> wrote:
>>> 
>>> labath added a comment.
>>> 
>>> This seems like it could be useful in some circumstances, though for the 
>>> use cases I am imagining (bug reporting) it would be easier to just 
>>> copy-paste the terminal contents.
>>> 
>>> As for the implementation, if the intention is for this to eventually 
>>> capture all debugger output, then I am not sure if this is the right 
>>> design. I think it would be fine for python/lua interpreters as those are 
>>> invoked from the lldb command interpreter, but I have a feeling that 
>>> routing the output printed via `Debugger::PrintAsync` back to the command 
>>> interpreter would look pretty weird. It may make sense for the core logic 
>>> of this to live in the Debugger or the IOHandler(Stack) classes -- though I 
>>> am not exactly sure about that either as the Debugger and CommandIntepreter 
>>> classes are fairly tightly coupled. However, I think that would be 
>>> consistent with the long term goal of reimplementing the command 
>>> interpreter on top of the SB API (in which case the `Debugger` object 
>>> should not know anything about the command interpreter (but it would still 
>>> need to to "something" with the PrintAsync output).
>> This isn’t directly related to how much and how we should capture lldb 
>> session output, and maybe I’m misunderstanding your meaning, but I wasn’t 
>> expecting that moving the command interpreter to use SB API’s would mean the 
>> Debugger Object would know nothing about the Command interpreter.  It would 
>> know as much about the command interpreter as it does about the script 
>> interpreter, namely the Debugger holds these objects and is the one to hand 
>> them out.  For instance when the breakpoint has a bunch of commands in its 
>> command action, it would go to the debugger to evaluate those commands.  I 
>> think that’s the reasonable place from which to vend the command and script 
>> interpreters.  So it’s okay IMO for the Debugger to know a little bit about 
>> these entities.  It shouldn’t know anything about the command syntax, etc.  
>> But since it is still the vendor of these objects, it seems okay for it to 
>> have an affordance to be notified of command results.
>> 
> 
> Well, the way I was thinking about this the "Debugger" would not know
> anything about Command *or* script interpreters. It would just know how
> to "debug" -- offer a programming API without any sort of textual
> interaction with a human.
> 
> However, this may be just a naming issue. There obviously needs to be
> some object which ties all of these together the thing which "debugs"
> and the thing which interfaces this with the user -- and it's not
> unreasonable to call this thing "the Debugger".
> 
> Nevertheless I think having this separation between "core debugger
> functionality" and a "particular way of interacting with the user" can
> be very useful:
> - it can enable someone to write a fully gdb-compatible (or some other
> debugger emulation) CLI experience on top of the "debugger core". This
> CLI would not need anything from the lldb CLI, but it could make use of
> all the "core" functionality (targets, breakpoints, threads, etc.)
> - someone wanting to build a lean-and-mean debugger for some specialized
> task could just make use of the "core" debugger functionality without
> pulling in the entire CLI
> 
> I don't expect either of these things to happen in the near future (or
> at all), but I like that this design would enable that sort of thing.
> Additionally (and this is the reason why I said (lldb_private::)Debugger
> in my first comment) this organization would avoid some problematic
> circular dependencies: If lldb_private::Debugger knows about the
> "command interpreter" and the "command interpreter" uses the SB api,
> then which side of the SB boundary does the command interpreter lie? It
> can't be "inside" the API, because it needs to access it to drive the
> debugging. But it also cannot be "outside" of the SB API, because then
> lldb_private::Debugger could not know about it.
> 
> That's why I figured that lldb::SBDebugger could be the "one debugger to
> rule them all", and lldb_private::Debugger could be "demoted" to just
> the "core" debugging facilities.
> 
> But now we're getting way ahead of ourselves...


One of the things that is core functionality in the debugger is “when X 
happens, do Y”.  When I stop, do something, when I hit a breakpoint do 
something, when a new shared library is loaded (we don’t offer this affordance 
yet, but we should), etc…  Similarly the script interpreter side of lldb gets 
pretty involved in formatting data.  Both of these tasks require non-trivial 
managing.   I think it would be annoying for every debugger client to have to 
code that up themselves.  Some of that can be clearly expressed as generic 
debugger behavior (like running a condition on a breakpoint hit.)  But you also 
want a callout to more customizable behaviors.  At base, of course, these are 
just callbacks and don’t necessarily involve the script or command 
interpreters.  But there’s a lot of bits of business particular to when the 
callbacks are running CLI or Script code, and it would be annoying to have 
every client have to reimplement these.

For instance, all CLI's will want to have to have a place to store the command 
callback text in the entities that are going to use them.  They would want that 
text to be part of the object’s “description” of itself.  And probably some 
other things that I’m forgetting.  I think we could make these sockets 
sufficiently light-weight that having them in the core debugger wouldn’t have 
any practical downsides, and would make building on top of it easier.  That’s 
why I am inclined to include this part of the Command & Script interfaces in 
the CoreDebugger.

But I agree, the CoreDebugger should not include the implementation of a 
particular CommandInterpreter or a particular ScriptInterpreter, and should 
handle not having an actual CommandInterpreter present, as it can handle not 
having a ScriptInterpreter present.

I don’t see the layering problem, however.  In my view, there would be an 
abstract lldb_private::CommandInterpreter that receives text for execution 
returns results in a generic lldb_private::CommandResultObject (the current 
HandleCommand, HandleCommands).  It would provide an abstract “pretty print 
command text” call so that we could use it in the Description methods of 
lldb_private objects (for instance for breakpoints…)  It could also offer 
completion on types, filenames, variable names etc, since that’s a generic bit 
of functionality any CLI might want to use.  It might even have 
“HandleCompletion”, since that only knows that the command is text with a 
cursor…  But that’s about all.  This is clearly all within the lldb_private 
API’s.  We could probably also make “RunCommandInterpreter” sufficiently 
general that it might be worth adding that to the core functionality, and since 
this is a fairly complex bit of business because of I/O handlers and the like 
this seems worth trying.  But again, no SB API’s would be involved here.  Then 
there would be SP API’s that publish this functionality.  Again, this is just 
about storing and running the commands, so it doesn’t depend on any details of 
the interpreter.

Then for lldb, we would build a LLDBCommandInterpreter that uses the SB API’s 
to implement commands, and adds functionality like “DefineOptionGroup", 
“DefineCommand”, etc to set up commands in the command interpreter and would 
implement HandleCommand so that it could be run by the lldb_private::Debugger 
functionality.  But this would all be clearly on the outside of lldb_private.

Jim


> 
> pl

_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to