[lldb-dap] Fix URL label and error code in DAPError (#145010)

This patch fixes some problems in DAPerror class (unnecessary copy in
ctor and typo in getUrlLabel function). During patch testing I found
flaky test TestDAP_server.test_server_interrupt (at least 1 fail on 50
runs). Looks like this problem is caused by data race between main and
event handler threads. Terminated event can be sent from Disconnect
function and event handler. However, only event handler sends exit
event. Also, after disconnecting, socket will be closed, so sometimes
sending event fails with "write failed: transport IO object invalid"
error. I tried to fix this problem by adding a wait for events thread
after disconnecting.

Failed log example:
```log
1750366596.399511337 lldb-dap server shutdown requested, disconnecting remaining clients...
1750366596.406297684 (client_0) <-- {"body":{"$__lldb_statistics":{"commands":"{}","memory":"{\"strings\":{\"bytesTotal\":2949120,\"bytesUnused\":1825545,\"bytesUsed\":1123575}}","plugins":"{\"abi\":[{\"enabled\":true,\"name\":\"SysV-arm64\"},{\"enabled\":true,\"name\":\"ABIMacOSX_arm64\"},{\"enabled\":true,\"name\":\"SysV-arm\"},{\"enabled\":true,\"name\":\"macosx-arm\"},{\"enabled\":true,\"name\":\"sysv-hexagon\"},{\"enabled\":true,\"name\":\"sysv-loongarch\"},{\"enabled\":true,\"name\":\"sysv-mips\"},{\"enabled\":true,\"name\":\"sysv-mips64\"},{\"enabled\":true,\"name\":\"sysv-msp430\"},{\"enabled\":true,\"name\":\"sysv-ppc\"},{\"enabled\":true,\"name\":\"sysv-ppc64\"},{\"enabled\":true,\"name\":\"sysv-riscv\"},{\"enabled\":true,\"name\":\"sysv-s390x\"},{\"enabled\":true,\"name\":\"abi.macosx-i386\"},{\"enabled\":true,\"name\":\"sysv-i386\"},{\"enabled\":true,\"name\":\"sysv-x86_64\"},{\"enabled\":true,\"name\":\"windows-x86_64\"}],\"architecture\":[{\"enabled\":true,\"name\":\"arm\"},{\"enabled\":true,\"name\":\"mips\"},{\"enabled\":true,\"name\":\"ppc64\"},{\"enabled\":true,\"name\":\"aarch64\"}],\"disassembler\":[{\"enabled\":true,\"name\":\"llvm-mc\"}],\"dynamic-loader\":[{\"enabled\":true,\"name\":\"darwin-kernel\"},{\"enabled\":true,\"name\":\"freebsd-kernel\"},{\"enabled\":true,\"name\":\"macosx-dyld\"},{\"enabled\":true,\"name\":\"macos-dyld\"},{\"enabled\":true,\"name\":\"posix-dyld\"},{\"enabled\":true,\"name\":\"static\"},{\"enabled\":true,\"name\":\"hexagon-dyld\"},{\"enabled\":true,\"name\":\"windows-dyld\"},{\"enabled\":true,\"name\":\"wasm-dyld\"}],\"emulate-instruction\":[{\"enabled\":true,\"name\":\"arm\"},{\"enabled\":true,\"name\":\"arm64\"},{\"enabled\":true,\"name\":\"LoongArch\"},{\"enabled\":true,\"name\":\"mips32\"},{\"enabled\":true,\"name\":\"mips64\"},{\"enabled\":true,\"name\":\"ppc64\"},{\"enabled\":true,\"name\":\"riscv\"}],\"instrumentation-runtime\":[{\"enabled\":true,\"name\":\"AddressSanitizer\"},{\"enabled\":true,\"name\":\"Libsanitizers-ASan\"},{\"enabled\":true,\"name\":\"MainThreadChecker\"},{\"enabled\":true,\"name\":\"ThreadSanitizer\"},{\"enabled\":true,\"name\":\"UndefinedBehaviorSanitizer\"}],\"jit-loader\":[{\"enabled\":true,\"name\":\"gdb\"}],\"language\":[{\"enabled\":true,\"name\":\"cplusplus\"},{\"enabled\":true,\"name\":\"objc\"},{\"enabled\":true,\"name\":\"objcplusplus\"}],\"language-runtime\":[{\"enabled\":true,\"name\":\"itanium\"},{\"enabled\":true,\"name\":\"apple-objc-v2\"},{\"enabled\":true,\"name\":\"apple-objc-v1\"},{\"enabled\":true,\"name\":\"gnustep-objc-libobjc2\"}],\"memory-history\":[{\"enabled\":true,\"name\":\"asan\"}],\"object-container\":[{\"enabled\":true,\"name\":\"bsd-archive\"},{\"enabled\":true,\"name\":\"mach-o\"},{\"enabled\":true,\"name\":\"mach-o-fileset\"}],\"object-file\":[{\"enabled\":true,\"name\":\"breakpad\"},{\"enabled\":true,\"name\":\"COFF\"},{\"enabled\":true,\"name\":\"elf\"},{\"enabled\":true,\"name\":\"JSON\"},{\"enabled\":true,\"name\":\"mach-o\"},{\"enabled\":true,\"name\":\"minidump\"},{\"enabled\":true,\"name\":\"pdb\"},{\"enabled\":true,\"name\":\"pe-coff\"},{\"enabled\":true,\"name\":\"xcoff\"},{\"enabled\":true,\"name\":\"wasm\"}],\"operating-system\":[{\"enabled\":true,\"name\":\"python\"}],\"platform\":[{\"enabled\":true,\"name\":\"remote-AIX\"},{\"enabled\":true,\"name\":\"remote-linux\"},{\"enabled\":true,\"name\":\"remote-android\"},{\"enabled\":true,\"name\":\"remote-freebsd\"},{\"enabled\":true,\"name\":\"remote-gdb-server\"},{\"enabled\":true,\"name\":\"darwin\"},{\"enabled\":true,\"name\":\"remote-ios\"},{\"enabled\":true,\"name\":\"remote-macosx\"},{\"enabled\":true,\"name\":\"host\"},{\"enabled\":true,\"name\":\"remote-netbsd\"},{\"enabled\":true,\"name\":\"remote-openbsd\"},{\"enabled\":true,\"name\":\"qemu-user\"},{\"enabled\":true,\"name\":\"remote-windows\"}],\"process\":[{\"enabled\":true,\"name\":\"ScriptedProcess\"},{\"enabled\":true,\"name\":\"elf-core\"},{\"enabled\":true,\"name\":\"mach-o-core\"},{\"enabled\":true,\"name\":\"minidump\"},{\"enabled\":true,\"name\":\"gdb-remote\"}],\"register-type-builder\":[{\"enabled\":true,\"name\":\"register-types-clang\"}],\"repl\":[{\"enabled\":true,\"name\":\"ClangREPL\"}],\"script-interpreter\":[{\"enabled\":true,\"name\":\"script-none\"},{\"enabled\":true,\"name\":\"script-python\"}],\"scripted-interface\":[{\"enabled\":true,\"name\":\"OperatingSystemPythonInterface\"},{\"enabled\":true,\"name\":\"ScriptedPlatformPythonInterface\"},{\"enabled\":true,\"name\":\"ScriptedProcessPythonInterface\"},{\"enabled\":true,\"name\":\"ScriptedStopHookPythonInterface\"},{\"enabled\":true,\"name\":\"ScriptedThreadPlanPythonInterface\"}],\"structured-data\":[{\"enabled\":true,\"name\":\"darwin-log\"}],\"symbol-file\":[{\"enabled\":true,\"name\":\"breakpad\"},{\"enabled\":true,\"name\":\"CTF\"},{\"enabled\":true,\"name\":\"dwarf\"},{\"enabled\":true,\"name\":\"dwarf-debugmap\"},{\"enabled\":true,\"name\":\"JSON\"},{\"enabled\":true,\"name\":\"native-pdb\"},{\"enabled\":true,\"name\":\"symtab\"}],\"symbol-locator\":[{\"enabled\":true,\"name\":\"debuginfod\"},{\"enabled\":true,\"name\":\"Default\"}],\"symbol-vendor\":[{\"enabled\":true,\"name\":\"ELF\"},{\"enabled\":true,\"name\":\"PE-COFF\"},{\"enabled\":true,\"name\":\"WASM\"}],\"system-runtime\":[{\"enabled\":true,\"name\":\"systemruntime-macosx\"}],\"trace-exporter\":[{\"enabled\":true,\"name\":\"ctf\"}],\"type-system\":[{\"enabled\":true,\"name\":\"clang\"}],\"unwind-assembly\":[{\"enabled\":true,\"name\":\"inst-emulation\"},{\"enabled\":true,\"name\":\"x86\"}]}","targets":"[{\"breakpoints\":[{\"details\":{\"Breakpoint\":{\"BKPTOptions\":{\"AutoContinue\":false,\"ConditionText\":\"\",\"EnabledState\":true,\"IgnoreCount\":0,\"OneShotState\":false},\"BKPTResolver\":{\"Options\":{\"Column\":0,\"Exact\":false,\"FileName\":\"/home/sergei/llvm-project/lldb/test/API/tools/lldb-dap/server/main.c\",\"Inlines\":true,\"LineNumber\":4,\"Offset\":0,\"SkipPrologue\":true},\"Type\":\"FileAndLine\"},\"Hardware\":false,\"Names\":[\"dap\"],\"SearchFilter\":{\"Options\":{},\"Type\":\"Unconstrained\"}}},\"hitCount\":1,\"id\":1,\"internal\":false,\"numLocations\":1,\"numResolvedLocations\":1,\"resolveTime\":0.064788999999999999},{\"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/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2\"]},\"Type\":\"Modules\"}}},\"hitCount\":2,\"id\":-1,\"internal\":true,\"kindDescription\":\"shared-library-event\",\"numLocations\":1,\"numResolvedLocations\":1,\"resolveTime\":0.00027700000000000001}],\"dyldPluginName\":\"posix-dyld\",\"expressionEvaluation\":{\"failures\":0,\"successes\":0},\"firstStopTime\":0.081890439999999995,\"frameVariable\":{\"failures\":0,\"successes\":0},\"launchOrAttachTime\":0.044839855999999997,\"moduleIdentifiers\":[140296113373488,140296115439216,140296116813568,140295710837504,140295643597696,140294502747184,140294972632368],\"signals\":[{\"SIGSTOP\":1}],\"sourceMapDeduceCount\":0,\"sourceRealpathAttemptCount\":0,\"sourceRealpathCompatibleCount\":0,\"stopCount\":7,\"summaryProviderStatistics\":[],\"targetCreateTime\":0.000736,\"totalBreakpointResolveTime\":0.065065999999999999,\"totalSharedLibraryEventHitCount\":2}]","totalDebugInfoByteSize":5107143,"totalDebugInfoEnabled":4,"totalDebugInfoIndexLoadedFromCache":0,"totalDebugInfoIndexSavedToCache":0,"totalDebugInfoIndexTime":0.183807,"totalDebugInfoParseTime":1.2240820000000001,"totalModuleCount":7,"totalModuleCountHasDebugInfo":4,"totalModuleCountWithIncompleteTypes":0,"totalModuleCountWithVariableErrors":0,"totalSymbolLocatorTime":"{\"Default\":0.0054260000000000003,\"debuginfod\":6.999999999999999e-06}","totalSymbolTableIndexTime":0.014254000000000001,"totalSymbolTableParseTime":0.099803000000000003,"totalSymbolTableStripped":0,"totalSymbolTableSymbolCount":23098,"totalSymbolTablesLoaded":7,"totalSymbolTablesLoadedFromCache":0,"totalSymbolTablesSavedToCache":0}},"event":"terminated","seq":0,"type":"event"}
1750366596.406688452 (client_0) write failed: transport IO object invalid
1750366596.406724215 (client_0) write failed: transport IO object invalid
1750366596.842197657 (client_0) client disconnected
```
This commit is contained in:
DrSergei 2025-06-23 19:34:22 +03:00 committed by GitHub
parent c0ce9adf60
commit 909cbcf988
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 42 additions and 6 deletions

View File

@ -18,14 +18,12 @@ char DAPError::ID;
DAPError::DAPError(std::string message, std::error_code EC, bool show_user,
std::optional<std::string> url,
std::optional<std::string> url_label)
: m_message(message), m_ec(EC), m_show_user(show_user), m_url(url),
m_url_label(url_label) {}
: m_message(std::move(message)), m_ec(EC), m_show_user(show_user),
m_url(std::move(url)), m_url_label(std::move(url_label)) {}
void DAPError::log(llvm::raw_ostream &OS) const { OS << m_message; }
std::error_code DAPError::convertToErrorCode() const {
return llvm::inconvertibleErrorCode();
}
std::error_code DAPError::convertToErrorCode() const { return m_ec; }
char NotStoppedError::ID;

View File

@ -30,7 +30,7 @@ public:
const std::string &getMessage() const { return m_message; }
bool getShowUser() const { return m_show_user; }
const std::optional<std::string> &getURL() const { return m_url; }
const std::optional<std::string> &getURLLabel() const { return m_url; }
const std::optional<std::string> &getURLLabel() const { return m_url_label; }
private:
std::string m_message;

View File

@ -1,4 +1,5 @@
add_lldb_unittest(DAPTests
DAPErrorTest.cpp
DAPTest.cpp
FifoFilesTest.cpp
Handler/DisconnectTest.cpp

View File

@ -0,0 +1,37 @@
//===-- DAPErrorTest.cpp---------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#include "DAPError.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include <string>
#include <system_error>
using namespace lldb_dap;
using namespace llvm;
TEST(DAPErrorTest, DefaultConstructor) {
DAPError error("Invalid thread");
EXPECT_EQ(error.getMessage(), "Invalid thread");
EXPECT_EQ(error.convertToErrorCode(), llvm::inconvertibleErrorCode());
EXPECT_TRUE(error.getShowUser());
EXPECT_EQ(error.getURL(), std::nullopt);
EXPECT_EQ(error.getURLLabel(), std::nullopt);
}
TEST(DAPErrorTest, FullConstructor) {
auto timed_out = std::make_error_code(std::errc::timed_out);
DAPError error("Timed out", timed_out, false, "URL", "URLLabel");
EXPECT_EQ(error.getMessage(), "Timed out");
EXPECT_EQ(error.convertToErrorCode(), timed_out);
EXPECT_FALSE(error.getShowUser());
EXPECT_THAT(error.getURL(), testing::Optional<std::string>("URL"));
EXPECT_THAT(error.getURLLabel(), testing::Optional<std::string>("URLLabel"));
}