[Lldb-commits] [PATCH] D78801: [LLDB] Add class ProcessWasm for WebAssembly debugging

2020-04-26 Thread Greg Clayton via Phabricator via lldb-commits
clayborg added a comment.

So a few things here. It doesn't seem like it is necessary to create the 
WasmProcessGDBRemote and IWasmProcess. It would be fine to extend the current 
ProcessGDBRemote and ThreadGDBRemote classes. The whole reason seems to be that 
the variables (globals, locals, etc) are fetched through the GDB server API and 
that doesn't happen for other users of the protocol where this information is 
fetched via the debug info. Is this correct? You seem to have debug info and 
DWARF (since you mentioned a new DWARF expression opcode), so how do variables 
actually work? Do you use debug info? What info for variables do you need to 
fetch from the API?

It also seems that you fetch the stack backtrace via the GBB remote protocol as 
well. This would be easy to add in to the generic GDB remote protocol. This 
could also be built in at the lldb_private::Process/lldb_private::Thread API 
level where a process/thread specifies it fetches the variables and/or stack 
itself instead of letting the unwind engine do its thing. This can be really 
useful for instance if a core or minidump file that is able to store a 
backtrace so that when you don't have all the system libraries you can still 
get a good backtrace from a core file. So the backtrace part should definitely 
be part of the core LLDB logic where it can ask a process or thread if it 
provides a backtrace or not and we add new virtual APIs to the 
lldb_private::Process/lldb_private::Thread classes to detect and handle this. 
The ProcessGDBRemote and ThreadGDBRemote would then implement these functions 
and answer "yes" if the GDB server supports fetching these things.

So if you can elaborate in detail how variables work and how the stack trace 
works and exactly what needs to go through the GDB server API, we can work out 
how this should happen in LLDB. From what I understand right now I would:

- modify lldb_private::Process/lldb_private::Thread to add new virtual (not 
pure virtual) APIs that answer "false" when asked if the process/thread 
provides variables and stacks
- modify the GDB remote protocol to handle a new "qSupported" variant that asks 
if variables and stacks are supported via the API. Most GDB servers will answer 
with not supported. See 
https://sourceware.org/gdb/current/onlinedocs/gdb/General-Query-Packets.html#qSupported
- modify ProcessGDBRemote and ThreadGDBRemote to override these APIs and answer 
"true" to handling variables and stack if the server supports this.
- Modify the unwind code to ask the lldb_private::Thread if it provides a 
backtrace. If true, then skip the normal unwind and use the new APIs on 
lldb_private::Thread
- Remove the ProcessWasm code and UnwindWasm code.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D78801/new/

https://reviews.llvm.org/D78801



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


[Lldb-commits] [PATCH] D78839: [lldb-vscode] Add an option for loading core files

2020-04-26 Thread Greg Clayton via Phabricator via lldb-commits
clayborg added a comment.

You might look around for a core file in another test location and be able to 
use that. Functionality looks good to me. This could have been done with 
attachCommands before, but it is nice to have a built in and supported way to 
do this.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D78839/new/

https://reviews.llvm.org/D78839



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


[Lldb-commits] [PATCH] D78801: [LLDB] Add class ProcessWasm for WebAssembly debugging

2020-04-26 Thread Paolo Severini via Phabricator via lldb-commits
paolosev updated this revision to Diff 260216.
paolosev added a comment.

I am adding all the pieces to this patch to make the whole picture clearer; I 
thought to add a piece at the time to simplify reviews, but probably it ended 
up making things more obscure. I can always split this patch later and I need 
to refactor everything anyway.

