microsoft / MIEngine

The Visual Studio MI Debug Engine ("MIEngine") provides an open-source Visual Studio Debugger extension that works with MI-enabled debuggers such as gdb and lldb.
MIT License
817 stars 218 forks source link

Base class members are not displayed correctly using natvis files (LLDB) #657

Open KazNX opened 7 years ago

KazNX commented 7 years ago

Hi,

Under MacOS with LLDB, natvis fails to resolve base class member expressions, generating an error message instead. For example, given the code:

class ClassA
{
public:
  int intVal;
};

class ClassB : public ClassA
{
public:
};

int main()
{
  ClassB b;
  b.intVal = 42;
}

ClassB will not resolve the member expression intVal when used in a natvis file.

Attached is a small example project highlighting the issue. Note that this project also highlights anonymous structure and union issues with and without natvis under LLDB (see comments at the top of main.cpp for details) reported here.

Windows 10 + CDB (Visual Studio 2017). Works as expected with and without natvis. Ubuntu 16.04 + GDB 7.11.1. Works without natvis, generates expression errors with. MacOS 10.12.6 + LLDB 370.0.42 (XCode 8.3.2 installed). Fails with or without natvis.

vscode-natvis.zip

KazNX commented 6 years ago

I've been exploring what's responsible for the bug and as far as I can tell, the issue appears to be due to discrepancies in the data returned by GDB-MI and LLDB-MI. I've run the code above using both MIs and the results are notably different.

Steps to reproduce:

  1. Debug the attached project using GDB-MI (I did this using Ubuntu).
  2. Stop at the printf() lines (breakpoint).
  3. Open the debug console and execute the following command: -exec -stack-list-locals 1
  4. Repeat the process using LLDB-MI under MacOS.

The results are as follows: GDB-MI locals: [{name=uveca,value={{{x = 1, y = 2, z = 3}, {r = 1, g = 2, b = 3}, {s = 1, t = 2, p = 3}}}},{name=uvecb,value={v = {{x = 1, y = 2, z = 3}, {r = 1, g = 2, b = 3}, {s = 1, t = 2, p = 3}}}},{name=sveca,value={{x = 1, y = 2, z = 3}}},{name=ustructa,value={{i = 42, f = 5.88545355e-44}}},{name=ustructb,value={u = {i = 1082549862, f = 4.19999981}}}]

LLDB-MI locals: [{name=uveca,value={ = { = {x = 1, y = 2, z = 3}, = {r = 1, g = 2, b = 3}, = {s = 1, t = 2, p = 3}}}},{name=uvecb,value={v = { = {x = 1, y = 2, z = 3}, = {r = 1, g = 2, b = 3}, = {s = 1, t = 2, p = 3}}}},{name=sveca,value={ = {x = 1, y = 2, z = 3}}},{name=ustructa,value={ = {i = 42, f = 0.0000000000000000000000000000000000000000000588545355}}},{name=ustructb,value={u = {i = 1082549862, f = 4.19999981}}}]

Note how LLDB0-MI output includes additional '=' signs interspersed throughout the string. These coincide with the anonymous unions. If you are parsing the results as JSON, then I can readily understand how these '=' signs will not parse.

I've been looking for where this is called from to see how this is handled and try confirm my suspicions, but I am not familiar enough with the VSCode debugger setup to find it.

pieandcakes commented 6 years ago

@KazNX You can probably start from: https://github.com/Microsoft/MIEngine/blob/master/src/MIDebugEngine/Natvis.Impl/Natvis.cs or in that folder.

pieandcakes commented 6 years ago

if gdb is working fine and it is just lldb we may need to special case it.

pieandcakes commented 6 years ago

I suspect that the issue is lldb-mi is not returning properly formatted MI commands. In this instance it should be deleting the equal sign since there is no LH value.

KazNX commented 6 years ago

@pieandcakes That was my conclusion.

KazNX commented 6 years ago

This seems fairly trivial to fix. If you are unable to move on this, can you please point out to me where in the code the results from the MI are parsed?

pieandcakes commented 6 years ago

@KazNX this is an issue in lldb-mi. If you have the lldb source code, I'd start with tools/lldb-mi/MICmdCmdVar.cpp

I will be looking into it but I haven't had time to setup a Mac to build and test different scenarios for it.

KazNX commented 6 years ago

@pieandcakes Some good news on this one; the lldb issue has been addressed by version 1.25.1. That is, the combination of anonymous unions and structs now can be displayed while debugging on MacOS using lldb. Natvis still doesn't correctly decode the member references though.

pieandcakes commented 6 years ago

@KazNX Thanks for updating us!

KazNX commented 4 years ago

I'm just wondering if anyone is going to follow up on this? Seems a fairly easy issue to address given the information above.

pieandcakes commented 4 years ago

@WardenGnaw

KazNX commented 3 years ago

Ping

dcourtois commented 1 year ago

Any news on this?? It's basically impossible to use natvis files on macOS because of this right now :/

charlietangora commented 1 month ago

There is a further issue using lldb-mi - in -var-list-children, it gives value="{...}" for a base class. Variables.cs line 275 is expecting to see no value for the base class entry.

This results in VariableNodeType being incorrectly set to something other than NodeType.BaseClass, and FullName calls incorrectly give something like DerivedVar.BaseClass, resulting in an error.

Is this something better fixed in lldb-mi, or should there be some change to Variables.cs to spot the Value of "{...}"?