question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Broken `value` field in a `VariablesResponse`, should be of type string, not array

See original GitHub issue

Hi, I’m trying to use this debugger as a debug adapter with Emacs’ dap-mode. I realize that this is not the primary purpose of code-debug, but it’s ‘officially’ supported by dap-mode. I’m using gdb v. 9.2 as debugger. dap-mode does some auto-download-magic for the debug adapter, so I did not download a specific version. But when looking into the downloaded extensions.vsixmanifest file, it looks to me like I’m using version 0.26.0:

<Identity Language="en-US" Id="debug" Version="0.26.0" Publisher="webfreak" />

I encountered a crash in dap-mode, which I think I traced back to a problem in code-debug.

I set dap-mode to print all I/O with the debug adapter (i.e., code-debug), and below is (some part of) what I see once a breakpoint is hit. This looks Okay so far - dap-mode is first requesting some info about the top stack frame, and then requests the local variables inside that stack frame. The response looks Okay to me.

Sending: 
{
  "command": "scopes",
  "arguments": {
    "frameId": 1
  },
  "type": "request",
  "seq": 14
}
Received:
{
  "seq": 6865,
  "type": "response",
  "request_seq": 14,
  "command": "scopes",
  "success": true,
  "body": {
    "scopes": [
      {
        "name": "Local",
        "variablesReference": 1001,
        "expensive": null
      }
    ]
  }
}



Sending: 
{
  "command": "variables",
  "arguments": {
    "variablesReference": 1001
  },
  "type": "request",
  "seq": 15
}
Received:
{
  "seq": 6866,
  "type": "response",
  "request_seq": 15,
  "command": "variables",
  "success": true,
  "body": {
    "variables": [
      {
        "name": "this",
        "value": "<args>",
        "variablesReference": 132072
      },
      {
        "name": "tripNotification",
        "value": "Ref@0x7ffffffecdb0",
        "variablesReference": 132073
      },
      {
        "name": "incoming",
        "type": "std::shared_ptr<rtd::CIncomingRBLData>",
        "value": "<unknown>",
        "variablesReference": 132074
      },
      {
        "name": "tripData",
        "type": "rtd::CRBLTripData",
        "value": "<unknown>",
        "variablesReference": 132075
      },
      {
        "name": "avmError",
        "value": "Ref@0x962a068",
        "variablesReference": 132076
      },
      {
        "name": "sanityCheckResult",
        "type": "EFAPTKernelLib::SAVMError",
        "value": "<unknown>",
        "variablesReference": 132077
      },
      {
        "name": "processingTime_msec",
        "value": "135841511",
        "variablesReference": 0
      }
    ]
  }
}

The crash now happens when I try to expand the this variable. This is the I/O for that request:

Sending: 
{
  "command": "variables",
  "arguments": {
    "variablesReference": 132072
  },
  "type": "request",
  "seq": 16
}
Received:
{
  "seq": 6867,
  "type": "response",
  "request_seq": 16,
  "command": "variables",
  "success": true,
  "body": {
    "variables": [
      {
        "name": "[err]",
        "value": [
          {
            "name": "m_lMessageCount",
            "value": "0",
            "variablesReference": 0
          },
          {
            "name": "m_accumulatedTime_msec",
            "value": "8675833939940",
            "variablesReference": 0
          },
          {
            "name": "m_ptKernelVersion",
            "value": "Object",
            "variablesReference": 132079
          },
          {
            "name": "m_ptrRblTripDataBuilder",
            "value": "std",
            "variablesReference": 0
          }
        ],
        "variablesReference": 0
      }
    ]
  }
}

Those variables look wrong to me. The DAP specification for the Variable type specifies that the value member must be a string, not a list.

Please let me know if there is anything I can do to help debug this. My (completely unsubstantiated) feeling is that this might be related to #342 .

Issue Analytics

  • State:open
  • Created a year ago
  • Comments:11 (1 by maintainers)

github_iconTop GitHub Comments

1reaction
browntscommented, May 10, 2022

Is this also related to any of the other variable printing issues #261 #248 #238?

These don’t appear to be the same issue as the main issue identified here. You’d see “<args>” shown next to a local variable if it was executing the “arg” logic as described above. However, I do believe that #261 is the same as the secondary issue described by @tinloaf in a follow-up post here, where it displays “std” for one of the values. That is due to the fact that the Debug Adapter’s expression parser (i.e., gdb_expansion.ts) is not sophisticated enough to handle something like the following (taken from the example in #261):

15-data-evaluate-expression "aeew"
GDB -> App: {"token":15,"outOfBandRecord":[],"resultRecords":{"resultClass":"done","results":[["value","std::vector of length 1, capacity 1 = {2}"]]}}

