Skip to content

Commit c8a26f8

Browse files
committed
[lldb-vscode] Send Statistics Dump in terminated event
This patch will gather debug info & breakpoint info from the statistics dump and send to DAP in terminated event. We will return full contents of statistics dump (`SBTarget.GetStatistics()`) as a JSON string. So that every time a new field being added, we will be able to capture them from DAP log without changing lldb-vscode. All the info above will be append to `statistics` field in the terminated event Test Plan Debugged a simple hello world program from VSCode. Exit debug session in two ways: 1) run to program exit; 2) user initiated debug session end (quit debugging before program exit). Check DAP log and see both debug sessions have statistics returned in terminated event. Here's an example when debugging the test program: ``` {"event":"terminated","seq":0,"statistics":"{\"memory\":{\"strings\":{\"bytesTotal\":1851392,\"bytesUnused\":905933,\"bytesUsed\":945459}},\"modules\":[{\"debugInfoByteSize\":0,\"debugInfoEnabled\":false,\"debugInfoIndexLoadedFromCache\":false,\"debugInfoIndexSavedToCache\":false,\"debugInfoIndexTime\":0,\"debugInfoParseTime\":0,\"identifier\":93901655961472,\"path\":\"/data/users/wanyi/llvm-sand/build/Debug/fbcode-x86_64/toolchain/lldb-test-build.noindex/tools/lldb-vscode/terminated-event/TestVSCode_terminatedEvent.test_terminated_event/a.out.stripped\",\"symbolTableIndexTime\":0.00067299999999999999,\"symbolTableLoadedFromCache\":false,\"symbolTableParseTime\":0.00054799999999999998,\"symbolTableSavedToCache\":false,\"symbolTableStripped\":false,\"triple\":\"x86_64--linux\",\"uuid\":\"E317E50F\"},{\"debugInfoByteSize\":833593,\"debugInfoEnabled\":true,\"debugInfoIndexLoadedFromCache\":false,\"debugInfoIndexSavedToCache\":false,\"debugInfoIndexTime\":0.012657,\"debugInfoParseTime\":0.32714500000000002,\"identifier\":93901656106336,\"path\":\"/usr/lib64/ld-2.28.so\",\"symbolTableIndexTime\":0.0017719999999999999,\"symbolTableLoadedFromCache\":false,\"symbolTableParseTime\":0.025423000000000001,\"symbolTableSavedToCache\":false,\"symbolTableStripped\":false,\"triple\":\"x86_64--linux\",\"uuid\":\"57D782C6-AF24-135E-6970-7B9D3334B91B-6CD33392\"},{\"debugInfoByteSize\":0,\"debugInfoEnabled\":false,\"debugInfoIndexLoadedFromCache\":false,\"debugInfoIndexSavedToCache\":false,\"debugInfoIndexTime\":0,\"debugInfoParseTime\":0,\"identifier\":93901654578688,\"path\":\"[vdso](0x00007ffff7ffd000)\",\"symbolTableIndexTime\":3.1000000000000001e-05,\"symbolTableLoadedFromCache\":false,\"symbolTableParseTime\":0.00038900000000000002,\"symbolTableSavedToCache\":false,\"symbolTableStripped\":false,\"triple\":\"x86_64-unknown-linux-gnu\",\"uuid\":\"B5AF4022-69CE-E598-5703-F5C62C32322D-D9CF26D1\"},{\"debugInfoByteSize\":1020,\"debugInfoEnabled\":true,\"debugInfoIndexLoadedFromCache\":false,\"debugInfoIndexSavedToCache\":false,\"debugInfoIndexTime\":0.0021559999999999999,\"debugInfoParseTime\":0.00024699999999999999,\"identifier\":140008887806080,\"path\":\"/data/users/wanyi/llvm-sand/build/Debug/fbcode-x86_64/toolchain/lldb-test-build.noindex/tools/lldb-vscode/terminated-event/TestVSCode_terminatedEvent.test_terminated_event/libfoo.so\",\"symbolTableIndexTime\":6.2000000000000003e-05,\"symbolTableLoadedFromCache\":false,\"symbolTableParseTime\":0.00080800000000000002,\"symbolTableSavedToCache\":false,\"symbolTableStripped\":false,\"triple\":\"x86_64--\",\"uuid\":\"109BFB15\"},{\"debugInfoByteSize\":0,\"debugInfoEnabled\":false,\"debugInfoIndexLoadedFromCache\":false,\"debugInfoIndexSavedToCache\":false,\"debugInfoIndexTime\":0,\"debugInfoParseTime\":0,\"identifier\":140008887859888,\"path\":\"/lib64/libdl.so.2\",\"symbolTableIndexTime\":0.000105,\"symbolTableLoadedFromCache\":false,\"symbolTableParseTime\":0.0013470000000000001,\"symbolTableSavedToCache\":false,\"symbolTableStripped\":false,\"triple\":\"x86_64--linux\",\"uuid\":\"776BF255-7FD5-1D1A-CAB0-D1D2D7568263-EC5999B5\"},{\"debugInfoByteSize\":0,\"debugInfoEnabled\":false,\"debugInfoIndexLoadedFromCache\":false,\"debugInfoIndexSavedToCache\":false,\"debugInfoIndexTime\":0,\"debugInfoParseTime\":0,\"identifier\":140008887883408,\"path\":\"/lib64/libstdc++.so.6\",\"symbolTableIndexTime\":0.038710000000000001,\"symbolTableLoadedFromCache\":false,\"symbolTableParseTime\":0.075740000000000002,\"symbolTableSavedToCache\":false,\"symbolTableStripped\":false,\"triple\":\"x86_64--linux\",\"uuid\":\"104D4081-3FC7-4F42-7CD4-AC714B249C02-DA5E62C3\"},{\"debugInfoByteSize\":0,\"debugInfoEnabled\":false,\"debugInfoIndexLoadedFromCache\":false,\"debugInfoIndexSavedToCache\":false,\"debugInfoIndexTime\":0,\"debugInfoParseTime\":0,\"identifier\":140008887951248,\"path\":\"/lib64/libm.so.6\",\"symbolTableIndexTime\":0.003212,\"symbolTableLoadedFromCache\":false,\"symbolTableParseTime\":0.027257,\"symbolTableSavedToCache\":false,\"symbolTableStripped\":false,\"triple\":\"x86_64--linux\",\"uuid\":\"089E6D24-BF02-DE2B-C57E-456118BFDC1D-691B14BB\"},{\"debugInfoByteSize\":0,\"debugInfoEnabled\":false,\"debugInfoIndexLoadedFromCache\":false,\"debugInfoIndexSavedToCache\":false,\"debugInfoIndexTime\":0,\"debugInfoParseTime\":0,\"identifier\":140008888170224,\"path\":\"/lib64/libgcc_s.so.1\",\"symbolTableIndexTime\":0.000357,\"symbolTableLoadedFromCache\":false,\"symbolTableParseTime\":0.0040460000000000001,\"symbolTableSavedToCache\":false,\"symbolTableStripped\":false,\"triple\":\"x86_64--\",\"uuid\":\"CD2F6200-D8CA-7045-ADDB-17C6C4240AAC-5DE305B1\"},{\"debugInfoByteSize\":0,\"debugInfoEnabled\":false,\"debugInfoIndexLoadedFromCache\":false,\"debugInfoIndexSavedToCache\":false,\"debugInfoIndexTime\":0,\"debugInfoParseTime\":0,\"identifier\":140008887911072,\"path\":\"/lib64/libc.so.6\",\"symbolTableIndexTime\":0.0070210000000000003,\"symbolTableLoadedFromCache\":false,\"symbolTableParseTime\":0.072236999999999996,\"symbolTableSavedToCache\":false,\"symbolTableStripped\":false,\"triple\":\"x86_64--linux\",\"uuid\":\"F65C85BF-DB90-4B62-3D4F-E2139B4D7C25-CF8C0B58\"},{\"debugInfoByteSize\":833593,\"debugInfoEnabled\":true,\"debugInfoIndexLoadedFromCache\":false,\"debugInfoIndexSavedToCache\":false,\"debugInfoIndexTime\":0.012407,\"debugInfoParseTime\":0.012078999999999999,\"identifier\":140008887927648,\"path\":\"/lib64/ld-linux-x86-64.so.2\",\"symbolTableIndexTime\":0.001758,\"symbolTableLoadedFromCache\":false,\"symbolTableParseTime\":0.022352,\"symbolTableSavedToCache\":false,\"symbolTableStripped\":false,\"triple\":\"x86_64--linux\",\"uuid\":\"57D782C6-AF24-135E-6970-7B9D3334B91B-6CD33392\"}],\"targets\":[{\"breakpoints\":[{\"details\":{\"Breakpoint\":{\"BKPTOptions\":{\"AutoContinue\":false,\"ConditionText\":\"\",\"EnabledState\":true,\"IgnoreCount\":0,\"OneShotState\":false},\"BKPTResolver\":{\"Options\":{\"NameMask\":[56],\"Offset\":0,\"SkipPrologue\":true,\"SymbolNames\":[\"foo\"]},\"Type\":\"SymbolName\"},\"Hardware\":false,\"Names\":[\"vscode\"],\"SearchFilter\":{\"Options\":{},\"Type\":\"Unconstrained\"}}},\"id\":1,\"internal\":false,\"numLocations\":1,\"numResolvedLocations\":1,\"resolveTime\":0.0020110000000000002},{\"details\":{\"Breakpoint\":{\"BKPTOptions\":{\"AutoContinue\":false,\"ConditionText\":\"\",\"EnabledState\":true,\"IgnoreCount\":0,\"OneShotState\":false},\"BKPTResolver\":{\"Options\":{\"Column\":0,\"Exact\":false,\"FileName\":\"/data/users/wanyi/llvm-sand/external/llvm-project/lldb/test/API/tools/lldb-vscode/terminated-event/main.cpp\",\"Inlines\":true,\"LineNumber\":5,\"Offset\":0,\"SkipPrologue\":true},\"Type\":\"FileAndLine\"},\"Hardware\":false,\"Names\":[\"vscode\"],\"SearchFilter\":{\"Options\":{},\"Type\":\"Unconstrained\"}}},\"id\":2,\"internal\":false,\"numLocations\":0,\"numResolvedLocations\":0,\"resolveTime\":0.22744400000000001},{\"details\":{\"Breakpoint\":{\"BKPTOptions\":{\"AutoContinue\":false,\"ConditionText\":\"\",\"EnabledState\":true,\"IgnoreCount\":0,\"OneShotState\":false},\"BKPTResolver\":{\"Options\":{\"Language\":\"c\",\"NameMask\":[4,4,4,4,4,4],\"Offset\":0,\"SkipPrologue\":false,\"SymbolNames\":[\"_dl_debug_state\",\"rtld_db_dlactivity\",\"__dl_rtld_db_dlactivity\",\"r_debug_state\",\"_r_debug_state\",\"_rtld_debug_state\"]},\"Type\":\"SymbolName\"},\"Hardware\":false,\"SearchFilter\":{\"Options\":{\"ModuleList\":[\"/usr/lib64/ld-2.28.so\"]},\"Type\":\"Modules\"}}},\"id\":-1,\"internal\":true,\"kindDescription\":\"shared-library-event\",\"numLocations\":1,\"numResolvedLocations\":1,\"resolveTime\":0.00034600000000000001}],\"expressionEvaluation\":{\"failures\":0,\"successes\":0},\"firstStopTime\":0.157499681,\"frameVariable\":{\"failures\":0,\"successes\":0},\"launchOrAttachTime\":0.117741226,\"moduleIdentifiers\":[93901655961472,93901656106336,93901654578688,140008887806080,140008887859888,140008887883408,140008887951248,140008888170224,140008887911072],\"signals\":[{\"SIGSTOP\":1}],\"sourceMapDeduceCount\":0,\"stopCount\":8,\"targetCreateTime\":0.00064000000000000005,\"totalBreakpointResolveTime\":0.22980100000000003}],\"totalDebugInfoByteSize\":1668206,\"totalDebugInfoEnabled\":3,\"totalDebugInfoIndexLoadedFromCache\":0,\"totalDebugInfoIndexSavedToCache\":0,\"totalDebugInfoIndexTime\":0.027220000000000001,\"totalDebugInfoParseTime\":0.33947100000000002,\"totalModuleCount\":10,\"totalModuleCountHasDebugInfo\":3,\"totalSymbolTableIndexTime\":0.053701000000000006,\"totalSymbolTableParseTime\":0.23014699999999999,\"totalSymbolTableStripped\":0,\"totalSymbolTablesLoadedFromCache\":0,\"totalSymbolTablesSavedToCache\":0}","type":"event"} ``` Differential Revision: https://reviews.llvm.org/D136177
1 parent b26f45e commit c8a26f8

