[Lldb-commits] [lldb] [lldb-dap][windows] add integratedTerminal support (PR #174635)
Sergei Druzhkov via lldb-commits
lldb-commits at lists.llvm.org
Tue Feb 3 11:57:56 PST 2026
================
@@ -285,6 +304,111 @@ static llvm::Error LaunchRunInTerminalTarget(llvm::opt::Arg &target_arg,
#endif
lldb_private::FileSystem::Initialize();
+
+#ifdef _WIN32
+ RunInTerminalLauncherCommChannel comm_channel(comm_file);
+
+ auto wcommandLineOrErr =
+ lldb_private::GetFlattenedWindowsCommandStringW(argv);
+ if (!wcommandLineOrErr)
+ return notifyError(comm_channel, "Failed to process arguments");
+
+ STARTUPINFOEXW startupinfoex = {};
+ startupinfoex.StartupInfo.cb = sizeof(STARTUPINFOEXW);
+ startupinfoex.StartupInfo.dwFlags |= STARTF_USESTDHANDLES;
+
+ HANDLE stdin_handle = GetStdHandle(STD_INPUT_HANDLE);
+ HANDLE stdout_handle = GetStdHandle(STD_OUTPUT_HANDLE);
+ HANDLE stderr_handle = GetStdHandle(STD_ERROR_HANDLE);
+
+ auto attributelist_or_err =
+ lldb_private::ProcThreadAttributeList::Create(startupinfoex);
+ if (!attributelist_or_err) {
+ return notifyError(comm_channel, "Could not open inherited handles",
+ attributelist_or_err.getError());
+ }
+
+ if (!stdio.empty()) {
+ llvm::SmallVector<llvm::StringRef, 3> files;
+ stdio.split(files, ';');
+ while (files.size() < 3)
+ files.push_back(files.back());
+
+ stdin_handle = lldb_private::ProcessLauncherWindows::GetStdioHandle(
+ files[0], STDIN_FILENO);
+ stdout_handle = lldb_private::ProcessLauncherWindows::GetStdioHandle(
+ files[1], STDOUT_FILENO);
+ stderr_handle = lldb_private::ProcessLauncherWindows::GetStdioHandle(
+ files[2], STDERR_FILENO);
+ }
+
+ llvm::scope_exit close_handles([&] {
+ // Only close the handles we created
+ if (stdio.empty())
+ return;
+ if (stdin_handle)
+ CloseHandle(stdin_handle);
+ if (stdout_handle)
+ CloseHandle(stdout_handle);
+ if (stderr_handle)
+ CloseHandle(stderr_handle);
+ });
+
+ auto inherited_handles_or_err =
+ lldb_private::ProcessLauncherWindows::GetInheritedHandles(
+ startupinfoex, /*launch_info*=*/nullptr, stdout_handle, stderr_handle,
+ stdin_handle);
+
+ if (!inherited_handles_or_err)
+ return notifyError(comm_channel, "Failed to get inherited handles",
+ inherited_handles_or_err.getError());
+ std::vector<HANDLE> inherited_handles = std::move(*inherited_handles_or_err);
+
+ PROCESS_INFORMATION pi = {};
+
+ // Start the process in a suspended state, while we attach the debugger.
+ BOOL result = CreateProcessW(
+ /*lpApplicationName=*/NULL, /*lpCommandLine=*/&(*wcommandLineOrErr)[0],
+ /*lpProcessAttributes=*/NULL, /*lpThreadAttributes=*/NULL,
+ /*bInheritHandles=*/!inherited_handles.empty(),
+ /*dwCreationFlags=*/CREATE_SUSPENDED, /*lpEnvironment=*/NULL,
+ /*lpCurrentDirectory=*/NULL,
+ /*lpStartupInfo=*/reinterpret_cast<STARTUPINFOW *>(&startupinfoex),
+ /*lpProcessInformation=*/&pi);
+
+ if (!result)
+ return notifyError(comm_channel, "Failed to launch target process");
+
+ auto cleanupAndReturn = [&](llvm::Error err) -> llvm::Error {
+ if (pi.hProcess)
+ TerminateProcess(pi.hProcess, 1);
+ if (pi.hThread)
+ CloseHandle(pi.hThread);
+ if (pi.hProcess)
+ CloseHandle(pi.hProcess);
+ return err;
+ };
+
+ // Notify the pid of the process to debug to the debugger. It will attach to
+ // the newly created process.
+ if (llvm::Error err = comm_channel.NotifyPid(pi.dwProcessId))
+ return cleanupAndReturn(std::move(err));
+
+ if (llvm::Error err = comm_channel.WaitUntilDebugAdapterAttaches(
+ std::chrono::milliseconds(timeout_in_ms)))
+ return cleanupAndReturn(std::move(err));
+
+ // The debugger attached to the process. We can resume it.
+ if (!ResumeThread(pi.hThread))
+ return cleanupAndReturn(
+ notifyError(comm_channel, "Failed to resume the target process"));
+
+ // Wait for child to complete to match POSIX behavior.
+ WaitForSingleObject(pi.hProcess, INFINITE);
+ CloseHandle(pi.hThread);
+ CloseHandle(pi.hProcess);
+ return llvm::Error::success();
----------------
DrSergei wrote:
I guess we should insert `exit(0)` to match POSIX behavior when exec never returns. Without that we trigger assert in `SBDebugger` initialization.
```
PS D:\projects\pipes> & 'D:\llvm-project\build-nopython-debug\bin\lldb-dap.exe' '--comm-file' '\\.\pipe\lldb-dap-run-in-terminal-comm-3900' '--stdio' ';tmp.txt;tmp.txt' '--launch-target' 'D:\projects\pipes/main.exe'
Assertion failed: !InstanceImpl() && "Already initialized.", file D:\llvm-project\lldb\include\lldb/Host/FileSystem.h, line 51
PLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/ and include the crash backtrace.
Stack dump:
0. Program arguments: D:\\llvm-project\\build-nopython-debug\\bin\\lldb-dap.exe --comm-file \\\\.\\pipe\\lldb-dap-run-in-terminal-comm-3900 --stdio ;tmp.txt;tmp.txt --launch-target D:\\projects\\pipes/main.exe
Exception Code: 0x80000003
#0 0x00007ff6bf759ebc HandleAbort D:\llvm-project\llvm\lib\Support\Windows\Signals.inc:371:0
#1 0x00007ffc111990ed (C:\WINDOWS\SYSTEM32\ucrtbased.dll+0xa90ed)
#2 0x00007ffc1119ae49 (C:\WINDOWS\SYSTEM32\ucrtbased.dll+0xaae49)
#3 0x00007ffc111a1345 (C:\WINDOWS\SYSTEM32\ucrtbased.dll+0xb1345)
#4 0x00007ffc111a0bd7 (C:\WINDOWS\SYSTEM32\ucrtbased.dll+0xb0bd7)
#5 0x00007ffc1119eba1 (C:\WINDOWS\SYSTEM32\ucrtbased.dll+0xaeba1)
#6 0x00007ffc111a18af (C:\WINDOWS\SYSTEM32\ucrtbased.dll+0xb18af)
#7 0x00007ffb3352a8f0 lldb_private::FileSystem::Initialize<>(void) D:\llvm-project\lldb\include\lldb\Host\FileSystem.h:51:0
#8 0x00007ffb3352a407 lldb_private::SystemInitializerCommon::Initialize(void) D:\llvm-project\lldb\source\Initialization\SystemInitializerCommon.cpp:71:0
#9 0x00007ffb331b6d5e lldb_private::SystemInitializerFull::Initialize(void) D:\llvm-project\lldb\source\API\SystemInitializerFull.cpp:54:0
#10 0x00007ffb33529c9b lldb_private::SystemLifetimeManager::Initialize(class std::unique_ptr<class lldb_private::SystemInitializer, struct std::default_delete<class lldb_private::SystemInitializer>>) D:\llvm-project\lldb\source\Initialization\SystemLifetimeManager.cpp:34:0
#11 0x00007ffb32fbda99 lldb::SBDebugger::InitializeWithErrorHandling(void) D:\llvm-project\lldb\source\API\SBDebugger.cpp:183:0
#12 0x00007ff6bf62ea13 main D:\llvm-project\lldb\tools\lldb-dap\tool\lldb-dap.cpp:775:0
#13 0x00007ff6bfa8ac49 invoke_main D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl:79:0
#14 0x00007ff6bfa8ab32 __scrt_common_main_seh D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl:288:0
#15 0x00007ff6bfa8a9ee __scrt_common_main D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl:331:0
#16 0x00007ff6bfa8acde mainCRTStartup D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_main.cpp:17:0
#17 0x00007ffc4fd5e8d7 (C:\WINDOWS\System32\KERNEL32.DLL+0x2e8d7)
#18 0x00007ffc5128c53c (C:\WINDOWS\SYSTEM32\ntdll.dll+0x8c53c)
```
https://github.com/llvm/llvm-project/pull/174635
More information about the lldb-commits
mailing list