I’m not sure if there is a published syntax format for these expressions or not. If so, the builtin parser could be updated to account for them. However, using the prettyPrinters option for valuesFormatting is likely the best solution and probably should be made the default setting to avoid future issues surrounding the sub-optimal parseText default.

1reaction
browntscommented, May 10, 2022

@WebFreak001, I created a test example based on the similar issue described in #197. From there, I was able to duplicate the problem reported by @tinloaf. I’ve attached an example application. launch.json, screen capture, trace, etc., in case someone wants to repeat this procedure. After I looked into this, it appears that any parameter passed as a pointer is being treated as an array. This is due to the check in gdb_expansion.ts which creates an ‘ExtendedVariable’ for pointer parameters (i.e., arguments). Additionally, the subsequent expansion logic in mibase.ts, appears to treat this like an array. Looking back at the history of when ‘ExtendedVariable’ was added, it appears it was an attempt to address issues with *argv[] in C (see the commit). This doesn’t seem correct though as this logic is used for any parameter passed as a pointer to a function. I tried commenting out the special “arg” logic in gdb_expansion.ts, and that works as well as the ‘prettyPrinters’ configuration does.

-			if (extra && MINode.valueOf(extra, "arg") == "1") {
-				ref = variableCreate(getNamespace("*(" + name), { arg: true });
-				val = "<args>";
-			} else {
				ref = variableCreate(getNamespace("*" + name));
				val = "Object@" + val;
-			}

I’m hoping you might remember the history behind this. Maybe this is just obsolete at this point and can be removed. I also didn’t see any other usage of the ‘ExtendedVariable’ except for this special case, so it’s possible that all of that processing surrounding it in mibase.ts might also be able to be removed, if nothing else uses it.

launch.json
        {
            "name": "Debug",
            "type": "gdb",
            "request": "launch",
            "target": "union_test",
            "cwd": "${workspaceRoot}",
            "valuesFormatting": "parseText"
        }
VSCode Screen Capture

union_test

C Source File
#include <stdio.h>

union example
{
    struct common
    {
        enum
        {
            TYPE_A,
            TYPE_B
        } id;
    } common;

    struct type_a
    {
        struct common c;
        int a_specific_data;
    } a;

    struct type_b
    {
        struct common c;
        int b_specific_data;
    } b;
};

static void foo (const union example *const ex)
{
    switch (ex->common.id)
    {
        case TYPE_A:
            printf("TYPE_A\n");
            break;
        case TYPE_B:
            printf("TYPE_B\n");
            break;
    }
}

int main(int argc, char* argv[])
{
    union example my_example;
    my_example.a.c.id = TYPE_A;
    my_example.a.a_specific_data = 0;
    foo(&my_example);
    return 0;
}
VSCode <-> Debug Adapter Trace
{"command":"scopes","arguments":{"frameId":1},"type":"request","seq":10}
{"seq":53,"type":"response","request_seq":10,"command":"scopes","success":true,"body":{"scopes":[{"name":"Local","variablesReference":1000,"expensive":false}]}}

{"command":"variables","arguments":{"variablesReference":1000},"type":"request","seq":11}
{"seq":56,"type":"response","request_seq":11,"command":"variables","success":true,"body":{"variables":[{"name":"ex","value":"<args>","variablesReference":1001}]}}

{"command":"variables","arguments":{"variablesReference":1001},"type":"request","seq":13}
{"seq":62,"type":"response","request_seq":13,"command":"variables","success":true,"body":{"variables":[{"name":"[err]","value":[{"name":"common","value":"Object","variablesReference":1002},{"name":"a","value":"Object","variablesReference":1004},{"name":"b","value":"Object","variablesReference":1006}],"variablesReference":0}]}}
Read more comments on GitHub >

github_iconTop Results From Across the Web

What is "not assignable to parameter of type never" error in ...
The reason was that the array was initialised with also the option of an empty array. Typescript saw a push to a type...
Read more >
The 10 Most Common JavaScript Issues Developers Face
If you need help figuring out why your JavaScript isn't working, consult this list of the 10 most common JavaScript issues from a...
Read more >
JavaScript data types and data structures - MDN Web Docs
String methods create new strings based on the content of the current string — for example: A substring of the original using substring()...
Read more >
JavaScript Split – How to Split a String into an Array in JS
The splitter can be a single character, another string, or a regular expression. After splitting the string into multiple substrings, the split ...
Read more >
Expression language methods - IBM Cloud Docs
syntax is not required. The following sections describe methods you can use to process values. They are organized by data type: Arrays; Date...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found