So, the idea is to use DWARF as debug info for Wasm, as it is already supported 
by LLVM and Emscripten. For this we introduced some time ago the plugin classes 
ObjectFileWasm, SymbolVendorWasm and DynamicLoaderWasmDYLD. However, 
WebAssembly is peculiarly different from the native targets. When source code 
is compiled to Wasm, Clang produces a module that contains Wasm bytecode (a bit 
like it happens with Java and C#) and the DWARF info refers to this bytecode.
The Wasm module then runs in a Wasm runtime. (It is also possible to 
AoT-compile Wasm to native, but this is outside the scope of this patch).

Therefore, LLDB cannot debug Wasm by just controlling the inferior process, but 
it needs to talk with the Wasm engine to query the Wasm engine state. For 
example, for backtrace, only the runtime knows what is the current call stack. 
Hence the idea of using the gdb-remote protocol: if a Wasm engine has a GDB 
stub LLDB can connect to it to start a debugging session and access its state.

Wasm execution is defined in terms of a stack machine. There are no registers 
(besides the implicit IP) and most Wasm instructions push/pop values into/from 
a virtual stack. Besides the stack the other possible stores are a set of 
parameters and locals defined in the function, a set of global variables 
defined in the module and the module memory, which is separated from the code 
address space.

The DWARF debug info to evaluate the value of variables is defined in terms of 
these constructs. For example, we can have something like this in DWARF:

  0x5a88:  DW_TAG_variable
DW_AT_location  (0x06f3: 
   [0x0840, 0x0850): DW_OP_WASM_location 
0x0 +8, DW_OP_stack_value)
DW_AT_name  ("xx")
DW_AT_type  (0x2b17 "float")
[…]

Which says that on that address range the value of ‘xx’ can be evaluated as the 
content of the 8th local. Here DW_OP_WASM_location is a Wasm-specific opcode, 
with two args, the first defines the store (0: Local, 1: Global, 2: the operand 
stack) and the index in that store. In most cases the value of the variable 
could be retrieved from the Wasm memory instead.

So, when LLDB wants to evaluate this variable, in 
`DWARFExpression::Evaluate()`, it needs to know what is the current the value 
of the Wasm locals, or to access the memory, and for this it needs to query the 
Wasm engine.

This is why there are changes to DWARFExpression::Evaluate(), to support the 
DW_OP_WASM_location case, and this is also why I created a class that derives 
from ProcessGDBRemote and overrides ReadMemory() in order to query the wasm 
engine. Also Value::GetValueAsData() needs to be modified when the value is 
retrieved from Wasm memory.

`GDBRemoteCommunicationClient` needs to be extended with a few Wasm-specific 
query packets:

- qWasmGlobal: query the value of a Wasm global variable
- qWasmLocal: query the value of a Wasm function argument or local
- qWasmStackValue: query the value in the Wasm operand stack
- qWasmMem: read from a Wasm memory
- qWasmCallStack: retrieve the Wasm call stack.

These are all the changes we need to fully support Wasm debugging.

Why the `IWasmProcess` interface? I was not sure whether gdb-remote should be 
the only way to access the engine state. In the future LLDB could also use some 
other (and less chatty) mechanisms to communicate with a Wasm engine. I did not 
want to put a dependency on GDBRemote in a class like DWARFExpression or Value, 
which should not care about these details. Therefore, I thought that the new 
class WasmProcessGDBRemote could implement the IWasmProcess interface, 
forwarding requests through the base class ProcessGDBRemote which then send the 
new gdb-remote query packets. But I agree that this makes the code certainly 
more convoluted and quite ugly.

My initial idea was to keep all the Wasm-related code as much as possible 
isolated in plugin classes. Now, I guess that the next steps instead would be 
to refactor the code to eliminate the new classes WasmProcessGDBRemote and 
UnwindWasm and modify existing ProcessGDBRemote and ThreadGDBRemote instead. 
However, I am not sure if this is possible without touching also the base 
classes Process and Thread. For example, let’s consider function 
DWARFExpression::Evaluate(). There, when the DWARF opcode is 
DW_OP_WASM_location, we need to access the Wasm state.  We can get to the 
Process object with frame->CalculateProcess() and then can we assume the 
process must always be a ProcessGDBRemote if the target mac