File tree

9 files changed

+119
-2
lines changed

9 files changed

+119
-2
lines changed

lldb/packages/Python/lldbsuite/test/tools/lldb-vscode/vscode.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -369,7 +369,13 @@ def wait_for_stopped(self, timeout=None):
369369
def wait_for_exited(self):
370370
event_dict = self.wait_for_event('exited')
371371
if event_dict is None:
372-
raise ValueError("didn't get stopped event")
372+
raise ValueError("didn't get exited event")
373+
return event_dict
374+
375+
def wait_for_terminated(self):
376+
event_dict = self.wait_for_event('terminated')
377+
if event_dict is None:
378+
raise ValueError("didn't get terminated event")
373379
return event_dict
374380

375381
def get_initialize_value(self, key):
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
DYLIB_NAME := foo
2+
DYLIB_CXX_SOURCES := foo.cpp
3+
CXX_SOURCES := main.cpp
4+
5+
LD_EXTRAS := -Wl,-rpath "-Wl,$(shell pwd)"
6+
USE_LIBDL :=1
7+
8+
include Makefile.rules
9+
10+
all: a.out.stripped
11+
12+
a.out.stripped:
13+
strip -o a.out.stripped a.out
14+
15+
ifneq "$(CODESIGN)" ""
16+
$(CODESIGN) -fs - a.out.stripped
17+
endif
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
"""
2+
Test lldb-vscode terminated event
3+
"""
4+
5+
import vscode
6+
from lldbsuite.test.decorators import *
7+
from lldbsuite.test.lldbtest import *
8+
from lldbsuite.test import lldbutil
9+
import lldbvscode_testcase
10+
import re
11+
import json
12+
13+
class TestVSCode_terminatedEvent(lldbvscode_testcase.VSCodeTestCaseBase):
14+
15+
@skipIfWindows
16+
@skipIfRemote
17+
def test_terminated_event(self):
18+
'''
19+
Terminated Event
20+
Now contains the statistics of a debug session:
21+
metatdata:
22+
totalDebugInfoByteSize > 0
23+
totalDebugInfoEnabled > 0
24+
totalModuleCountHasDebugInfo > 0
25+
...
26+
targetInfo:
27+
totalBreakpointResolveTime > 0
28+
breakpoints:
29+
recognize function breakpoint
30+
recognize source line breakpoint
31+
It should contains the breakpoints info: function bp & source line bp
32+
'''
33+
34+
program_basename = "a.out.stripped"
35+
program = self.getBuildArtifact(program_basename)
36+
self.build_and_launch(program)
37+
# Set breakpoints
38+
functions = ['foo']
39+
breakpoint_ids = self.set_function_breakpoints(functions)
40+
self.assertEquals(len(breakpoint_ids), len(functions), 'expect one breakpoint')
41+
main_bp_line = line_number('main.cpp', '// main breakpoint 1')
42+
breakpoint_ids.append(self.set_source_breakpoints('main.cpp', [main_bp_line]))
43+
44+
self.continue_to_breakpoints(breakpoint_ids)
45+
self.continue_to_exit()
46+
47+
statistics = json.loads(self.vscode.wait_for_terminated()['statistics'])
48+
self.assertTrue(statistics['totalDebugInfoByteSize'] > 0)
49+
self.assertTrue(statistics['totalDebugInfoEnabled'] > 0)
50+
self.assertTrue(statistics['totalModuleCountHasDebugInfo'] > 0)
51+
52+
# lldb-vscode debugs one target at a time
53+
self.assertTrue(statistics['targets'][0]['totalBreakpointResolveTime'] > 0)
54+
55+
breakpoints = statistics['targets'][0]['breakpoints']
56+
self.assertIn('foo',
57+
breakpoints[0]['details']['Breakpoint']['BKPTResolver']['Options']['SymbolNames'],
58+
'foo is a symbol breakpoint')
59+
self.assertTrue(breakpoints[1]['details']['Breakpoint']['BKPTResolver']['Options']['FileName'].endswith('main.cpp'),
60+
'target has source line breakpoint in main.cpp')
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
int foo() {
2+
return 12;
3+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
int foo();
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
#include <iostream>
2+
#include "foo.h"
3+
4+
int main(int argc, char const *argv[]) {
5+
std::cout << "Hello World!" << std::endl; // main breakpoint 1
6+
foo();
7+
return 0;
8+
}

lldb/tools/lldb-vscode/JSONUtils.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include "lldb/API/SBBreakpoint.h"
2020
#include "lldb/API/SBBreakpointLocation.h"
2121
#include "lldb/API/SBDeclaration.h"
22+
#include "lldb/API/SBStructuredData.h"
2223
#include "lldb/API/SBValue.h"
2324
#include "lldb/Host/PosixApi.h"
2425

@@ -1139,6 +1140,21 @@ CreateRunInTerminalReverseRequest(const llvm::json::Object &launch_request,
11391140
return reverse_request;
11401141
}
11411142

1143+
llvm::json::Object CreateTerminatedEventObject() {
1144+
llvm::json::Object event(CreateEventObject("terminated"));
1145+
lldb::SBStructuredData statistics = g_vsc.target.GetStatistics();
1146+
bool is_dictionary =
1147+
statistics.GetType() == lldb::eStructuredDataTypeDictionary;
1148+
if (!is_dictionary) {
1149+
return event;
1150+
}
1151+
1152+
lldb::SBStream stats_stream;
1153+
statistics.GetAsJSON(stats_stream);
1154+
event.try_emplace("statistics", llvm::json::fixUTF8(stats_stream.GetData()));
1155+
return event;
1156+
}
1157+
11421158
std::string JSONToString(const llvm::json::Value &json) {
11431159
std::string data;
11441160
llvm::raw_string_ostream os(data);

lldb/tools/lldb-vscode/JSONUtils.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -485,6 +485,12 @@ CreateRunInTerminalReverseRequest(const llvm::json::Object &launch_request,
485485
llvm::StringRef debug_adaptor_path,
486486
llvm::StringRef comm_file);
487487

488+
/// Create a "Terminated" JSON object that contains statistics
489+
///
490+
/// \return
491+
/// A body JSON object with debug info and breakpoint info
492+
llvm::json::Object CreateTerminatedEventObject();
493+
488494
/// Convert a given JSON object to a string.
489495
std::string JSONToString(const llvm::json::Value &json);
490496

lldb/tools/lldb-vscode/lldb-vscode.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,7 @@ void SendTerminatedEvent() {
204204
g_vsc.sent_terminated_event = true;
205205
g_vsc.RunTerminateCommands();
206206
// Send a "terminated" event
207-
llvm::json::Object event(CreateEventObject("terminated"));
207+
llvm::json::Object event(CreateTerminatedEventObject());
208208
g_vsc.SendJSON(llvm::json::Value(std::move(event)));
209209
}
210210
}

0 commit comments

Comments
 (0)