[lldb]Send statistics in initialized event (#178978)

Re-attemp landing of old commit:
7fe3586cda

Co-authored-by: George Hu <georgehuyubo@gmail.com>
This commit is contained in:
GeorgeHuyubo 2026-02-04 09:10:07 -08:00 committed by GitHub
parent 4a0a2057a8
commit 23bf55eda4
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 119 additions and 2 deletions

View File

@ -310,6 +310,7 @@ class DebugCommunication(object):
# trigger enqueue thread
self._recv_thread.start()
self.initialized_event = None
@classmethod
def encode_content(cls, s: str) -> bytes:
@ -516,6 +517,7 @@ class DebugCommunication(object):
self.output[category] = output
elif event == "initialized":
self.initialized = True
self.initialized_event = packet
elif event == "process":
# When a new process is attached or launched, remember the
# details that are available in the body of the event

View File

@ -0,0 +1,17 @@
DYLIB_NAME := foo
DYLIB_CXX_SOURCES := foo.cpp
CXX_SOURCES := main.cpp
LD_EXTRAS := -Wl,-rpath "-Wl,$(shell pwd)"
USE_LIBDL :=1
include Makefile.rules
all: a.out.stripped
a.out.stripped:
strip -o a.out.stripped a.out
ifneq "$(CODESIGN)" ""
$(CODESIGN) -fs - a.out.stripped
endif

View File

@ -0,0 +1,76 @@
"""
Test lldb-dap terminated event
"""
import dap_server
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
import json
import re
import lldbdap_testcase
from lldbsuite.test import lldbutil
class TestDAP_eventStatistic(lldbdap_testcase.DAPTestCaseBase):
"""
Test case that captures both initialized and terminated events.
META-ONLY: Intended to succeed TestDAP_terminatedEvent.py, but upstream keeps updating that file, so both that and this file will probably exist for a while.
"""
def check_statistics_summary(self, statistics):
self.assertTrue(statistics["totalDebugInfoByteSize"] > 0)
self.assertTrue(statistics["totalDebugInfoEnabled"] > 0)
self.assertTrue(statistics["totalModuleCountHasDebugInfo"] > 0)
self.assertNotIn("modules", statistics.keys())
def check_target_summary(self, statistics):
# lldb-dap debugs one target at a time
target = json.loads(statistics["targets"])[0]
self.assertIn("totalSharedLibraryEventHitCount", target)
@skipIfWindows
@skipIfRemote
def test_terminated_event(self):
"""
Terminated Event
Now contains the statistics of a debug session:
metatdata:
totalDebugInfoByteSize > 0
totalDebugInfoEnabled > 0
totalModuleCountHasDebugInfo > 0
...
"""
program_basename = "a.out.stripped"
program = self.getBuildArtifact(program_basename)
self.build_and_launch(program)
self.continue_to_exit()
statistics = self.dap_server.wait_for_terminated()["body"]["$__lldb_statistics"]
self.check_statistics_summary(statistics)
self.check_target_summary(statistics)
@skipIfWindows
@skipIfRemote
def test_initialized_event(self):
"""
Initialized Event
Now contains the statistics of a debug session:
totalDebugInfoByteSize > 0
totalDebugInfoEnabled > 0
totalModuleCountHasDebugInfo > 0
...
"""
program_basename = "a.out"
program = self.getBuildArtifact(program_basename)
self.build_and_launch(program)
self.dap_server.wait_for_event("initialized")
statistics = self.dap_server.initialized_event["body"]["$__lldb_statistics"]
self.check_statistics_summary(statistics)
self.continue_to_exit()

View File

@ -0,0 +1 @@
int foo() { return 12; }

View File

@ -0,0 +1 @@
int foo();

View File

@ -0,0 +1,8 @@
#include "foo.h"
#include <iostream>
int main(int argc, char const *argv[]) {
std::cout << "Hello World!" << std::endl;
foo();
return 0;
}

View File

@ -11,6 +11,7 @@
#include "DAP.h"
#include "DAPError.h"
#include "JSONUtils.h"
#include "Protocol/ProtocolBase.h"
#include "Protocol/ProtocolRequests.h"
#include "Protocol/ProtocolTypes.h"
@ -197,8 +198,7 @@ class DelayedResponseRequestHandler : public BaseRequestHandler {
// The 'configurationDone' request is not sent until after 'initialized'
// triggers the breakpoints being sent and 'configurationDone' is the last
// message in the chain.
protocol::Event initialized{"initialized"};
dap.Send(initialized);
dap.SendJSON(CreateInitializedEventObject(dap.target));
};
protected:

View File

@ -590,6 +590,12 @@ llvm::json::Object CreateTerminatedEventObject(lldb::SBTarget &target) {
return event;
}
llvm::json::Object CreateInitializedEventObject(lldb::SBTarget &target) {
llvm::json::Object event(CreateEventObject("initialized"));
addStatistic(target, event);
return event;
}
std::string JSONToString(const llvm::json::Value &json) {
std::string data;
llvm::raw_string_ostream os(data);

View File

@ -333,6 +333,12 @@ llvm::json::Object CreateRunInTerminalReverseRequest(
/// A body JSON object with debug info and breakpoint info
llvm::json::Object CreateTerminatedEventObject(lldb::SBTarget &target);
/// Create a "Initialized" JSON object that contains statistics
///
/// \return
/// A body JSON object with debug info
llvm::json::Object CreateInitializedEventObject(lldb::SBTarget &target);
/// Convert a given JSON object to a string.
std::string JSONToString(const llvm::json::Value &json);