[Lldb-commits] [lldb] [lldb-dap] Updating RequestHandler to encode/decode arguments and response. (PR #130090)

2025-03-12 Thread Adrian Vogelsgesang via lldb-commits


@@ -240,6 +240,137 @@ using Message = std::variant;
 bool fromJSON(const llvm::json::Value &, Message &, llvm::json::Path);
 llvm::json::Value toJSON(const Message &);
 
+// MARK: Types
+
+// "Source": {
+//   "type": "object",
+//   "description": "A `Source` is a descriptor for source code.\nIt is 
returned
+//   from the debug adapter as part of a `StackFrame` and it is used by clients
+//   when specifying breakpoints.", "properties": {
+// "name": {
+//   "type": "string",
+//   "description": "The short name of the source. Every source returned
+//   from the debug adapter has a name.\nWhen sending a source to the debug
+//   adapter this name is optional."
+// },
+// "path": {
+//   "type": "string",
+//   "description": "The path of the source to be shown in the UI.\nIt is
+//   only used to locate and load the content of the source if no
+//   `sourceReference` is specified (or its value is 0)."
+// },
+// "sourceReference": {
+//   "type": "integer",
+//   "description": "If the value > 0 the contents of the source must be
+//   retrieved through the `source` request (even if a path is
+//   specified).\nSince a `sourceReference` is only valid for a session, it
+//   can not be used to persist a source.\nThe value should be less than or
+//   equal to 2147483647 (2^31-1)."
+// },
+// "presentationHint": {
+//   "type": "string",
+//   "description": "A hint for how to present the source in the UI.\nA
+//   value of `deemphasize` can be used to indicate that the source is not
+//   available or that it is skipped on stepping.", "enum": [ "normal",
+//   "emphasize", "deemphasize" ]
+// },
+// "origin": {
+//   "type": "string",
+//   "description": "The origin of this source. For example, 'internal
+//   module', 'inlined content from source map', etc."
+// },
+// "sources": {
+//   "type": "array",
+//   "items": {
+// "$ref": "#/definitions/Source"
+//   },
+//   "description": "A list of sources that are related to this source.
+//   These may be the source that generated this source."
+// },
+// "adapterData": {
+//   "type": [ "array", "boolean", "integer", "null", "number", "object",
+//   "string" ], "description": "Additional data that a debug adapter might
+//   want to loop through the client.\nThe client should leave the data
+//   intact and persist it across sessions. The client should not interpret
+//   the data."
+// },
+// "checksums": {
+//   "type": "array",
+//   "items": {
+// "$ref": "#/definitions/Checksum"
+//   },
+//   "description": "The checksums associated with this file."
+// }
+//   }
+// },
+struct Source {
+  enum class PresentationHint { normal, emphasize, deemphasize };
+
+  std::optional name;
+  std::optional path;
+  std::optional sourceReference;
+  std::optional presentationHint;
+
+  // unsupproted keys origin, sources, adapterData, checksums
+};
+bool fromJSON(const llvm::json::Value &, Source &, llvm::json::Path);
+llvm::json::Value toJSON(const Source &);
+
+// MARK: Requests
+
+// "SourceArguments": {
+//   "type": "object",
+//   "description": "Arguments for `source` request.",
+//   "properties": {
+// "source": {
+//   "$ref": "#/definitions/Source",
+//   "description": "Specifies the source content to load. Either
+//   `source.path` or `source.sourceReference` must be specified."
+// },
+// "sourceReference": {
+//   "type": "integer",
+//   "description": "The reference to the source. This is the same as
+//   `source.sourceReference`.\nThis is provided for backward compatibility
+//   since old clients do not understand the `source` attribute."
+// }
+//   },
+//   "required": [ "sourceReference" ]
+// },
+struct SourceArguments {

vogelsgesang wrote:

> I'm fine with changing how we structure things, but I liked having the 
> distinction between lldb_dap::protocol for the underlying protocol, lldb_dap 
> for our intermediate components and lldb/lldb_private for the SB API layer of 
> the debugger itself.

Indeed, you brought up a couple of good arguments for keeping the protocol 
separate. I am undecided. Let's see if anyone else jumps in and also has 
additional arguments in either direction. Otherwise, I would be fine with 
either way.

> The [DAP 
> spec](https://microsoft.github.io/debug-adapter-protocol/specification) 
> already groups at a high level into Base Protocol, Events, Requests, Reverse 
> Requests and Types, which I was roughly following in this file using // MARK: 
>  headings between sections.

Even if we don't move `*Args`, `*Request` and `*Response` types to the 
corresponding `*RequestHandler`, I think we should still separate the base 
protocol from the remaining protocol types. I would prefer separate files over 
`// MARK: `

[Lldb-commits] [lldb] [LLDB][Telemetry]Define TargetInfo for collecting data about a target (PR #127834)

2025-03-12 Thread Pavel Labath via lldb-commits

labath wrote:

> Does that make sense?

Somewhat, but I think there's still a lot of confusion between a target vs. 
process vs. the main executable of the target.

> 
> * How long did it take to load the target? ( the first time it was load 
> vs subsequent times ...)

Define "target". Define "loading a target". When a process does an execve is it 
still the same target (as far as the rest of lldb is concerned, it is, even 
though it starts executing a different binary)?

Right now, you're measuring the time it takes to run SetExecutableModule. I 
think that's a reasonable thing to measure. What I have a problem with is 
drawing a line between that and SetExitStatus, as those two things are very 
different. I also (to a slightly lesser degree) have an issue with calling that 
"TargetInfo", as it's really information about what we're doing with the 
executable module (for some target).

In the lldb object model, there's isn't really a concept of "loading a target". 
Target's can be *created*. They can be created with or without an executable 
module. If they're created without it, the module can be set at a later time 
(e.g. during an attach operation). While setting the executable module, the 
debug info for that module may or may not be parsed, depending on the 
`preload-symbols` setting. I think this is the definition of "loading" you're 
referring to, but that is not "loading a target", that is "loading (parsing) 
the debug info for a module" (which happens to be the executable module of some 
target). 

If you want to measure SetExecutableModule, then I think you should call it 
that (SetExecutableModuleInfo?). With that framing, I think everything you have 
here makes sense. You are reporting that we've set (for whatever reason) the 
executable module (identified by its UUID) of a target (we don't have a way to 
identify a target independently of its executable, but it sounds like you don't 
care about that), and saying it took certain amount of seconds.

> * Did the target exit successfully? (if not, what was the issue) How long 
> did the "exit" take?

Similarly, I have an issue with this framing, because targets don't exit 
(processes do). I'd call this ProcessExitInfo, because that's exactly what it's 
doing: it reports that a process, identified by the UUID of its executable 
(which, ideally, is one of the executables that we've set earlier, but there 
isn't an exact 1:1 matching between the two events) has exited and how it did 
that.

https://github.com/llvm/llvm-project/pull/127834
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb][AIX] Added base files for NativeProcess Support for AIX (PR #118160)

2025-03-12 Thread Pavel Labath via lldb-commits


@@ -0,0 +1,256 @@
+//===-- NativeProcessAIX.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 "NativeProcessAIX.h"
+#include "Plugins/Process/POSIX/ProcessPOSIXLog.h"
+#include "lldb/Host/Host.h"
+#include "lldb/Host/HostProcess.h"
+#include "lldb/Host/ProcessLaunchInfo.h"
+#include "lldb/Host/posix/ProcessLauncherPosixFork.h"
+#include "lldb/Symbol/ObjectFile.h"
+#include "lldb/Utility/Log.h"
+#include "lldb/Utility/State.h"
+#include "lldb/Utility/Status.h"
+#include "llvm/Support/Errno.h"
+#include "llvm/Support/Error.h"
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+using namespace lldb;
+using namespace lldb_private;
+using namespace lldb_private::process_aix;
+using namespace llvm;
+
+static constexpr unsigned k_ptrace_word_size = sizeof(void *);
+static_assert(sizeof(long) >= k_ptrace_word_size,
+  "Size of long must be larger than ptrace word size");
+
+// Simple helper function to ensure flags are enabled on the given file
+// descriptor.
+static llvm::Error EnsureFDFlags(int fd, int flags) {
+  int status = fcntl(fd, F_GETFL);
+  if (status == -1)
+return errorCodeToError(errnoAsErrorCode());
+  if (fcntl(fd, F_SETFL, status | flags) == -1)
+return errorCodeToError(errnoAsErrorCode());
+  return Error::success();
+}
+
+NativeProcessAIX::Manager::Manager(MainLoop &mainloop)
+: NativeProcessProtocol::Manager(mainloop) {
+  Status status;
+  m_sigchld_handle = mainloop.RegisterSignal(
+  SIGCHLD, [this](MainLoopBase &) { SigchldHandler(); }, status);
+  assert(m_sigchld_handle && status.Success());
+}
+
+// Public Static Methods
+
+llvm::Expected>
+NativeProcessAIX::Manager::Launch(ProcessLaunchInfo &launch_info,
+  NativeDelegate &native_delegate) {
+  Log *log = GetLog(POSIXLog::Process);
+
+  Status status;
+  ::pid_t pid = ProcessLauncherPosixFork()
+.LaunchProcess(launch_info, status)
+.GetProcessId();
+  LLDB_LOG(log, "pid = {0:x}", pid);
+  if (status.Fail()) {
+LLDB_LOG(log, "failed to launch process: {0}", status);
+return status.ToError();
+  }
+
+  // Wait for the child process to trap on its call to execve.
+  int wstatus = 0;
+  ::pid_t wpid = llvm::sys::RetryAfterSignal(-1, ::waitpid, pid, &wstatus, 0);
+  assert(wpid == pid);
+  UNUSED_IF_ASSERT_DISABLED(wpid);
+  if (!WIFSTOPPED(wstatus)) {
+LLDB_LOG(log, "Could not sync with inferior process: wstatus={1}",
+ WaitStatus::Decode(wstatus));
+return llvm::make_error("Could not sync with inferior 
process",
+ llvm::inconvertibleErrorCode());
+  }
+  LLDB_LOG(log, "inferior started, now in stopped state");
+
+  ProcessInstanceInfo Info;
+  if (!Host::GetProcessInfo(pid, Info)) {
+return llvm::make_error("Cannot get process architectrue",
+ llvm::inconvertibleErrorCode());
+  }
+
+  // Set the architecture to the exe architecture.
+  LLDB_LOG(log, "pid = {0}, detected architecture {1}", pid,
+   Info.GetArchitecture().GetArchitectureName());
+
+  return std::unique_ptr(new NativeProcessAIX(
+  pid, launch_info.GetPTY().ReleasePrimaryFileDescriptor(), 
native_delegate,
+  Info.GetArchitecture(), *this, {pid}));
+}
+
+llvm::Expected>
+NativeProcessAIX::Manager::Attach(
+lldb::pid_t pid, NativeProcessProtocol::NativeDelegate &native_delegate) {
+  Log *log = GetLog(POSIXLog::Process);
+  LLDB_LOG(log, "pid = {0:x}", pid);
+
+  ProcessInstanceInfo Info;
+  if (!Host::GetProcessInfo(pid, Info)) {
+return llvm::make_error("Cannot get process architectrue",
+ llvm::inconvertibleErrorCode());
+  }
+  auto tids_or = NativeProcessAIX::Attach(pid);
+  if (!tids_or)
+return tids_or.takeError();
+
+  return std::unique_ptr(new NativeProcessAIX(
+  pid, -1, native_delegate, Info.GetArchitecture(), *this, *tids_or));
+}
+
+lldb::addr_t NativeProcessAIX::GetSharedLibraryInfoAddress() {
+  return LLDB_INVALID_ADDRESS;
+}
+
+NativeProcessAIX::Extension
+NativeProcessAIX::Manager::GetSupportedExtensions() const {
+  NativeProcessAIX::Extension supported = {};
+
+  return supported;
+}
+
+void NativeProcessAIX::Manager::SigchldHandler() {}
+
+void NativeProcessAIX::Manager::CollectThread(::pid_t tid) {}
+
+// Public Instance Methods
+
+NativeProcessAIX::NativeProcessAIX(::pid_t pid, int terminal_fd,
+   NativeDelegate &delegate,
+   const ArchSpec &arch, Manager &manager,
+   llvm::ArrayRef<::pid_t> tids)
+: NativeProcessProtoc

[Lldb-commits] [lldb] [lldb-dap] Refactoring IOStream into Transport handler. (PR #130026)

2025-03-12 Thread Pavel Labath via lldb-commits


@@ -63,12 +64,12 @@ const char DEV_NULL[] = "/dev/null";
 
 namespace lldb_dap {
 
-DAP::DAP(llvm::StringRef client_name, llvm::StringRef path, std::ofstream *log,
- lldb::IOObjectSP input, lldb::IOObjectSP output, ReplMode repl_mode,
- std::vector pre_init_commands)
-: client_name(client_name), debug_adapter_path(path), log(log),
-  input(std::move(input)), output(std::move(output)),
-  broadcaster("lldb-dap"), exception_breakpoints(),
+DAP::DAP(llvm::StringRef path, std::ofstream *log,
+ const ReplMode default_repl_mode,
+ const std::vector &pre_init_commands,
+ llvm::StringRef client_name, Transport &transport)
+: debug_adapter_path(path), log(log), client_name(client_name),
+  transport(transport), broadcaster("lldb-dap"), exception_breakpoints(),
   pre_init_commands(std::move(pre_init_commands)),

labath wrote:

This `std::move` us a noop now that the argument is `const&`. if you want to 
keep it that way, then delete the move, though I actually think the original 
code was better as it lets the caller decide whether it needs its own copy of 
the argument or not (where as this guarantees there will be at least one copy 
operation)

https://github.com/llvm/llvm-project/pull/130026
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb][AIX] Added base files for NativeProcess Support for AIX (PR #118160)

2025-03-12 Thread Pavel Labath via lldb-commits


@@ -0,0 +1,256 @@
+//===-- NativeProcessAIX.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 "NativeProcessAIX.h"
+#include "Plugins/Process/POSIX/ProcessPOSIXLog.h"
+#include "lldb/Host/Host.h"
+#include "lldb/Host/HostProcess.h"
+#include "lldb/Host/ProcessLaunchInfo.h"
+#include "lldb/Host/posix/ProcessLauncherPosixFork.h"
+#include "lldb/Symbol/ObjectFile.h"
+#include "lldb/Utility/Log.h"
+#include "lldb/Utility/State.h"
+#include "lldb/Utility/Status.h"
+#include "llvm/Support/Errno.h"
+#include "llvm/Support/Error.h"
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+using namespace lldb;
+using namespace lldb_private;
+using namespace lldb_private::process_aix;
+using namespace llvm;
+
+static constexpr unsigned k_ptrace_word_size = sizeof(void *);
+static_assert(sizeof(long) >= k_ptrace_word_size,
+  "Size of long must be larger than ptrace word size");
+
+// Simple helper function to ensure flags are enabled on the given file
+// descriptor.
+static llvm::Error EnsureFDFlags(int fd, int flags) {
+  int status = fcntl(fd, F_GETFL);
+  if (status == -1)
+return errorCodeToError(errnoAsErrorCode());
+  if (fcntl(fd, F_SETFL, status | flags) == -1)
+return errorCodeToError(errnoAsErrorCode());
+  return Error::success();
+}
+
+NativeProcessAIX::Manager::Manager(MainLoop &mainloop)
+: NativeProcessProtocol::Manager(mainloop) {
+  Status status;
+  m_sigchld_handle = mainloop.RegisterSignal(
+  SIGCHLD, [this](MainLoopBase &) { SigchldHandler(); }, status);
+  assert(m_sigchld_handle && status.Success());
+}
+
+// Public Static Methods
+
+llvm::Expected>
+NativeProcessAIX::Manager::Launch(ProcessLaunchInfo &launch_info,
+  NativeDelegate &native_delegate) {
+  Log *log = GetLog(POSIXLog::Process);
+
+  Status status;
+  ::pid_t pid = ProcessLauncherPosixFork()
+.LaunchProcess(launch_info, status)
+.GetProcessId();
+  LLDB_LOG(log, "pid = {0:x}", pid);
+  if (status.Fail()) {
+LLDB_LOG(log, "failed to launch process: {0}", status);
+return status.ToError();
+  }
+
+  // Wait for the child process to trap on its call to execve.
+  int wstatus = 0;
+  ::pid_t wpid = llvm::sys::RetryAfterSignal(-1, ::waitpid, pid, &wstatus, 0);
+  assert(wpid == pid);
+  UNUSED_IF_ASSERT_DISABLED(wpid);
+  if (!WIFSTOPPED(wstatus)) {
+LLDB_LOG(log, "Could not sync with inferior process: wstatus={1}",
+ WaitStatus::Decode(wstatus));
+return llvm::make_error("Could not sync with inferior 
process",
+ llvm::inconvertibleErrorCode());
+  }
+  LLDB_LOG(log, "inferior started, now in stopped state");
+
+  ProcessInstanceInfo Info;
+  if (!Host::GetProcessInfo(pid, Info)) {
+return llvm::make_error("Cannot get process architectrue",
+ llvm::inconvertibleErrorCode());
+  }
+
+  // Set the architecture to the exe architecture.
+  LLDB_LOG(log, "pid = {0}, detected architecture {1}", pid,
+   Info.GetArchitecture().GetArchitectureName());
+
+  return std::unique_ptr(new NativeProcessAIX(
+  pid, launch_info.GetPTY().ReleasePrimaryFileDescriptor(), 
native_delegate,
+  Info.GetArchitecture(), *this, {pid}));
+}
+
+llvm::Expected>
+NativeProcessAIX::Manager::Attach(
+lldb::pid_t pid, NativeProcessProtocol::NativeDelegate &native_delegate) {
+  Log *log = GetLog(POSIXLog::Process);
+  LLDB_LOG(log, "pid = {0:x}", pid);
+
+  ProcessInstanceInfo Info;
+  if (!Host::GetProcessInfo(pid, Info)) {
+return llvm::make_error("Cannot get process architectrue",
+ llvm::inconvertibleErrorCode());
+  }
+  auto tids_or = NativeProcessAIX::Attach(pid);
+  if (!tids_or)
+return tids_or.takeError();
+
+  return std::unique_ptr(new NativeProcessAIX(
+  pid, -1, native_delegate, Info.GetArchitecture(), *this, *tids_or));
+}
+
+lldb::addr_t NativeProcessAIX::GetSharedLibraryInfoAddress() {
+  return LLDB_INVALID_ADDRESS;
+}
+
+NativeProcessAIX::Extension
+NativeProcessAIX::Manager::GetSupportedExtensions() const {
+  NativeProcessAIX::Extension supported = {};
+
+  return supported;
+}
+
+void NativeProcessAIX::Manager::SigchldHandler() {}
+
+void NativeProcessAIX::Manager::CollectThread(::pid_t tid) {}
+
+// Public Instance Methods
+
+NativeProcessAIX::NativeProcessAIX(::pid_t pid, int terminal_fd,
+   NativeDelegate &delegate,
+   const ArchSpec &arch, Manager &manager,
+   llvm::ArrayRef<::pid_t> tids)
+: NativeProcessProtoc

[Lldb-commits] [lldb] [lldb] Let languages see all SymbolContexts at once when filtering breakpoints (PR #129937)

2025-03-12 Thread Felipe de Azevedo Piovezan via lldb-commits

https://github.com/felipepiovezan closed 
https://github.com/llvm/llvm-project/pull/129937
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] fef0b8a - [lldb] Let languages see all SymbolContexts at once when filtering breakpoints (#129937)

2025-03-12 Thread via lldb-commits

Author: Felipe de Azevedo Piovezan
Date: 2025-03-12T07:22:24-03:00
New Revision: fef0b8a0ba58b56fc7ab54143e8d2f4c02938777

URL: 
https://github.com/llvm/llvm-project/commit/fef0b8a0ba58b56fc7ab54143e8d2f4c02938777
DIFF: 
https://github.com/llvm/llvm-project/commit/fef0b8a0ba58b56fc7ab54143e8d2f4c02938777.diff

LOG: [lldb] Let languages see all SymbolContexts at once when filtering 
breakpoints (#129937)

This allows languages to make decisions based on the whole set of symbol
contexts, giving them strictly more power than when they are only
allowed to see one at a time.

Added: 


Modified: 
lldb/include/lldb/Target/Language.h
lldb/source/Breakpoint/BreakpointResolver.cpp

Removed: 




diff  --git a/lldb/include/lldb/Target/Language.h 
b/lldb/include/lldb/Target/Language.h
index 38ca458159edc..b699a90aff8e4 100644
--- a/lldb/include/lldb/Target/Language.h
+++ b/lldb/include/lldb/Target/Language.h
@@ -354,14 +354,13 @@ class Language : public PluginInterface {
 
   virtual llvm::StringRef GetInstanceVariableName() { return {}; }
 
-  /// Returns true if this SymbolContext should be ignored when setting
-  /// breakpoints by line (number or regex). Helpful for languages that create
-  /// artificial functions without meaningful user code associated with them
-  /// (e.g. code that gets expanded in late compilation stages, like by
-  /// CoroSplitter).
-  virtual bool IgnoreForLineBreakpoints(const SymbolContext &) const {
-return false;
-  }
+  /// Given a symbol context list of matches which supposedly represent the
+  /// same file and line number in a CU, erases those that should be ignored
+  /// when setting breakpoints by line (number or regex). Helpful for languages
+  /// that create split a single source-line into many functions (e.g. call
+  /// sites transformed by CoroSplitter).
+  virtual void
+  FilterForLineBreakpoints(llvm::SmallVectorImpl &) const {}
 
   /// Returns a boolean indicating whether two symbol contexts are equal for 
the
   /// purposes of frame comparison. If the plugin has no opinion, it should

diff  --git a/lldb/source/Breakpoint/BreakpointResolver.cpp 
b/lldb/source/Breakpoint/BreakpointResolver.cpp
index 5fe544908c39e..91fdff4a455da 100644
--- a/lldb/source/Breakpoint/BreakpointResolver.cpp
+++ b/lldb/source/Breakpoint/BreakpointResolver.cpp
@@ -207,16 +207,15 @@ bool operator<(const SourceLoc lhs, const SourceLoc rhs) {
 void BreakpointResolver::SetSCMatchesByLine(
 SearchFilter &filter, SymbolContextList &sc_list, bool skip_prologue,
 llvm::StringRef log_ident, uint32_t line, std::optional column) {
-  llvm::SmallVector all_scs;
-
-  for (const auto &sc : sc_list) {
-if (Language::GetGlobalLanguageProperties()
-.GetEnableFilterForLineBreakpoints())
-  if (Language *lang = Language::FindPlugin(sc.GetLanguage());
-  lang && lang->IgnoreForLineBreakpoints(sc))
-continue;
-all_scs.push_back(sc);
-  }
+  llvm::SmallVector all_scs(sc_list.begin(), sc_list.end());
+
+  // Let the language plugin filter `sc_list`. Because all symbol contexts in
+  // sc_list are assumed to belong to the same File, Line and CU, the code 
below
+  // assumes they have the same language.
+  if (!sc_list.IsEmpty() && Language::GetGlobalLanguageProperties()
+.GetEnableFilterForLineBreakpoints())
+if (Language *lang = Language::FindPlugin(sc_list[0].GetLanguage()))
+  lang->FilterForLineBreakpoints(all_scs);
 
   while (all_scs.size()) {
 uint32_t closest_line = UINT32_MAX;



___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] Implement ANSI & Unicode aware string stripping & padding (PR #130878)

2025-03-12 Thread Jonas Devlieghere via lldb-commits


@@ -172,28 +175,99 @@ inline std::string 
FormatAnsiTerminalCodes(llvm::StringRef format,
   return fmt;
 }
 
+inline std::tuple
+FindNextAnsiSequence(llvm::StringRef str) {
+  llvm::StringRef left;
+  llvm::StringRef right = str;
+
+  while (!right.empty()) {
+const size_t start = right.find(ANSI_ESC_START);
+
+// ANSI_ESC_START not found.
+if (start == llvm::StringRef::npos)
+  return {str, {}, {}};
+
+// Split the string around the current ANSI_ESC_START.
+left = str.take_front(left.size() + start);
+llvm::StringRef escape = right.substr(start);
+right = right.substr(start + ANSI_ESC_START_LEN + 1);
+
+const size_t end = right.find_first_not_of("0123456789;");
+
+// ANSI_ESC_END found.
+if (end < right.size() && (right[end] == 'm' || right[end] == 'G'))
+  return {left, escape.take_front(ANSI_ESC_START_LEN + 1 + end + 1),
+  right.substr(end + 1)};
+
+// Maintain the invariant that str == left + right at the start of the 
loop.
+left = str.take_front(left.size() + ANSI_ESC_START_LEN + 1);
+  }
+
+  return {str, {}, {}};
+}
+
 inline std::string StripAnsiTerminalCodes(llvm::StringRef str) {
   std::string stripped;
   while (!str.empty()) {
-llvm::StringRef left, right;
-
-std::tie(left, right) = str.split(ANSI_ESC_START);
+auto [left, escape, right] = FindNextAnsiSequence(str);
 stripped += left;
+str = right;
+  }
+  return stripped;
+}
 
-// ANSI_ESC_START not found.
-if (left == str && right.empty())
-  break;
+inline std::string TrimAndPad(llvm::StringRef str, size_t visible_length,
+  char padding = ' ') {
+  std::string result;
+  result.reserve(visible_length);
+  size_t result_visibile_length = 0;
+
+  // Trim the string to the given visible length.
+  while (!str.empty()) {
+auto [left, escape, right] = FindNextAnsiSequence(str);
+str = right;
 
-size_t end = right.find_first_not_of("0123456789;");
-if (end < right.size() && (right[end] == 'm' || right[end] == 'G')) {
-  str = right.substr(end + 1);
-} else {
-  // ANSI_ESC_END not found.
-  stripped += ANSI_ESC_START;
-  str = right;
+// Compute the length of the string without escape codes. If it fits, 
append
+// it together with the invisible escape code.
+size_t column_width = llvm::sys::locale::columnWidth(left);
+if (result_visibile_length + column_width <= visible_length) {
+  result.append(left).append(escape);
+  result_visibile_length += column_width;
+  continue;
+}
+
+// The string doesn't fit but doesn't fit but doesn't contain unicode.
+// Append the substring that fits.
+if (column_width == left.size()) {
+  llvm::StringRef trimmed =
+  left.take_front(visible_length - result_visibile_length);
+  result.append(trimmed);
+  result_visibile_length += visible_length - result_visibile_length;
+  continue;
+}

JDevlieghere wrote:

Good point, I didn't consider that. 

https://github.com/llvm/llvm-project/pull/130878
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] Implement ANSI & Unicode aware string stripping & padding (PR #130878)

2025-03-12 Thread Jonas Devlieghere via lldb-commits

https://github.com/JDevlieghere updated 
https://github.com/llvm/llvm-project/pull/130878

>From e50c6aec3cdb5d30fa12b19709329b49036ae924 Mon Sep 17 00:00:00 2001
From: Jonas Devlieghere 
Date: Tue, 11 Mar 2025 18:59:50 -0700
Subject: [PATCH 1/2] [lldb] Implement ANSI & Unicode aware string stripping &
 padding

This PR implements a unicode and ANSI escape code aware function to trim
and pad strings. This is a break-out from #121860.
---
 lldb/include/lldb/Utility/AnsiTerminal.h| 102 +---
 lldb/unittests/Utility/AnsiTerminalTest.cpp |  49 ++
 2 files changed, 137 insertions(+), 14 deletions(-)

diff --git a/lldb/include/lldb/Utility/AnsiTerminal.h 
b/lldb/include/lldb/Utility/AnsiTerminal.h
index 1939c49c7b859..a49f6db26f7b7 100644
--- a/lldb/include/lldb/Utility/AnsiTerminal.h
+++ b/lldb/include/lldb/Utility/AnsiTerminal.h
@@ -70,9 +70,12 @@
 #define ANSI_1_CTRL(ctrl1) "\033["##ctrl1 ANSI_ESC_END
 #define ANSI_2_CTRL(ctrl1, ctrl2) "\033["##ctrl1 ";"##ctrl2 ANSI_ESC_END
 
+#define ANSI_ESC_START_LEN 2
+
 #include "llvm/ADT/ArrayRef.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Locale.h"
 
 #include 
 
@@ -172,28 +175,99 @@ inline std::string 
FormatAnsiTerminalCodes(llvm::StringRef format,
   return fmt;
 }
 
+inline std::tuple
+FindNextAnsiSequence(llvm::StringRef str) {
+  llvm::StringRef left;
+  llvm::StringRef right = str;
+
+  while (!right.empty()) {
+const size_t start = right.find(ANSI_ESC_START);
+
+// ANSI_ESC_START not found.
+if (start == llvm::StringRef::npos)
+  return {str, {}, {}};
+
+// Split the string around the current ANSI_ESC_START.
+left = str.take_front(left.size() + start);
+llvm::StringRef escape = right.substr(start);
+right = right.substr(start + ANSI_ESC_START_LEN + 1);
+
+const size_t end = right.find_first_not_of("0123456789;");
+
+// ANSI_ESC_END found.
+if (end < right.size() && (right[end] == 'm' || right[end] == 'G'))
+  return {left, escape.take_front(ANSI_ESC_START_LEN + 1 + end + 1),
+  right.substr(end + 1)};
+
+// Maintain the invariant that str == left + right at the start of the 
loop.
+left = str.take_front(left.size() + ANSI_ESC_START_LEN + 1);
+  }
+
+  return {str, {}, {}};
+}
+
 inline std::string StripAnsiTerminalCodes(llvm::StringRef str) {
   std::string stripped;
   while (!str.empty()) {
-llvm::StringRef left, right;
-
-std::tie(left, right) = str.split(ANSI_ESC_START);
+auto [left, escape, right] = FindNextAnsiSequence(str);
 stripped += left;
+str = right;
+  }
+  return stripped;
+}
 
-// ANSI_ESC_START not found.
-if (left == str && right.empty())
-  break;
+inline std::string TrimAndPad(llvm::StringRef str, size_t visible_length,
+  char padding = ' ') {
+  std::string result;
+  result.reserve(visible_length);
+  size_t result_visibile_length = 0;
+
+  // Trim the string to the given visible length.
+  while (!str.empty()) {
+auto [left, escape, right] = FindNextAnsiSequence(str);
+str = right;
 
-size_t end = right.find_first_not_of("0123456789;");
-if (end < right.size() && (right[end] == 'm' || right[end] == 'G')) {
-  str = right.substr(end + 1);
-} else {
-  // ANSI_ESC_END not found.
-  stripped += ANSI_ESC_START;
-  str = right;
+// Compute the length of the string without escape codes. If it fits, 
append
+// it together with the invisible escape code.
+size_t column_width = llvm::sys::locale::columnWidth(left);
+if (result_visibile_length + column_width <= visible_length) {
+  result.append(left).append(escape);
+  result_visibile_length += column_width;
+  continue;
+}
+
+// The string doesn't fit but doesn't fit but doesn't contain unicode.
+// Append the substring that fits.
+if (column_width == left.size()) {
+  llvm::StringRef trimmed =
+  left.take_front(visible_length - result_visibile_length);
+  result.append(trimmed);
+  result_visibile_length += visible_length - result_visibile_length;
+  continue;
+}
+
+// The string doesn't fit but contains unicode. Repeatedly trim the string
+// until it fits.
+llvm::StringRef trimmed = left;
+while (!trimmed.empty()) {
+  // This relies on columnWidth returning -2 for invalid/partial unicode
+  // characters, which after conversion to size_t will be larger than the
+  // visible width.
+  column_width = llvm::sys::locale::columnWidth(trimmed);
+  if (result_visibile_length + column_width <= visible_length) {
+result.append(trimmed);
+result_visibile_length += column_width;
+break;
+  }
+  trimmed = trimmed.drop_back();
 }
   }
-  return stripped;
+
+  // Pad the string.
+  if (result_visibile_length < visible_length)
+result.append(visible_length - result_visibile_length, padding);
+
+  return result;
 }
 
 } /

[Lldb-commits] [lldb] [lldb] Use Function::GetAddressRange*s* in "frame diagnose" (PR #130949)

2025-03-12 Thread Pavel Labath via lldb-commits

https://github.com/labath created 
https://github.com/llvm/llvm-project/pull/130949

No test because generating discontinous functions is tedious and there's 
nothing particularly interesting happening in here. As long as the analyzer 
stays within a single basic block. it doesn't really care whether the function 
is discontinous or not. I could create cases where the algorithm breaks when 
going across basic blocks, but that's more of inherent limitation of the 
algorithm (the inability to follow jumps "backwards") than something specific 
to discontinous functions.

At this point, I'm more interested in cleaning up the last few remaining uses 
of the deprecated function that I'm about improving "frame diagnose".

>From 58754f4359d54373aa798314dd79bf3fe0dd5bc0 Mon Sep 17 00:00:00 2001
From: Pavel Labath 
Date: Wed, 12 Mar 2025 13:06:48 +0100
Subject: [PATCH] [lldb] Use Function::GetAddressRange*s* in "frame diagnose"

No test because generating discontinous functions is tedious and there's
nothing particularly interesting happening in here. As long as the
analyzer stays within a single basic block. it doesn't really care
whether the function is discontinous or not. I could create cases the
algorithm breaks when going across basic blocks, but that's more of
inherent limitation of the algorithm (the inability to follow jumps
"backwards") than something specific to discontinous functions.

At this point, I'm more interested in cleaning up the last few remaining
uses of the deprecated function that I'm about improving "frame
diagnose".
---
 lldb/source/Target/StackFrame.cpp | 16 ++--
 1 file changed, 6 insertions(+), 10 deletions(-)

diff --git a/lldb/source/Target/StackFrame.cpp 
b/lldb/source/Target/StackFrame.cpp
index d92b7d8b9d899..bab36e9aa1033 100644
--- a/lldb/source/Target/StackFrame.cpp
+++ b/lldb/source/Target/StackFrame.cpp
@@ -1783,15 +1783,11 @@ lldb::ValueObjectSP 
StackFrame::GuessValueForRegisterAndOffset(ConstString reg,
 return ValueObjectSP();
   }
 
-  AddressRange pc_range = function->GetAddressRange();
-
-  if (GetFrameCodeAddress().GetFileAddress() <
-  pc_range.GetBaseAddress().GetFileAddress() ||
-  GetFrameCodeAddress().GetFileAddress() -
-  pc_range.GetBaseAddress().GetFileAddress() >=
-  pc_range.GetByteSize()) {
+  AddressRange unused_range;
+  if (!function->GetRangeContainingLoadAddress(
+  GetFrameCodeAddress().GetLoadAddress(target_sp.get()), *target_sp,
+  unused_range))
 return ValueObjectSP();
-  }
 
   const char *plugin_name = nullptr;
   const char *flavor = nullptr;
@@ -1799,8 +1795,8 @@ lldb::ValueObjectSP 
StackFrame::GuessValueForRegisterAndOffset(ConstString reg,
   const char *features = nullptr;
   const bool force_live_memory = true;
   DisassemblerSP disassembler_sp = Disassembler::DisassembleRange(
-  target_arch, plugin_name, flavor, cpu, features, *target_sp, pc_range,
-  force_live_memory);
+  target_arch, plugin_name, flavor, cpu, features, *target_sp,
+  function->GetAddressRanges(), force_live_memory);
 
   if (!disassembler_sp || !disassembler_sp->GetInstructionList().GetSize()) {
 return ValueObjectSP();

___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb-dap] Support vscode launch URLs (PR #125843)

2025-03-12 Thread Adrian Vogelsgesang via lldb-commits


@@ -0,0 +1,37 @@
+import * as vscode from "vscode";
+
+export class LaunchUriHandler implements vscode.UriHandler {
+async handleUri(uri: vscode.Uri) {
+try {
+const params = new URLSearchParams(uri.query);
+if (uri.path == '/launch/config') {
+const configJson = params.get("config");
+if (configJson === null) {
+throw new Error("Missing `config` URI parameter");
+}
+// Build the debug config
+let debugConfig: vscode.DebugConfiguration = {
+type: 'lldb-dap',
+request: 'launch',
+name: '',
+};
+Object.assign(debugConfig, JSON.parse(configJson));

vogelsgesang wrote:

> I meant the type validation in the c++ land, we do some basic checks on the 
> types but we don't really report errors if something fails, for example:

Agree, we should probably verify the launch configurations in C++ more closely. 
I think we should take a similar approach to #130090 also for our launch 
config. That would be a different PR, though.

> We could do a basic sanity check on the typescript side of things to see if 
> the URL parameters look like they're correct.

I think we should keep the TypeScript layer as thin as possible. Implementing 
the validation in C++ has the benefit that it is reusable across clients (not 
only VS-Code). Furthermore, testing the C++ code is much easier. We have no 
test infrastructure in place for our TypeScript code

https://github.com/llvm/llvm-project/pull/125843
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [LLDB][Telemetry]Define TargetInfo for collecting data about a target (PR #127834)

2025-03-12 Thread Vy Nguyen via lldb-commits

oontvoo wrote:

> Define "target". 

"target" == the thing to be debugged. Eg.., `lldb ` or (after starting 
lldb, you'd do `target create `).

> Define "loading a target". When a process does an execve is it still the same 
> target (as far as the rest of lldb is concerned, it is, even though it starts 
> executing a different binary)?

I think by "loading" i mean the time it takes from "target create" command till 
when lldb command prompt is ready to accept the next command. (Admitted, in 
this implementation, it's not quite measuring that since that's a bit more 
tricky to instrument, so I settled to the closest thing, which was around 
initting the main executable).

Can you clarify your definition of "target" ? :) You're saying a "target" could 
have *different* main-executable ("different binary")?? How would that use case 
look? 

I understand you could do something like
```
~/home/ $ lldb  # << start LLDB w/o specifying a debug target
< ... inside lldb prompt >
0: (lldb) target create path/to/MyTarget
1:  (lldb) run  
< finish>
2: (lldb) run
< ... finish >
3: (lldb) run
```

Same target, 3 different "runs" but still the same *binary*.
In other words, we would have had 1 target,  3 (different) processes (ie., 
different PIDs), 3 exit statuses (one for each of those processes).

Is this the right characterisation?
 
So maybe the data can be restructured to:
```
TargetInfo {
  + target_id;
  + target_name; /// (ie., the  argument)
  + (other related stuff like platform, arch, etc)

  + init_time_duration: Ideally, measuring the time it takes from "target 
create" till ready. (or just initting the main exec)
  // The following two is less important, but could be interesting
  + start_timestamp: When the target was first created
  + exit_timestamp: when the target is deleted 
}

ProcessInfo {
   + target_id; /// The ID of the Target object that this process belongs to
   + exit_status
}
 
```



https://github.com/llvm/llvm-project/pull/127834
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] Implement ANSI & Unicode aware string stripping & padding (PR #130878)

2025-03-12 Thread Pavel Labath via lldb-commits

https://github.com/labath approved this pull request.


https://github.com/llvm/llvm-project/pull/130878
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] Implement ANSI & Unicode aware string stripping & padding (PR #130878)

2025-03-12 Thread Pavel Labath via lldb-commits


@@ -172,28 +175,99 @@ inline std::string 
FormatAnsiTerminalCodes(llvm::StringRef format,
   return fmt;
 }
 
+inline std::tuple
+FindNextAnsiSequence(llvm::StringRef str) {
+  llvm::StringRef left;
+  llvm::StringRef right = str;
+
+  while (!right.empty()) {
+const size_t start = right.find(ANSI_ESC_START);
+
+// ANSI_ESC_START not found.
+if (start == llvm::StringRef::npos)
+  return {str, {}, {}};
+
+// Split the string around the current ANSI_ESC_START.
+left = str.take_front(left.size() + start);
+llvm::StringRef escape = right.substr(start);
+right = right.substr(start + ANSI_ESC_START_LEN + 1);
+
+const size_t end = right.find_first_not_of("0123456789;");
+
+// ANSI_ESC_END found.
+if (end < right.size() && (right[end] == 'm' || right[end] == 'G'))
+  return {left, escape.take_front(ANSI_ESC_START_LEN + 1 + end + 1),
+  right.substr(end + 1)};
+
+// Maintain the invariant that str == left + right at the start of the 
loop.
+left = str.take_front(left.size() + ANSI_ESC_START_LEN + 1);
+  }
+
+  return {str, {}, {}};
+}
+
 inline std::string StripAnsiTerminalCodes(llvm::StringRef str) {
   std::string stripped;
   while (!str.empty()) {
-llvm::StringRef left, right;
-
-std::tie(left, right) = str.split(ANSI_ESC_START);
+auto [left, escape, right] = FindNextAnsiSequence(str);
 stripped += left;
+str = right;
+  }
+  return stripped;
+}
 
-// ANSI_ESC_START not found.
-if (left == str && right.empty())
-  break;
+inline std::string TrimAndPad(llvm::StringRef str, size_t visible_length,
+  char padding = ' ') {
+  std::string result;
+  result.reserve(visible_length);
+  size_t result_visibile_length = 0;
+
+  // Trim the string to the given visible length.
+  while (!str.empty()) {
+auto [left, escape, right] = FindNextAnsiSequence(str);
+str = right;
 
-size_t end = right.find_first_not_of("0123456789;");
-if (end < right.size() && (right[end] == 'm' || right[end] == 'G')) {
-  str = right.substr(end + 1);
-} else {
-  // ANSI_ESC_END not found.
-  stripped += ANSI_ESC_START;
-  str = right;
+// Compute the length of the string without escape codes. If it fits, 
append
+// it together with the invisible escape code.
+size_t column_width = llvm::sys::locale::columnWidth(left);
+if (result_visibile_length + column_width <= visible_length) {
+  result.append(left).append(escape);
+  result_visibile_length += column_width;
+  continue;
+}
+
+// The string doesn't fit but doesn't fit but doesn't contain unicode.
+// Append the substring that fits.
+if (column_width == left.size()) {
+  llvm::StringRef trimmed =
+  left.take_front(visible_length - result_visibile_length);
+  result.append(trimmed);
+  result_visibile_length += visible_length - result_visibile_length;
+  continue;
+}

labath wrote:

I think this optimization is not correct due to unicode characters which take 
up two spaces. If they're encoded using two bytes then this check will pass, 
but it's not legal to split it in half.

https://github.com/llvm/llvm-project/pull/130878
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] Use Function::GetAddressRange*s* in "frame diagnose" (PR #130949)

2025-03-12 Thread David Spickett via lldb-commits

https://github.com/DavidSpickett approved this pull request.

Updating the API, not trying to add anything new to frame diagnose, sounds good 
to me.

https://github.com/llvm/llvm-project/pull/130949
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb][AIX] Added base files for NativeProcess Support for AIX (PR #118160)

2025-03-12 Thread Pavel Labath via lldb-commits


@@ -0,0 +1,256 @@
+//===-- NativeProcessAIX.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 "NativeProcessAIX.h"
+#include "Plugins/Process/POSIX/ProcessPOSIXLog.h"
+#include "lldb/Host/Host.h"
+#include "lldb/Host/HostProcess.h"
+#include "lldb/Host/ProcessLaunchInfo.h"
+#include "lldb/Host/posix/ProcessLauncherPosixFork.h"
+#include "lldb/Symbol/ObjectFile.h"
+#include "lldb/Utility/Log.h"
+#include "lldb/Utility/State.h"
+#include "lldb/Utility/Status.h"
+#include "llvm/Support/Errno.h"
+#include "llvm/Support/Error.h"
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+using namespace lldb;
+using namespace lldb_private;
+using namespace lldb_private::process_aix;
+using namespace llvm;
+
+static constexpr unsigned k_ptrace_word_size = sizeof(void *);
+static_assert(sizeof(long) >= k_ptrace_word_size,
+  "Size of long must be larger than ptrace word size");
+
+// Simple helper function to ensure flags are enabled on the given file
+// descriptor.
+static llvm::Error EnsureFDFlags(int fd, int flags) {
+  int status = fcntl(fd, F_GETFL);
+  if (status == -1)
+return errorCodeToError(errnoAsErrorCode());
+  if (fcntl(fd, F_SETFL, status | flags) == -1)
+return errorCodeToError(errnoAsErrorCode());
+  return Error::success();
+}
+
+NativeProcessAIX::Manager::Manager(MainLoop &mainloop)
+: NativeProcessProtocol::Manager(mainloop) {
+  Status status;
+  m_sigchld_handle = mainloop.RegisterSignal(
+  SIGCHLD, [this](MainLoopBase &) { SigchldHandler(); }, status);
+  assert(m_sigchld_handle && status.Success());
+}
+
+// Public Static Methods
+
+llvm::Expected>
+NativeProcessAIX::Manager::Launch(ProcessLaunchInfo &launch_info,
+  NativeDelegate &native_delegate) {
+  Log *log = GetLog(POSIXLog::Process);
+
+  Status status;
+  ::pid_t pid = ProcessLauncherPosixFork()
+.LaunchProcess(launch_info, status)
+.GetProcessId();
+  LLDB_LOG(log, "pid = {0:x}", pid);
+  if (status.Fail()) {
+LLDB_LOG(log, "failed to launch process: {0}", status);
+return status.ToError();
+  }
+
+  // Wait for the child process to trap on its call to execve.
+  int wstatus = 0;
+  ::pid_t wpid = llvm::sys::RetryAfterSignal(-1, ::waitpid, pid, &wstatus, 0);
+  assert(wpid == pid);
+  UNUSED_IF_ASSERT_DISABLED(wpid);
+  if (!WIFSTOPPED(wstatus)) {
+LLDB_LOG(log, "Could not sync with inferior process: wstatus={1}",
+ WaitStatus::Decode(wstatus));
+return llvm::make_error("Could not sync with inferior 
process",
+ llvm::inconvertibleErrorCode());
+  }
+  LLDB_LOG(log, "inferior started, now in stopped state");
+
+  ProcessInstanceInfo Info;
+  if (!Host::GetProcessInfo(pid, Info)) {
+return llvm::make_error("Cannot get process architectrue",
+ llvm::inconvertibleErrorCode());
+  }
+
+  // Set the architecture to the exe architecture.
+  LLDB_LOG(log, "pid = {0}, detected architecture {1}", pid,
+   Info.GetArchitecture().GetArchitectureName());

labath wrote:

This is kind of a hack. It would be better to determine the architecture of the 
process (basically, whether it's 32 or 64 bit) through ptrace, but linux does 
it this way because there's no good way to do that via ptrace. The situation 
may be different (better) on AIX.

In any case, since you're only supporting 64 bit processes now, it may be 
better to just hardcode AIX  (via a call to `HostInfo::GetArchitecture`) for now

https://github.com/llvm/llvm-project/pull/118160
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [LLDB][Telemetry]Define TargetInfo for collecting data about a target (PR #127834)

2025-03-12 Thread Pavel Labath via lldb-commits

labath wrote:

> > Define "target".
> 
> "target" == the thing to be debugged. Eg.., `lldb ` or (after 
> starting lldb, you'd do `target create `).

Okay. So far, so good.

> 
> > Define "loading a target". When a process does an execve is it still the 
> > same target (as far as the rest of lldb is concerned, it is, even though it 
> > starts executing a different binary)?
> 
> I think by "loading" i mean the time it takes from "target create" command 
> till when lldb command prompt is ready to accept the next command. (Admitted, 
> in this implementation, it's not quite measuring that since that's a bit more 
> tricky to instrument, so I settled to the closest thing, which was around 
> initting the main executable).

This is where it gets tricky. I know you want that, but I don't think that 
*all* you want (if it was, you may not even need this patch since it's kind of 
implicitly measured by the command interpreter telemetry). I think you also 
want to handle cases where the target is created through SB API.  If *that* was 
all you wanted, then the best place to instrument might be something like 
`TargetList::CreateTarget`. However, there is also the case of attaching, in 
which case you first create a [target without an 
executable](https://github.com/llvm/llvm-project/blob/665299eb3e7a142199e2c22eb294c5e01ef1655d/lldb/source/Commands/CommandObjectProcess.cpp#L334)
 and later set the executable [once you've attached to the running 
process](https://github.com/llvm/llvm-project/blob/665299eb3e7a142199e2c22eb294c5e01ef1655d/lldb/source/Commands/CommandObjectProcess.cpp#L361).
 There are also other cases (loading a core file (`target create --core`), 
connecting to a remote debug server (`process connect`)), which look like 
"attaching" in some ways, but go through slightly different paths.

This is why I suggested way back to focus on SetExecutableModule, as that is 
(one) place where all of these paths converge, and it covers the most expensive 
part of the operation. I don't think it's the only way to capture all this 
information, but I still think it's *a* way to do it. However, it's definitely 
not the same as "loading/creating a target".

> 
> Can you clarify your definition of "target" ? :) You're saying a "target" 
> could have _different_ main-executable ("different binary")?? How would that 
> use case look?

I can give you at least three:
1. execve
```
$ head *.c
==> ping.c <==
int main() { execlp("./pong", "pong", 0); }

==> pong.c <==
int main() { execlp("./ping", "ping", 0); }
$ lldb ./ping
(lldb) target create "./ping"
Current executable set to '/tmp/ping' (x86_64).
(lldb) process launch --stop-at-entry 
Process 14214 stopped
* thread #1, name = 'ping', stop reason = signal SIGSTOP
frame #0: 0x77fe2bc0 ld-linux-x86-64.so.2`_start
ld-linux-x86-64.so.2`_start:
->  0x77fe2bc0 <+0>: movq   %rsp, %rdi
0x77fe2bc3 <+3>: callq  0x77fe38c0 ; _dl_start

ld-linux-x86-64.so.2`_dl_start_user:
0x77fe2bc8 <+0>: movq   %rax, %r12
0x77fe2bcb <+3>: movq   %rsp, %r13
Process 14214 launched: '/tmp/ping' (x86_64)
(lldb) target list
Current targets:
* target #0: /tmp/ping ( arch=x86_64-pc-linux-gnu, platform=host, pid=14214, 
state=stopped )
### We are executing "ping" now
(lldb) c
Process 14214 resuming
Process 14214 stopped
* thread #1, name = 'pong', stop reason = exec
frame #0: 0x77fe2bc0 ld-linux-x86-64.so.2`_start
ld-linux-x86-64.so.2`_start:
->  0x77fe2bc0 <+0>: movq   %rsp, %rdi
0x77fe2bc3 <+3>: callq  0x77fe38c0 ; _dl_start

ld-linux-x86-64.so.2`_dl_start_user:
0x77fe2bc8 <+0>: movq   %rax, %r12
0x77fe2bcb <+3>: movq   %rsp, %r13
(lldb) target list
Current targets:
* target #0: /tmp/pong ( arch=x86_64-pc-linux-gnu, platform=host, pid=14214, 
state=stopped )
# Same target, same pid, but a different executable -- SetExecutableModule was 
called to switch the new image
(lldb) c
Process 14214 resuming
Process 14214 stopped
* thread #1, name = 'ping', stop reason = exec
frame #0: 0x77fe2bc0 ld-linux-x86-64.so.2`_start
ld-linux-x86-64.so.2`_start:
->  0x77fe2bc0 <+0>: movq   %rsp, %rdi
0x77fe2bc3 <+3>: callq  0x77fe38c0 ; _dl_start

ld-linux-x86-64.so.2`_dl_start_user:
0x77fe2bc8 <+0>: movq   %rax, %r12
0x77fe2bcb <+3>: movq   %rsp, %r13
(lldb) target list
Current targets:
* target #0: /tmp/ping ( arch=x86_64-pc-linux-gnu, platform=host, pid=14214, 
state=stopped )
# Still the same target, but now we're back to the first binary => Another 
SetExecutableModule call
```
2. Guessing the wrong binary when attaching:
```
$ lldb /bin/ls
(lldb) target create "/bin/ls"
Current executable set to '/bin/ls' (x86_64).
# One SetExecutableModule call here
(lldb) process attach -p 14329
Process 14329 stopped
* thread #1, name = 'cat', stop reason = signal SIGSTOP
frame #0: 0x7f337699c1d1 libc.so.6`read + 17
libc.so.6`read:
->  0x7f337699c1d1 <+17>: cmpq   $-0x1000, %rax ; imm = 0x

[Lldb-commits] [lldb] [lldb-dap] Support vscode launch URLs (PR #125843)

2025-03-12 Thread John Harrison via lldb-commits

https://github.com/ashgti approved this pull request.

Looks great!

https://github.com/llvm/llvm-project/pull/125843
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb-dap] Updating RequestHandler to encode/decode arguments and response. (PR #130090)

2025-03-12 Thread Jonas Devlieghere via lldb-commits


@@ -240,6 +240,137 @@ using Message = std::variant;
 bool fromJSON(const llvm::json::Value &, Message &, llvm::json::Path);
 llvm::json::Value toJSON(const Message &);
 
+// MARK: Types
+
+// "Source": {
+//   "type": "object",
+//   "description": "A `Source` is a descriptor for source code.\nIt is 
returned
+//   from the debug adapter as part of a `StackFrame` and it is used by clients
+//   when specifying breakpoints.", "properties": {
+// "name": {
+//   "type": "string",
+//   "description": "The short name of the source. Every source returned
+//   from the debug adapter has a name.\nWhen sending a source to the debug
+//   adapter this name is optional."
+// },
+// "path": {
+//   "type": "string",
+//   "description": "The path of the source to be shown in the UI.\nIt is
+//   only used to locate and load the content of the source if no
+//   `sourceReference` is specified (or its value is 0)."
+// },
+// "sourceReference": {
+//   "type": "integer",
+//   "description": "If the value > 0 the contents of the source must be
+//   retrieved through the `source` request (even if a path is
+//   specified).\nSince a `sourceReference` is only valid for a session, it
+//   can not be used to persist a source.\nThe value should be less than or
+//   equal to 2147483647 (2^31-1)."
+// },
+// "presentationHint": {
+//   "type": "string",
+//   "description": "A hint for how to present the source in the UI.\nA
+//   value of `deemphasize` can be used to indicate that the source is not
+//   available or that it is skipped on stepping.", "enum": [ "normal",
+//   "emphasize", "deemphasize" ]
+// },
+// "origin": {
+//   "type": "string",
+//   "description": "The origin of this source. For example, 'internal
+//   module', 'inlined content from source map', etc."
+// },
+// "sources": {
+//   "type": "array",
+//   "items": {
+// "$ref": "#/definitions/Source"
+//   },
+//   "description": "A list of sources that are related to this source.
+//   These may be the source that generated this source."
+// },
+// "adapterData": {
+//   "type": [ "array", "boolean", "integer", "null", "number", "object",
+//   "string" ], "description": "Additional data that a debug adapter might
+//   want to loop through the client.\nThe client should leave the data
+//   intact and persist it across sessions. The client should not interpret
+//   the data."
+// },
+// "checksums": {
+//   "type": "array",
+//   "items": {
+// "$ref": "#/definitions/Checksum"
+//   },
+//   "description": "The checksums associated with this file."
+// }
+//   }
+// },
+struct Source {
+  enum class PresentationHint { normal, emphasize, deemphasize };
+
+  std::optional name;
+  std::optional path;
+  std::optional sourceReference;
+  std::optional presentationHint;
+
+  // unsupproted keys origin, sources, adapterData, checksums
+};
+bool fromJSON(const llvm::json::Value &, Source &, llvm::json::Path);
+llvm::json::Value toJSON(const Source &);
+
+// MARK: Requests
+
+// "SourceArguments": {
+//   "type": "object",
+//   "description": "Arguments for `source` request.",
+//   "properties": {
+// "source": {
+//   "$ref": "#/definitions/Source",
+//   "description": "Specifies the source content to load. Either
+//   `source.path` or `source.sourceReference` must be specified."
+// },
+// "sourceReference": {
+//   "type": "integer",
+//   "description": "The reference to the source. This is the same as
+//   `source.sourceReference`.\nThis is provided for backward compatibility
+//   since old clients do not understand the `source` attribute."
+// }
+//   },
+//   "required": [ "sourceReference" ]
+// },
+struct SourceArguments {
+  std::optional source;
+  int64_t sourceReference;
+};
+bool fromJSON(const llvm::json::Value &, SourceArguments &, llvm::json::Path);
+
+// "SourceResponse": {
+//   "allOf": [ { "$ref": "#/definitions/Response" }, {
+// "type": "object",
+// "description": "Response to `source` request.",
+// "properties": {
+//   "body": {
+// "type": "object",
+// "properties": {
+//   "content": {
+// "type": "string",
+// "description": "Content of the source reference."
+//   },
+//   "mimeType": {
+// "type": "string",
+// "description": "Content type (MIME type) of the source."
+//   }
+// },
+// "required": [ "content" ]
+//   }
+// },
+// "required": [ "body" ]
+//   }]
+// },
+struct SourceResponseBody {
+  std::string content;
+  std::optional mimeType;
+};

JDevlieghere wrote:

I agree with the reasoning and I'm on board with removing it.

https://github.com/llvm/llvm-project/pull/1300

[Lldb-commits] [lldb] [lldb-dap] Refactoring IOStream into Transport handler. (PR #130026)

2025-03-12 Thread Jonas Devlieghere via lldb-commits


@@ -210,12 +209,33 @@ struct DAP {
   // will contain that expression.
   std::string last_nonempty_var_expression;
 
-  DAP(llvm::StringRef client_name, llvm::StringRef path, std::ofstream *log,
-  lldb::IOObjectSP input, lldb::IOObjectSP output, ReplMode repl_mode,
-  std::vector pre_init_commands);
+  /// Creates a new DAP sessions.
+  ///
+  /// \param[in] path
+  /// Path to the lldb-dap binary.
+  /// \param[in] log
+  /// Log file stream, if configured.
+  /// \param[in] default_repl_mode
+  /// Default repl mode behavior, as configured by the binary.
+  /// \param[in] pre_init_commands
+  /// LLDB commands to execute as soon as the debugger instance is 
allocaed.
+  /// \param[in] client_name
+  /// Debug session client name, for example 'stdin/stdout' or 'client_1'.

JDevlieghere wrote:

What's the reason for moving the `path` and `client_name` apart? 

https://github.com/llvm/llvm-project/pull/130026
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] Update dwim-print to show expanded objc instances (PR #117500)

2025-03-12 Thread Dave Lee via lldb-commits

https://github.com/kastiglione updated 
https://github.com/llvm/llvm-project/pull/117500

>From 3199d3ee3817a8551cda1f5fce6083fef1c079d9 Mon Sep 17 00:00:00 2001
From: Dave Lee 
Date: Sat, 23 Nov 2024 18:25:22 -0800
Subject: [PATCH 1/4] [lldb] Update dwim-print to show expanded objc instances

When printing an ObjC object, which is a pointer, lldb has handled it like it 
treats any
other pointer, printing only pointer address and class name. The object is not 
expanded,
and its children are not shown.

This change updates the dwim-print to print expanded objc pointers - it is 
assumed
that's what the user meant.

Note that this is currently possible using the `--ptr-depth`/`-P` flag, but the 
default
is 0. With this change, when dwim-print prints objc objects, the default is 
effectively
changed to 1.
---
 .../lldb/DataFormatters/DumpValueObjectOptions.h |  3 +++
 lldb/source/Commands/CommandObjectDWIMPrint.cpp  |  3 ++-
 .../DataFormatters/DumpValueObjectOptions.cpp|  6 ++
 .../source/DataFormatters/ValueObjectPrinter.cpp | 14 --
 lldb/test/API/commands/dwim-print/objc/Makefile  |  3 +++
 .../dwim-print/objc/TestDWIMPrintObjC.py | 16 
 lldb/test/API/commands/dwim-print/objc/main.m| 15 +++
 7 files changed, 53 insertions(+), 7 deletions(-)
 create mode 100644 lldb/test/API/commands/dwim-print/objc/Makefile
 create mode 100644 lldb/test/API/commands/dwim-print/objc/TestDWIMPrintObjC.py
 create mode 100644 lldb/test/API/commands/dwim-print/objc/main.m

diff --git a/lldb/include/lldb/DataFormatters/DumpValueObjectOptions.h 
b/lldb/include/lldb/DataFormatters/DumpValueObjectOptions.h
index c7f8116c4..7e213f29b3bc0 100644
--- a/lldb/include/lldb/DataFormatters/DumpValueObjectOptions.h
+++ b/lldb/include/lldb/DataFormatters/DumpValueObjectOptions.h
@@ -125,6 +125,8 @@ class DumpValueObjectOptions {
 
   DumpValueObjectOptions &SetRevealEmptyAggregates(bool reveal = true);
 
+  DumpValueObjectOptions &SetExpandPointerTypeFlags(unsigned flags);
+
   DumpValueObjectOptions &SetElementCount(uint32_t element_count = 0);
 
   DumpValueObjectOptions &
@@ -142,6 +144,7 @@ class DumpValueObjectOptions {
   DeclPrintingHelper m_decl_printing_helper;
   ChildPrintingDecider m_child_printing_decider;
   PointerAsArraySettings m_pointer_as_array;
+  unsigned m_expand_ptr_type_flags = 0;
   bool m_use_synthetic : 1;
   bool m_scope_already_checked : 1;
   bool m_flat_output : 1;
diff --git a/lldb/source/Commands/CommandObjectDWIMPrint.cpp 
b/lldb/source/Commands/CommandObjectDWIMPrint.cpp
index 62c4e74d853ad..8bfef15036cc7 100644
--- a/lldb/source/Commands/CommandObjectDWIMPrint.cpp
+++ b/lldb/source/Commands/CommandObjectDWIMPrint.cpp
@@ -87,7 +87,8 @@ void CommandObjectDWIMPrint::DoExecute(StringRef command,
 
   DumpValueObjectOptions dump_options = m_varobj_options.GetAsDumpOptions(
   m_expr_options.m_verbosity, m_format_options.GetFormat());
-  dump_options.SetHideRootName(suppress_result);
+  dump_options.SetHideRootName(suppress_result)
+  .SetExpandPointerTypeFlags(lldb::eTypeIsObjC);
 
   bool is_po = m_varobj_options.use_objc;
 
diff --git a/lldb/source/DataFormatters/DumpValueObjectOptions.cpp 
b/lldb/source/DataFormatters/DumpValueObjectOptions.cpp
index 18d590d47d9a0..a4db0d3cb240f 100644
--- a/lldb/source/DataFormatters/DumpValueObjectOptions.cpp
+++ b/lldb/source/DataFormatters/DumpValueObjectOptions.cpp
@@ -201,6 +201,12 @@ DumpValueObjectOptions::SetRevealEmptyAggregates(bool 
reveal) {
   return *this;
 }
 
+DumpValueObjectOptions &
+DumpValueObjectOptions::SetExpandPointerTypeFlags(unsigned flags) {
+  m_expand_ptr_type_flags = flags;
+  return *this;
+}
+
 DumpValueObjectOptions &
 DumpValueObjectOptions::SetElementCount(uint32_t element_count) {
   m_pointer_as_array = PointerAsArraySettings(element_count);
diff --git a/lldb/source/DataFormatters/ValueObjectPrinter.cpp 
b/lldb/source/DataFormatters/ValueObjectPrinter.cpp
index face38253efab..83db9292c5e76 100644
--- a/lldb/source/DataFormatters/ValueObjectPrinter.cpp
+++ b/lldb/source/DataFormatters/ValueObjectPrinter.cpp
@@ -554,12 +554,14 @@ bool ValueObjectPrinter::ShouldPrintChildren(
   return false;
 
 const bool is_root_level = m_curr_depth == 0;
-
-if (is_ref && is_root_level && print_children) {
-  // If this is the root object (depth is zero) that we are showing and
-  // it is a reference, and no pointer depth has been supplied print out
-  // what it references. Don't do this at deeper depths otherwise we can
-  // end up with infinite recursion...
+const bool is_expanded_ptr =
+is_ptr && m_type_flags.Test(m_options.m_expand_ptr_type_flags);
+
+if ((is_ref || is_expanded_ptr) && is_root_level && print_children) {
+  // If this is the root object (depth is zero) that we are showing and it
+  // is either a reference or a preferred type of pointer, then print it.
+  // Don't do this at deeper depths otherwise we can e

[Lldb-commits] [lldb] [lldb] Do not bump memory modificator ID when "internal" debugger memory is updated (PR #129092)

2025-03-12 Thread via lldb-commits

jimingham wrote:

When we define a variable in the expression parser, like:

(lldb) expr SomeStruct $mine = {10, 20, 30}

we allocate memory in the target (in the allocated memory cache.)  When we go 
to update that variable in the expression parser, we need to write a new value 
into the allocated memory.  Does that process still work with your change such 
that we see the correct new value for the variable?

https://github.com/llvm/llvm-project/pull/129092
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb-dap] Support vscode launch URLs (PR #125843)

2025-03-12 Thread Adrian Vogelsgesang via lldb-commits

vogelsgesang wrote:

@ashgti @walter-erquinigo could you take another look at this PR? Afaict, all 
comments should be addressed and this PR is (hopefully) ready to be merged

https://github.com/llvm/llvm-project/pull/125843
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb][AIX] Added base files for NativeProcess Support for AIX (PR #118160)

2025-03-12 Thread Dhruv Srivastava via lldb-commits

https://github.com/DhruvSrivastavaX updated 
https://github.com/llvm/llvm-project/pull/118160

>From 03a290e9c748540b69ca6df7fa9c4481f9cdd3d0 Mon Sep 17 00:00:00 2001
From: Dhruv-Srivastava 
Date: Sat, 30 Nov 2024 01:14:15 -0600
Subject: [PATCH 01/10] Added base files for NativeProcess for AIX

---
 .../source/Plugins/Process/AIX/CMakeLists.txt |  14 +
 .../Plugins/Process/AIX/NativeProcessAIX.cpp  | 288 ++
 .../Plugins/Process/AIX/NativeProcessAIX.h| 134 
 lldb/source/Plugins/Process/CMakeLists.txt|   3 +
 4 files changed, 439 insertions(+)
 create mode 100644 lldb/source/Plugins/Process/AIX/CMakeLists.txt
 create mode 100644 lldb/source/Plugins/Process/AIX/NativeProcessAIX.cpp
 create mode 100644 lldb/source/Plugins/Process/AIX/NativeProcessAIX.h

diff --git a/lldb/source/Plugins/Process/AIX/CMakeLists.txt 
b/lldb/source/Plugins/Process/AIX/CMakeLists.txt
new file mode 100644
index 0..4fabbe9302287
--- /dev/null
+++ b/lldb/source/Plugins/Process/AIX/CMakeLists.txt
@@ -0,0 +1,14 @@
+add_lldb_library(lldbPluginProcessAIX
+  NativeProcessAIX.cpp
+
+  LINK_LIBS
+lldbCore
+lldbHost
+lldbSymbol
+lldbTarget
+lldbUtility
+lldbPluginProcessPOSIX
+lldbPluginProcessUtility
+  LINK_COMPONENTS
+Support
+  )
diff --git a/lldb/source/Plugins/Process/AIX/NativeProcessAIX.cpp 
b/lldb/source/Plugins/Process/AIX/NativeProcessAIX.cpp
new file mode 100644
index 0..6661693b2fc02
--- /dev/null
+++ b/lldb/source/Plugins/Process/AIX/NativeProcessAIX.cpp
@@ -0,0 +1,288 @@
+//===-- NativeProcessAIX.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 "NativeProcessAIX.h"
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include "NativeThreadAIX.h"
+#include "Plugins/Process/POSIX/ProcessPOSIXLog.h"
+#include "lldb/Core/ModuleSpec.h"
+#include "lldb/Host/Host.h"
+#include "lldb/Host/HostProcess.h"
+#include "lldb/Host/ProcessLaunchInfo.h"
+#include "lldb/Host/PseudoTerminal.h"
+#include "lldb/Host/ThreadLauncher.h"
+#include "lldb/Host/common/NativeRegisterContext.h"
+#include "lldb/Host/aix/Ptrace.h"
+#include "lldb/Host/posix/ProcessLauncherPosixFork.h"
+#include "lldb/Symbol/ObjectFile.h"
+#include "lldb/Target/Process.h"
+#include "lldb/Target/Target.h"
+#include "lldb/Utility/LLDBAssert.h"
+#include "lldb/Utility/LLDBLog.h"
+#include "lldb/Utility/RegisterValue.h"
+#include "lldb/Utility/State.h"
+#include "lldb/Utility/Status.h"
+#include "lldb/Utility/StringExtractor.h"
+#include "llvm/ADT/ScopeExit.h"
+#include "llvm/Support/Errno.h"
+#include "llvm/Support/Error.h"
+#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/Threading.h"
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#ifdef __aarch64__
+#include 
+#include 
+#endif
+
+// Support hardware breakpoints in case it has not been defined
+#ifndef TRAP_HWBKPT
+#define TRAP_HWBKPT 4
+#endif
+
+#ifndef HWCAP2_MTE
+#define HWCAP2_MTE (1 << 18)
+#endif
+
+using namespace lldb;
+using namespace lldb_private;
+using namespace lldb_private::process_aix;
+using namespace llvm;
+
+static constexpr unsigned k_ptrace_word_size = sizeof(void *);
+static_assert(sizeof(long) >= k_ptrace_word_size,
+  "Size of long must be larger than ptrace word size");
+
+// Simple helper function to ensure flags are enabled on the given file
+// descriptor.
+static Status EnsureFDFlags(int fd, int flags) {
+  Status error;
+
+  int status = fcntl(fd, F_GETFL);
+  if (status == -1) {
+error = Status::FromErrno();
+return error;
+  }
+
+  if (fcntl(fd, F_SETFL, status | flags) == -1) {
+error = Status::FromErrno();
+return error;
+  }
+
+  return error;
+}
+
+NativeProcessAIX::Manager::Manager(MainLoop &mainloop)
+: NativeProcessProtocol::Manager(mainloop) {
+  Status status;
+  m_sigchld_handle = mainloop.RegisterSignal(
+  SIGCHLD, [this](MainLoopBase &) { SigchldHandler(); }, status);
+  assert(m_sigchld_handle && status.Success());
+}
+
+// Public Static Methods
+
+llvm::Expected>
+NativeProcessAIX::Manager::Launch(ProcessLaunchInfo &launch_info,
+NativeDelegate &native_delegate) {
+  Log *log = GetLog(POSIXLog::Process);
+
+  Status status;
+  ::pid_t pid = ProcessLauncherPosixFork()
+.LaunchProcess(launch_info, status)
+.GetProcessId();
+  LLDB_LOG(log, "pid = {0:x}", pid);
+  if (status.Fail()) {
+LLDB_LOG(log, "failed to launch process: {0}", status);
+return status.ToError();
+  }
+
+  // Wait for the child process to trap on its call to execve.
+  int wstatus = 0;
+  ::pid

[Lldb-commits] [lldb] [lldb][AIX] Added base files for NativeProcess Support for AIX (PR #118160)

2025-03-12 Thread Dhruv Srivastava via lldb-commits

https://github.com/DhruvSrivastavaX edited 
https://github.com/llvm/llvm-project/pull/118160
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb][AIX] Added base files for NativeProcess Support for AIX (PR #118160)

2025-03-12 Thread Dhruv Srivastava via lldb-commits


@@ -0,0 +1,256 @@
+//===-- NativeProcessAIX.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 "NativeProcessAIX.h"
+#include "Plugins/Process/POSIX/ProcessPOSIXLog.h"
+#include "lldb/Host/Host.h"
+#include "lldb/Host/HostProcess.h"
+#include "lldb/Host/ProcessLaunchInfo.h"
+#include "lldb/Host/posix/ProcessLauncherPosixFork.h"
+#include "lldb/Symbol/ObjectFile.h"
+#include "lldb/Utility/Log.h"
+#include "lldb/Utility/State.h"
+#include "lldb/Utility/Status.h"
+#include "llvm/Support/Errno.h"
+#include "llvm/Support/Error.h"
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+using namespace lldb;
+using namespace lldb_private;
+using namespace lldb_private::process_aix;
+using namespace llvm;
+
+static constexpr unsigned k_ptrace_word_size = sizeof(void *);
+static_assert(sizeof(long) >= k_ptrace_word_size,
+  "Size of long must be larger than ptrace word size");
+
+// Simple helper function to ensure flags are enabled on the given file
+// descriptor.
+static llvm::Error EnsureFDFlags(int fd, int flags) {
+  int status = fcntl(fd, F_GETFL);
+  if (status == -1)
+return errorCodeToError(errnoAsErrorCode());
+  if (fcntl(fd, F_SETFL, status | flags) == -1)
+return errorCodeToError(errnoAsErrorCode());
+  return Error::success();
+}
+
+NativeProcessAIX::Manager::Manager(MainLoop &mainloop)
+: NativeProcessProtocol::Manager(mainloop) {
+  Status status;
+  m_sigchld_handle = mainloop.RegisterSignal(
+  SIGCHLD, [this](MainLoopBase &) { SigchldHandler(); }, status);
+  assert(m_sigchld_handle && status.Success());
+}
+
+// Public Static Methods
+
+llvm::Expected>
+NativeProcessAIX::Manager::Launch(ProcessLaunchInfo &launch_info,
+  NativeDelegate &native_delegate) {
+  Log *log = GetLog(POSIXLog::Process);
+
+  Status status;
+  ::pid_t pid = ProcessLauncherPosixFork()
+.LaunchProcess(launch_info, status)
+.GetProcessId();
+  LLDB_LOG(log, "pid = {0:x}", pid);
+  if (status.Fail()) {
+LLDB_LOG(log, "failed to launch process: {0}", status);
+return status.ToError();
+  }
+
+  // Wait for the child process to trap on its call to execve.
+  int wstatus = 0;
+  ::pid_t wpid = llvm::sys::RetryAfterSignal(-1, ::waitpid, pid, &wstatus, 0);
+  assert(wpid == pid);
+  UNUSED_IF_ASSERT_DISABLED(wpid);
+  if (!WIFSTOPPED(wstatus)) {
+LLDB_LOG(log, "Could not sync with inferior process: wstatus={1}",
+ WaitStatus::Decode(wstatus));
+return llvm::make_error("Could not sync with inferior 
process",
+ llvm::inconvertibleErrorCode());
+  }
+  LLDB_LOG(log, "inferior started, now in stopped state");
+
+  ProcessInstanceInfo Info;
+  if (!Host::GetProcessInfo(pid, Info)) {
+return llvm::make_error("Cannot get process architectrue",
+ llvm::inconvertibleErrorCode());
+  }
+
+  // Set the architecture to the exe architecture.
+  LLDB_LOG(log, "pid = {0}, detected architecture {1}", pid,
+   Info.GetArchitecture().GetArchitectureName());
+
+  return std::unique_ptr(new NativeProcessAIX(
+  pid, launch_info.GetPTY().ReleasePrimaryFileDescriptor(), 
native_delegate,
+  Info.GetArchitecture(), *this, {pid}));
+}
+
+llvm::Expected>
+NativeProcessAIX::Manager::Attach(
+lldb::pid_t pid, NativeProcessProtocol::NativeDelegate &native_delegate) {
+  Log *log = GetLog(POSIXLog::Process);
+  LLDB_LOG(log, "pid = {0:x}", pid);
+
+  ProcessInstanceInfo Info;
+  if (!Host::GetProcessInfo(pid, Info)) {
+return llvm::make_error("Cannot get process architectrue",
+ llvm::inconvertibleErrorCode());
+  }
+  auto tids_or = NativeProcessAIX::Attach(pid);
+  if (!tids_or)
+return tids_or.takeError();
+
+  return std::unique_ptr(new NativeProcessAIX(
+  pid, -1, native_delegate, Info.GetArchitecture(), *this, *tids_or));
+}
+
+lldb::addr_t NativeProcessAIX::GetSharedLibraryInfoAddress() {
+  return LLDB_INVALID_ADDRESS;
+}
+
+NativeProcessAIX::Extension
+NativeProcessAIX::Manager::GetSupportedExtensions() const {
+  NativeProcessAIX::Extension supported = {};
+
+  return supported;
+}
+
+void NativeProcessAIX::Manager::SigchldHandler() {}
+
+void NativeProcessAIX::Manager::CollectThread(::pid_t tid) {}
+
+// Public Instance Methods
+
+NativeProcessAIX::NativeProcessAIX(::pid_t pid, int terminal_fd,
+   NativeDelegate &delegate,
+   const ArchSpec &arch, Manager &manager,
+   llvm::ArrayRef<::pid_t> tids)
+: NativeProcessProtoc

[Lldb-commits] [lldb] [lldb-dap] Validate server mode support prior to invoking lldb-dap. (PR #130855)

2025-03-12 Thread John Harrison via lldb-commits

https://github.com/ashgti closed 
https://github.com/llvm/llvm-project/pull/130855
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb-dap] Refactoring IOStream into Transport handler. (PR #130026)

2025-03-12 Thread John Harrison via lldb-commits


@@ -63,12 +64,12 @@ const char DEV_NULL[] = "/dev/null";
 
 namespace lldb_dap {
 
-DAP::DAP(llvm::StringRef client_name, llvm::StringRef path, std::ofstream *log,
- lldb::IOObjectSP input, lldb::IOObjectSP output, ReplMode repl_mode,
- std::vector pre_init_commands)
-: client_name(client_name), debug_adapter_path(path), log(log),
-  input(std::move(input)), output(std::move(output)),
-  broadcaster("lldb-dap"), exception_breakpoints(),
+DAP::DAP(llvm::StringRef path, std::ofstream *log,
+ const ReplMode default_repl_mode,
+ const std::vector &pre_init_commands,
+ llvm::StringRef client_name, Transport &transport)
+: debug_adapter_path(path), log(log), client_name(client_name),
+  transport(transport), broadcaster("lldb-dap"), exception_breakpoints(),
   pre_init_commands(std::move(pre_init_commands)),

ashgti wrote:

Reverted `pre_init_commands` changes

https://github.com/llvm/llvm-project/pull/130026
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] Make breakpoint stop reason more accurate for function breakpoints (PR #130841)

2025-03-12 Thread via lldb-commits

https://github.com/satyajanga closed 
https://github.com/llvm/llvm-project/pull/130841
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] Make breakpoint stop reason more accurate for function breakpoints (PR #130841)

2025-03-12 Thread via lldb-commits

https://github.com/satyajanga reopened 
https://github.com/llvm/llvm-project/pull/130841
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] Make breakpoint stop reason more accurate for function breakpoints (PR #130841)

2025-03-12 Thread via lldb-commits

satyajanga wrote:

> > tools/lldb-dap/attach/TestDAP_attach.py : creates function breakpoints 
> > tests that they are hit.
> > tools/lldb-dap/breakpoint/TestDAP_setFunctionBreakpoints.py also creates 
> > breakpoints tests that they are hit.
> 
> Are these two tests checking "reason" field in stopped DAP event?



https://github.com/llvm/llvm-project/pull/130841
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] Make breakpoint stop reason more accurate for function breakpoints (PR #130841)

2025-03-12 Thread via lldb-commits


@@ -967,17 +967,23 @@ llvm::json::Value CreateThreadStopped(DAP &dap, 
lldb::SBThread &thread,
   body.try_emplace("reason", "exception");
   EmplaceSafeString(body, "description", exc_bp->label);
 } else {
+  std::string reason = "breakpoint";

satyajanga wrote:

updated it

https://github.com/llvm/llvm-project/pull/130841
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] Make breakpoint stop reason more accurate for function breakpoints (PR #130841)

2025-03-12 Thread via lldb-commits

https://github.com/satyajanga ready_for_review 
https://github.com/llvm/llvm-project/pull/130841
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb-dap] Refactoring IOStream into Transport handler. (PR #130026)

2025-03-12 Thread John Harrison via lldb-commits

https://github.com/ashgti updated 
https://github.com/llvm/llvm-project/pull/130026

>From c340c38a82880114471938b19512670d7f94245e Mon Sep 17 00:00:00 2001
From: John Harrison 
Date: Thu, 6 Mar 2025 10:18:36 +0100
Subject: [PATCH 01/10] [lldb-dap] Refactoring IOStream into Transport handler.

Instead of having two discrete InputStream and OutputStream helpers,
this merges the two into a unifed 'Transport' handler.

This handler is responsible for reading the DAP message headers, parsing
the resulting JSON and converting the messages into
`lldb_dap::protocol::Message`s for both input and output.
---
 .../test/tools/lldb-dap/dap_server.py |   4 +-
 lldb/tools/lldb-dap/CMakeLists.txt|   4 +-
 lldb/tools/lldb-dap/DAP.cpp   | 110 -
 lldb/tools/lldb-dap/DAP.h |  18 +--
 lldb/tools/lldb-dap/IOStream.cpp  |  73 -
 lldb/tools/lldb-dap/IOStream.h|  42 -
 lldb/tools/lldb-dap/Transport.cpp | 146 ++
 lldb/tools/lldb-dap/Transport.h   |  54 +++
 8 files changed, 240 insertions(+), 211 deletions(-)
 delete mode 100644 lldb/tools/lldb-dap/IOStream.cpp
 delete mode 100644 lldb/tools/lldb-dap/IOStream.h
 create mode 100644 lldb/tools/lldb-dap/Transport.cpp
 create mode 100644 lldb/tools/lldb-dap/Transport.h

diff --git a/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py 
b/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py
index 9471594b66012..0fea3419d9725 100644
--- a/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py
+++ b/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py
@@ -337,7 +337,7 @@ def send_recv(self, command):
 self.send_packet(
 {
 "type": "response",
-"seq": -1,
+"seq": 0,
 "request_seq": response_or_request["seq"],
 "success": True,
 "command": "runInTerminal",
@@ -349,7 +349,7 @@ def send_recv(self, command):
 self.send_packet(
 {
 "type": "response",
-"seq": -1,
+"seq": 0,
 "request_seq": response_or_request["seq"],
 "success": True,
 "command": "startDebugging",
diff --git a/lldb/tools/lldb-dap/CMakeLists.txt 
b/lldb/tools/lldb-dap/CMakeLists.txt
index 9a2d604f4d573..8a76cb58dbcab 100644
--- a/lldb/tools/lldb-dap/CMakeLists.txt
+++ b/lldb/tools/lldb-dap/CMakeLists.txt
@@ -28,14 +28,14 @@ add_lldb_tool(lldb-dap
   FifoFiles.cpp
   FunctionBreakpoint.cpp
   InstructionBreakpoint.cpp
-  IOStream.cpp
   JSONUtils.cpp
   LLDBUtils.cpp
   OutputRedirector.cpp
   ProgressEvent.cpp
+  Protocol.cpp
   RunInTerminal.cpp
   SourceBreakpoint.cpp
-  Protocol.cpp
+  Transport.cpp
   Watchpoint.cpp
 
   Handler/ResponseHandler.cpp
diff --git a/lldb/tools/lldb-dap/DAP.cpp b/lldb/tools/lldb-dap/DAP.cpp
index edd3b31be8ff7..6d19eb2917a1b 100644
--- a/lldb/tools/lldb-dap/DAP.cpp
+++ b/lldb/tools/lldb-dap/DAP.cpp
@@ -12,6 +12,7 @@
 #include "JSONUtils.h"
 #include "LLDBUtils.h"
 #include "OutputRedirector.h"
+#include "Transport.h"
 #include "lldb/API/SBBreakpoint.h"
 #include "lldb/API/SBCommandInterpreter.h"
 #include "lldb/API/SBCommandReturnObject.h"
@@ -67,7 +68,7 @@ DAP::DAP(llvm::StringRef client_name, llvm::StringRef path, 
std::ofstream *log,
  lldb::IOObjectSP input, lldb::IOObjectSP output, ReplMode repl_mode,
  std::vector pre_init_commands)
 : client_name(client_name), debug_adapter_path(path), log(log),
-  input(std::move(input)), output(std::move(output)),
+  transport(client_name, std::move(input), std::move(output)),
   broadcaster("lldb-dap"), exception_breakpoints(),
   pre_init_commands(std::move(pre_init_commands)),
   focus_tid(LLDB_INVALID_THREAD_ID), stop_at_entry(false), 
is_attach(false),
@@ -221,52 +222,27 @@ void DAP::StopEventHandlers() {
   }
 }
 
-// Send the JSON in "json_str" to the "out" stream. Correctly send the
-// "Content-Length:" field followed by the length, followed by the raw
-// JSON bytes.
-void DAP::SendJSON(const std::string &json_str) {
-  output.write_full("Content-Length: ");
-  output.write_full(llvm::utostr(json_str.size()));
-  output.write_full("\r\n\r\n");
-  output.write_full(json_str);
-}
-
 // Serialize the JSON value into a string and send the JSON packet to
 // the "out" stream.
 void DAP::SendJSON(const llvm::json::Value &json) {
-  std::string json_str;
-  llvm::raw_string_ostream strm(json_str);
-  strm << json;
-  static std::mutex mutex;
-  std::lock_guard locker(mutex);
-  SendJSON(json_str);
-
-  DAP_LOG(log, "({0}) <-- {1}", client_name, json_str);
-}
-
-// Read a JSON packet from the "in" stre

[Lldb-commits] [lldb] Make breakpoint stop reason more accurate for function breakpoints (PR #130841)

2025-03-12 Thread via lldb-commits

satyajanga wrote:

> > tools/lldb-dap/attach/TestDAP_attach.py : creates function breakpoints 
> > tests that they are hit.
> > tools/lldb-dap/breakpoint/TestDAP_setFunctionBreakpoints.py also creates 
> > breakpoints tests that they are hit.
> 
> Are these two tests checking "reason" field in stopped DAP event?

Yes. They call the `DAPTestCaseBase.verify_breakpoint_hit` it validates the 
description and reason (indirectly).

https://github.com/llvm/llvm-project/pull/130841
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] Make breakpoint stop reason more accurate for function breakpoints (PR #130841)

2025-03-12 Thread via lldb-commits

https://github.com/satyajanga updated 
https://github.com/llvm/llvm-project/pull/130841

>From 55d3b7d0ecf103cc97942c1406926853c35356c1 Mon Sep 17 00:00:00 2001
From: satya janga 
Date: Tue, 11 Mar 2025 13:39:08 -0700
Subject: [PATCH 1/4] Make breakpoint stop reason more accurate

---
 .../test/tools/lldb-dap/lldbdap_testcase.py   |  3 ++-
 lldb/tools/lldb-dap/DAP.cpp   | 26 +++
 lldb/tools/lldb-dap/DAP.h | 12 ++---
 lldb/tools/lldb-dap/JSONUtils.cpp | 12 ++---
 4 files changed, 46 insertions(+), 7 deletions(-)

diff --git 
a/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/lldbdap_testcase.py 
b/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/lldbdap_testcase.py
index 70b04b051e0ec..5faf83ca826a0 100644
--- a/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/lldbdap_testcase.py
+++ b/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/lldbdap_testcase.py
@@ -86,6 +86,7 @@ def verify_breakpoint_hit(self, breakpoint_ids):
 if (
 body["reason"] != "breakpoint"
 and body["reason"] != "instruction breakpoint"
+and body["reason"] != "function breakpoint"
 ):
 continue
 if "description" not in body:
@@ -100,7 +101,7 @@ def verify_breakpoint_hit(self, breakpoint_ids):
 # location.
 description = body["description"]
 for breakpoint_id in breakpoint_ids:
-match_desc = "breakpoint %s." % (breakpoint_id)
+match_desc = "%s %s." % (body["reason"], breakpoint_id)
 if match_desc in description:
 return
 self.assertTrue(False, "breakpoint not hit")
diff --git a/lldb/tools/lldb-dap/DAP.cpp b/lldb/tools/lldb-dap/DAP.cpp
index edd3b31be8ff7..485c420dc59e8 100644
--- a/lldb/tools/lldb-dap/DAP.cpp
+++ b/lldb/tools/lldb-dap/DAP.cpp
@@ -1128,6 +1128,32 @@ DAP::GetInstructionBPFromStopReason(lldb::SBThread 
&thread) {
   return inst_bp;
 }
 
+FunctionBreakpoint *DAP::GetFunctionBPFromStopReason(lldb::SBThread &thread) {
+  const auto num = thread.GetStopReasonDataCount();
+  FunctionBreakpoint *func_bp = nullptr;
+  for (size_t i = 0; i < num; i += 2) {
+// thread.GetStopReasonDataAtIndex(i) will return the bp ID and
+// thread.GetStopReasonDataAtIndex(i+1) will return the location
+// within that breakpoint. We only care about the bp ID so we can
+// see if this is an function breakpoint that is getting hit.
+lldb::break_id_t bp_id = thread.GetStopReasonDataAtIndex(i);
+func_bp = GetFunctionBreakPoint(bp_id);
+// If any breakpoint is not an function breakpoint, then stop and
+// report this as a normal breakpoint
+if (func_bp == nullptr)
+  return nullptr;
+  }
+  return func_bp;
+}
+
+FunctionBreakpoint *DAP::GetFunctionBreakPoint(const lldb::break_id_t bp_id) {
+  for (auto &bp : function_breakpoints) {
+if (bp.second.bp.GetID() == bp_id)
+  return &bp.second;
+  }
+  return nullptr;
+}
+
 lldb::SBValueList *Variables::GetTopLevelScope(int64_t variablesReference) {
   switch (variablesReference) {
   case VARREF_LOCALS:
diff --git a/lldb/tools/lldb-dap/DAP.h b/lldb/tools/lldb-dap/DAP.h
index 3ff1992b61f5b..ea72b41d02516 100644
--- a/lldb/tools/lldb-dap/DAP.h
+++ b/lldb/tools/lldb-dap/DAP.h
@@ -125,21 +125,21 @@ struct Variables {
 
 struct StartDebuggingRequestHandler : public lldb::SBCommandPluginInterface {
   DAP &dap;
-  explicit StartDebuggingRequestHandler(DAP &d) : dap(d) {};
+  explicit StartDebuggingRequestHandler(DAP &d) : dap(d){};
   bool DoExecute(lldb::SBDebugger debugger, char **command,
  lldb::SBCommandReturnObject &result) override;
 };
 
 struct ReplModeRequestHandler : public lldb::SBCommandPluginInterface {
   DAP &dap;
-  explicit ReplModeRequestHandler(DAP &d) : dap(d) {};
+  explicit ReplModeRequestHandler(DAP &d) : dap(d){};
   bool DoExecute(lldb::SBDebugger debugger, char **command,
  lldb::SBCommandReturnObject &result) override;
 };
 
 struct SendEventRequestHandler : public lldb::SBCommandPluginInterface {
   DAP &dap;
-  explicit SendEventRequestHandler(DAP &d) : dap(d) {};
+  explicit SendEventRequestHandler(DAP &d) : dap(d){};
   bool DoExecute(lldb::SBDebugger debugger, char **command,
  lldb::SBCommandReturnObject &result) override;
 };
@@ -383,6 +383,12 @@ struct DAP {
 
   InstructionBreakpoint *GetInstructionBPFromStopReason(lldb::SBThread 
&thread);
 
+  FunctionBreakpoint *GetFunctionBPFromStopReason(lldb::SBThread &thread);
+
+  FunctionBreakpoint *GetFunctionBreakPoint(const lldb::break_id_t bp_id);
+
+  void WaitWorkerThreadsToExit();
+
 private:
   // Send the JSON in "json_str" to the "out" stream. Correctly send the
   // "Content-Length:" field followed by the length, followed by the raw
diff --git a/lldb/tools/lldb-dap/JSONUtils.cpp 
b/lldb/tools

[Lldb-commits] [lldb] [lldb-dap] Refactoring IOStream into Transport handler. (PR #130026)

2025-03-12 Thread John Harrison via lldb-commits

https://github.com/ashgti updated 
https://github.com/llvm/llvm-project/pull/130026

>From c340c38a82880114471938b19512670d7f94245e Mon Sep 17 00:00:00 2001
From: John Harrison 
Date: Thu, 6 Mar 2025 10:18:36 +0100
Subject: [PATCH 1/8] [lldb-dap] Refactoring IOStream into Transport handler.

Instead of having two discrete InputStream and OutputStream helpers,
this merges the two into a unifed 'Transport' handler.

This handler is responsible for reading the DAP message headers, parsing
the resulting JSON and converting the messages into
`lldb_dap::protocol::Message`s for both input and output.
---
 .../test/tools/lldb-dap/dap_server.py |   4 +-
 lldb/tools/lldb-dap/CMakeLists.txt|   4 +-
 lldb/tools/lldb-dap/DAP.cpp   | 110 -
 lldb/tools/lldb-dap/DAP.h |  18 +--
 lldb/tools/lldb-dap/IOStream.cpp  |  73 -
 lldb/tools/lldb-dap/IOStream.h|  42 -
 lldb/tools/lldb-dap/Transport.cpp | 146 ++
 lldb/tools/lldb-dap/Transport.h   |  54 +++
 8 files changed, 240 insertions(+), 211 deletions(-)
 delete mode 100644 lldb/tools/lldb-dap/IOStream.cpp
 delete mode 100644 lldb/tools/lldb-dap/IOStream.h
 create mode 100644 lldb/tools/lldb-dap/Transport.cpp
 create mode 100644 lldb/tools/lldb-dap/Transport.h

diff --git a/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py 
b/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py
index 9471594b66012..0fea3419d9725 100644
--- a/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py
+++ b/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py
@@ -337,7 +337,7 @@ def send_recv(self, command):
 self.send_packet(
 {
 "type": "response",
-"seq": -1,
+"seq": 0,
 "request_seq": response_or_request["seq"],
 "success": True,
 "command": "runInTerminal",
@@ -349,7 +349,7 @@ def send_recv(self, command):
 self.send_packet(
 {
 "type": "response",
-"seq": -1,
+"seq": 0,
 "request_seq": response_or_request["seq"],
 "success": True,
 "command": "startDebugging",
diff --git a/lldb/tools/lldb-dap/CMakeLists.txt 
b/lldb/tools/lldb-dap/CMakeLists.txt
index 9a2d604f4d573..8a76cb58dbcab 100644
--- a/lldb/tools/lldb-dap/CMakeLists.txt
+++ b/lldb/tools/lldb-dap/CMakeLists.txt
@@ -28,14 +28,14 @@ add_lldb_tool(lldb-dap
   FifoFiles.cpp
   FunctionBreakpoint.cpp
   InstructionBreakpoint.cpp
-  IOStream.cpp
   JSONUtils.cpp
   LLDBUtils.cpp
   OutputRedirector.cpp
   ProgressEvent.cpp
+  Protocol.cpp
   RunInTerminal.cpp
   SourceBreakpoint.cpp
-  Protocol.cpp
+  Transport.cpp
   Watchpoint.cpp
 
   Handler/ResponseHandler.cpp
diff --git a/lldb/tools/lldb-dap/DAP.cpp b/lldb/tools/lldb-dap/DAP.cpp
index edd3b31be8ff7..6d19eb2917a1b 100644
--- a/lldb/tools/lldb-dap/DAP.cpp
+++ b/lldb/tools/lldb-dap/DAP.cpp
@@ -12,6 +12,7 @@
 #include "JSONUtils.h"
 #include "LLDBUtils.h"
 #include "OutputRedirector.h"
+#include "Transport.h"
 #include "lldb/API/SBBreakpoint.h"
 #include "lldb/API/SBCommandInterpreter.h"
 #include "lldb/API/SBCommandReturnObject.h"
@@ -67,7 +68,7 @@ DAP::DAP(llvm::StringRef client_name, llvm::StringRef path, 
std::ofstream *log,
  lldb::IOObjectSP input, lldb::IOObjectSP output, ReplMode repl_mode,
  std::vector pre_init_commands)
 : client_name(client_name), debug_adapter_path(path), log(log),
-  input(std::move(input)), output(std::move(output)),
+  transport(client_name, std::move(input), std::move(output)),
   broadcaster("lldb-dap"), exception_breakpoints(),
   pre_init_commands(std::move(pre_init_commands)),
   focus_tid(LLDB_INVALID_THREAD_ID), stop_at_entry(false), 
is_attach(false),
@@ -221,52 +222,27 @@ void DAP::StopEventHandlers() {
   }
 }
 
-// Send the JSON in "json_str" to the "out" stream. Correctly send the
-// "Content-Length:" field followed by the length, followed by the raw
-// JSON bytes.
-void DAP::SendJSON(const std::string &json_str) {
-  output.write_full("Content-Length: ");
-  output.write_full(llvm::utostr(json_str.size()));
-  output.write_full("\r\n\r\n");
-  output.write_full(json_str);
-}
-
 // Serialize the JSON value into a string and send the JSON packet to
 // the "out" stream.
 void DAP::SendJSON(const llvm::json::Value &json) {
-  std::string json_str;
-  llvm::raw_string_ostream strm(json_str);
-  strm << json;
-  static std::mutex mutex;
-  std::lock_guard locker(mutex);
-  SendJSON(json_str);
-
-  DAP_LOG(log, "({0}) <-- {1}", client_name, json_str);
-}
-
-// Read a JSON packet from the "in" stream

[Lldb-commits] [lldb] Make breakpoint stop reason more accurate for function breakpoints (PR #130841)

2025-03-12 Thread via lldb-commits


@@ -1128,6 +1128,32 @@ DAP::GetInstructionBPFromStopReason(lldb::SBThread 
&thread) {
   return inst_bp;
 }
 
+FunctionBreakpoint *DAP::GetFunctionBPFromStopReason(lldb::SBThread &thread) {
+  const auto num = thread.GetStopReasonDataCount();
+  FunctionBreakpoint *func_bp = nullptr;
+  for (size_t i = 0; i < num; i += 2) {
+// thread.GetStopReasonDataAtIndex(i) will return the bp ID and
+// thread.GetStopReasonDataAtIndex(i+1) will return the location
+// within that breakpoint. We only care about the bp ID so we can
+// see if this is an function breakpoint that is getting hit.
+lldb::break_id_t bp_id = thread.GetStopReasonDataAtIndex(i);
+func_bp = GetFunctionBreakPoint(bp_id);
+// If any breakpoint is not an function breakpoint, then stop and
+// report this as a normal breakpoint
+if (func_bp == nullptr)
+  return nullptr;
+  }
+  return func_bp;
+}
+
+FunctionBreakpoint *DAP::GetFunctionBreakPoint(const lldb::break_id_t bp_id) {
+  for (auto &bp : function_breakpoints) {
+if (bp.second.bp.GetID() == bp_id)
+  return &bp.second;
+  }
+  return nullptr;
+}
+

satyajanga wrote:

Done. I also refactored in Exception Break points.

Curious to know your thoughts about putting the specializations in header file. 
Another thought was adding DAP-inl.h and add them there.

https://github.com/llvm/llvm-project/pull/130841
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] Make breakpoint stop reason more accurate for function breakpoints (PR #130841)

2025-03-12 Thread via lldb-commits

https://github.com/satyajanga edited 
https://github.com/llvm/llvm-project/pull/130841
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb-dap] Refactoring IOStream into Transport handler. (PR #130026)

2025-03-12 Thread John Harrison via lldb-commits

https://github.com/ashgti updated 
https://github.com/llvm/llvm-project/pull/130026

>From c340c38a82880114471938b19512670d7f94245e Mon Sep 17 00:00:00 2001
From: John Harrison 
Date: Thu, 6 Mar 2025 10:18:36 +0100
Subject: [PATCH 1/9] [lldb-dap] Refactoring IOStream into Transport handler.

Instead of having two discrete InputStream and OutputStream helpers,
this merges the two into a unifed 'Transport' handler.

This handler is responsible for reading the DAP message headers, parsing
the resulting JSON and converting the messages into
`lldb_dap::protocol::Message`s for both input and output.
---
 .../test/tools/lldb-dap/dap_server.py |   4 +-
 lldb/tools/lldb-dap/CMakeLists.txt|   4 +-
 lldb/tools/lldb-dap/DAP.cpp   | 110 -
 lldb/tools/lldb-dap/DAP.h |  18 +--
 lldb/tools/lldb-dap/IOStream.cpp  |  73 -
 lldb/tools/lldb-dap/IOStream.h|  42 -
 lldb/tools/lldb-dap/Transport.cpp | 146 ++
 lldb/tools/lldb-dap/Transport.h   |  54 +++
 8 files changed, 240 insertions(+), 211 deletions(-)
 delete mode 100644 lldb/tools/lldb-dap/IOStream.cpp
 delete mode 100644 lldb/tools/lldb-dap/IOStream.h
 create mode 100644 lldb/tools/lldb-dap/Transport.cpp
 create mode 100644 lldb/tools/lldb-dap/Transport.h

diff --git a/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py 
b/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py
index 9471594b66012..0fea3419d9725 100644
--- a/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py
+++ b/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py
@@ -337,7 +337,7 @@ def send_recv(self, command):
 self.send_packet(
 {
 "type": "response",
-"seq": -1,
+"seq": 0,
 "request_seq": response_or_request["seq"],
 "success": True,
 "command": "runInTerminal",
@@ -349,7 +349,7 @@ def send_recv(self, command):
 self.send_packet(
 {
 "type": "response",
-"seq": -1,
+"seq": 0,
 "request_seq": response_or_request["seq"],
 "success": True,
 "command": "startDebugging",
diff --git a/lldb/tools/lldb-dap/CMakeLists.txt 
b/lldb/tools/lldb-dap/CMakeLists.txt
index 9a2d604f4d573..8a76cb58dbcab 100644
--- a/lldb/tools/lldb-dap/CMakeLists.txt
+++ b/lldb/tools/lldb-dap/CMakeLists.txt
@@ -28,14 +28,14 @@ add_lldb_tool(lldb-dap
   FifoFiles.cpp
   FunctionBreakpoint.cpp
   InstructionBreakpoint.cpp
-  IOStream.cpp
   JSONUtils.cpp
   LLDBUtils.cpp
   OutputRedirector.cpp
   ProgressEvent.cpp
+  Protocol.cpp
   RunInTerminal.cpp
   SourceBreakpoint.cpp
-  Protocol.cpp
+  Transport.cpp
   Watchpoint.cpp
 
   Handler/ResponseHandler.cpp
diff --git a/lldb/tools/lldb-dap/DAP.cpp b/lldb/tools/lldb-dap/DAP.cpp
index edd3b31be8ff7..6d19eb2917a1b 100644
--- a/lldb/tools/lldb-dap/DAP.cpp
+++ b/lldb/tools/lldb-dap/DAP.cpp
@@ -12,6 +12,7 @@
 #include "JSONUtils.h"
 #include "LLDBUtils.h"
 #include "OutputRedirector.h"
+#include "Transport.h"
 #include "lldb/API/SBBreakpoint.h"
 #include "lldb/API/SBCommandInterpreter.h"
 #include "lldb/API/SBCommandReturnObject.h"
@@ -67,7 +68,7 @@ DAP::DAP(llvm::StringRef client_name, llvm::StringRef path, 
std::ofstream *log,
  lldb::IOObjectSP input, lldb::IOObjectSP output, ReplMode repl_mode,
  std::vector pre_init_commands)
 : client_name(client_name), debug_adapter_path(path), log(log),
-  input(std::move(input)), output(std::move(output)),
+  transport(client_name, std::move(input), std::move(output)),
   broadcaster("lldb-dap"), exception_breakpoints(),
   pre_init_commands(std::move(pre_init_commands)),
   focus_tid(LLDB_INVALID_THREAD_ID), stop_at_entry(false), 
is_attach(false),
@@ -221,52 +222,27 @@ void DAP::StopEventHandlers() {
   }
 }
 
-// Send the JSON in "json_str" to the "out" stream. Correctly send the
-// "Content-Length:" field followed by the length, followed by the raw
-// JSON bytes.
-void DAP::SendJSON(const std::string &json_str) {
-  output.write_full("Content-Length: ");
-  output.write_full(llvm::utostr(json_str.size()));
-  output.write_full("\r\n\r\n");
-  output.write_full(json_str);
-}
-
 // Serialize the JSON value into a string and send the JSON packet to
 // the "out" stream.
 void DAP::SendJSON(const llvm::json::Value &json) {
-  std::string json_str;
-  llvm::raw_string_ostream strm(json_str);
-  strm << json;
-  static std::mutex mutex;
-  std::lock_guard locker(mutex);
-  SendJSON(json_str);
-
-  DAP_LOG(log, "({0}) <-- {1}", client_name, json_str);
-}
-
-// Read a JSON packet from the "in" stream

[Lldb-commits] [lldb] [lldb-dap] Updating RequestHandler to encode/decode arguments and response. (PR #130090)

2025-03-12 Thread Adrian Vogelsgesang via lldb-commits


@@ -240,6 +240,137 @@ using Message = std::variant;
 bool fromJSON(const llvm::json::Value &, Message &, llvm::json::Path);
 llvm::json::Value toJSON(const Message &);
 
+// MARK: Types
+
+// "Source": {
+//   "type": "object",
+//   "description": "A `Source` is a descriptor for source code.\nIt is 
returned
+//   from the debug adapter as part of a `StackFrame` and it is used by clients
+//   when specifying breakpoints.", "properties": {
+// "name": {
+//   "type": "string",
+//   "description": "The short name of the source. Every source returned
+//   from the debug adapter has a name.\nWhen sending a source to the debug
+//   adapter this name is optional."
+// },
+// "path": {
+//   "type": "string",
+//   "description": "The path of the source to be shown in the UI.\nIt is
+//   only used to locate and load the content of the source if no
+//   `sourceReference` is specified (or its value is 0)."
+// },
+// "sourceReference": {
+//   "type": "integer",
+//   "description": "If the value > 0 the contents of the source must be
+//   retrieved through the `source` request (even if a path is
+//   specified).\nSince a `sourceReference` is only valid for a session, it
+//   can not be used to persist a source.\nThe value should be less than or
+//   equal to 2147483647 (2^31-1)."
+// },
+// "presentationHint": {
+//   "type": "string",
+//   "description": "A hint for how to present the source in the UI.\nA
+//   value of `deemphasize` can be used to indicate that the source is not
+//   available or that it is skipped on stepping.", "enum": [ "normal",
+//   "emphasize", "deemphasize" ]
+// },
+// "origin": {
+//   "type": "string",
+//   "description": "The origin of this source. For example, 'internal
+//   module', 'inlined content from source map', etc."
+// },
+// "sources": {
+//   "type": "array",
+//   "items": {
+// "$ref": "#/definitions/Source"
+//   },
+//   "description": "A list of sources that are related to this source.
+//   These may be the source that generated this source."
+// },
+// "adapterData": {
+//   "type": [ "array", "boolean", "integer", "null", "number", "object",
+//   "string" ], "description": "Additional data that a debug adapter might
+//   want to loop through the client.\nThe client should leave the data
+//   intact and persist it across sessions. The client should not interpret
+//   the data."
+// },
+// "checksums": {
+//   "type": "array",
+//   "items": {
+// "$ref": "#/definitions/Checksum"
+//   },
+//   "description": "The checksums associated with this file."
+// }
+//   }
+// },
+struct Source {
+  enum class PresentationHint { normal, emphasize, deemphasize };
+
+  std::optional name;
+  std::optional path;
+  std::optional sourceReference;
+  std::optional presentationHint;
+
+  // unsupproted keys origin, sources, adapterData, checksums
+};
+bool fromJSON(const llvm::json::Value &, Source &, llvm::json::Path);
+llvm::json::Value toJSON(const Source &);
+
+// MARK: Requests
+
+// "SourceArguments": {
+//   "type": "object",
+//   "description": "Arguments for `source` request.",
+//   "properties": {
+// "source": {
+//   "$ref": "#/definitions/Source",
+//   "description": "Specifies the source content to load. Either
+//   `source.path` or `source.sourceReference` must be specified."
+// },
+// "sourceReference": {
+//   "type": "integer",
+//   "description": "The reference to the source. This is the same as
+//   `source.sourceReference`.\nThis is provided for backward compatibility
+//   since old clients do not understand the `source` attribute."
+// }
+//   },
+//   "required": [ "sourceReference" ]
+// },
+struct SourceArguments {
+  std::optional source;
+  int64_t sourceReference;
+};
+bool fromJSON(const llvm::json::Value &, SourceArguments &, llvm::json::Path);
+
+// "SourceResponse": {
+//   "allOf": [ { "$ref": "#/definitions/Response" }, {
+// "type": "object",
+// "description": "Response to `source` request.",
+// "properties": {
+//   "body": {
+// "type": "object",
+// "properties": {
+//   "content": {
+// "type": "string",
+// "description": "Content of the source reference."
+//   },
+//   "mimeType": {
+// "type": "string",
+// "description": "Content type (MIME type) of the source."
+//   }
+// },
+// "required": [ "content" ]
+//   }
+// },
+// "required": [ "body" ]
+//   }]
+// },
+struct SourceResponseBody {
+  std::string content;
+  std::optional mimeType;
+};

vogelsgesang wrote:

should we attach the comments from the schema.json to the individual members?

Do we then even still need the

[Lldb-commits] [lldb] Make breakpoint stop reason more accurate for function breakpoints (PR #130841)

2025-03-12 Thread via lldb-commits

https://github.com/satyajanga edited 
https://github.com/llvm/llvm-project/pull/130841
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] Make breakpoint stop reason more accurate for function breakpoints (PR #130841)

2025-03-12 Thread via lldb-commits

https://github.com/satyajanga updated 
https://github.com/llvm/llvm-project/pull/130841

>From 55d3b7d0ecf103cc97942c1406926853c35356c1 Mon Sep 17 00:00:00 2001
From: satya janga 
Date: Tue, 11 Mar 2025 13:39:08 -0700
Subject: [PATCH 1/4] Make breakpoint stop reason more accurate

---
 .../test/tools/lldb-dap/lldbdap_testcase.py   |  3 ++-
 lldb/tools/lldb-dap/DAP.cpp   | 26 +++
 lldb/tools/lldb-dap/DAP.h | 12 ++---
 lldb/tools/lldb-dap/JSONUtils.cpp | 12 ++---
 4 files changed, 46 insertions(+), 7 deletions(-)

diff --git 
a/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/lldbdap_testcase.py 
b/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/lldbdap_testcase.py
index 70b04b051e0ec..5faf83ca826a0 100644
--- a/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/lldbdap_testcase.py
+++ b/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/lldbdap_testcase.py
@@ -86,6 +86,7 @@ def verify_breakpoint_hit(self, breakpoint_ids):
 if (
 body["reason"] != "breakpoint"
 and body["reason"] != "instruction breakpoint"
+and body["reason"] != "function breakpoint"
 ):
 continue
 if "description" not in body:
@@ -100,7 +101,7 @@ def verify_breakpoint_hit(self, breakpoint_ids):
 # location.
 description = body["description"]
 for breakpoint_id in breakpoint_ids:
-match_desc = "breakpoint %s." % (breakpoint_id)
+match_desc = "%s %s." % (body["reason"], breakpoint_id)
 if match_desc in description:
 return
 self.assertTrue(False, "breakpoint not hit")
diff --git a/lldb/tools/lldb-dap/DAP.cpp b/lldb/tools/lldb-dap/DAP.cpp
index edd3b31be8ff7..485c420dc59e8 100644
--- a/lldb/tools/lldb-dap/DAP.cpp
+++ b/lldb/tools/lldb-dap/DAP.cpp
@@ -1128,6 +1128,32 @@ DAP::GetInstructionBPFromStopReason(lldb::SBThread 
&thread) {
   return inst_bp;
 }
 
+FunctionBreakpoint *DAP::GetFunctionBPFromStopReason(lldb::SBThread &thread) {
+  const auto num = thread.GetStopReasonDataCount();
+  FunctionBreakpoint *func_bp = nullptr;
+  for (size_t i = 0; i < num; i += 2) {
+// thread.GetStopReasonDataAtIndex(i) will return the bp ID and
+// thread.GetStopReasonDataAtIndex(i+1) will return the location
+// within that breakpoint. We only care about the bp ID so we can
+// see if this is an function breakpoint that is getting hit.
+lldb::break_id_t bp_id = thread.GetStopReasonDataAtIndex(i);
+func_bp = GetFunctionBreakPoint(bp_id);
+// If any breakpoint is not an function breakpoint, then stop and
+// report this as a normal breakpoint
+if (func_bp == nullptr)
+  return nullptr;
+  }
+  return func_bp;
+}
+
+FunctionBreakpoint *DAP::GetFunctionBreakPoint(const lldb::break_id_t bp_id) {
+  for (auto &bp : function_breakpoints) {
+if (bp.second.bp.GetID() == bp_id)
+  return &bp.second;
+  }
+  return nullptr;
+}
+
 lldb::SBValueList *Variables::GetTopLevelScope(int64_t variablesReference) {
   switch (variablesReference) {
   case VARREF_LOCALS:
diff --git a/lldb/tools/lldb-dap/DAP.h b/lldb/tools/lldb-dap/DAP.h
index 3ff1992b61f5b..ea72b41d02516 100644
--- a/lldb/tools/lldb-dap/DAP.h
+++ b/lldb/tools/lldb-dap/DAP.h
@@ -125,21 +125,21 @@ struct Variables {
 
 struct StartDebuggingRequestHandler : public lldb::SBCommandPluginInterface {
   DAP &dap;
-  explicit StartDebuggingRequestHandler(DAP &d) : dap(d) {};
+  explicit StartDebuggingRequestHandler(DAP &d) : dap(d){};
   bool DoExecute(lldb::SBDebugger debugger, char **command,
  lldb::SBCommandReturnObject &result) override;
 };
 
 struct ReplModeRequestHandler : public lldb::SBCommandPluginInterface {
   DAP &dap;
-  explicit ReplModeRequestHandler(DAP &d) : dap(d) {};
+  explicit ReplModeRequestHandler(DAP &d) : dap(d){};
   bool DoExecute(lldb::SBDebugger debugger, char **command,
  lldb::SBCommandReturnObject &result) override;
 };
 
 struct SendEventRequestHandler : public lldb::SBCommandPluginInterface {
   DAP &dap;
-  explicit SendEventRequestHandler(DAP &d) : dap(d) {};
+  explicit SendEventRequestHandler(DAP &d) : dap(d){};
   bool DoExecute(lldb::SBDebugger debugger, char **command,
  lldb::SBCommandReturnObject &result) override;
 };
@@ -383,6 +383,12 @@ struct DAP {
 
   InstructionBreakpoint *GetInstructionBPFromStopReason(lldb::SBThread 
&thread);
 
+  FunctionBreakpoint *GetFunctionBPFromStopReason(lldb::SBThread &thread);
+
+  FunctionBreakpoint *GetFunctionBreakPoint(const lldb::break_id_t bp_id);
+
+  void WaitWorkerThreadsToExit();
+
 private:
   // Send the JSON in "json_str" to the "out" stream. Correctly send the
   // "Content-Length:" field followed by the length, followed by the raw
diff --git a/lldb/tools/lldb-dap/JSONUtils.cpp 
b/lldb/tools

[Lldb-commits] [lldb] 7790d69 - [lldb-dap] Refactoring IOStream into Transport handler. (#130026)

2025-03-12 Thread via lldb-commits

Author: John Harrison
Date: 2025-03-12T12:29:05-07:00
New Revision: 7790d69cce048d7c81fceaf979fd2ec60e37476b

URL: 
https://github.com/llvm/llvm-project/commit/7790d69cce048d7c81fceaf979fd2ec60e37476b
DIFF: 
https://github.com/llvm/llvm-project/commit/7790d69cce048d7c81fceaf979fd2ec60e37476b.diff

LOG: [lldb-dap] Refactoring IOStream into Transport handler. (#130026)

Instead of having two discrete InputStream and OutputStream helpers,
this merges the two into a unifed 'Transport' handler.

This handler is responsible for reading the DAP message headers, parsing
the resulting JSON and converting the messages into
`lldb_dap::protocol::Message`s for both input and output.

-

Co-authored-by: Jonas Devlieghere 

Added: 
lldb/tools/lldb-dap/Transport.cpp
lldb/tools/lldb-dap/Transport.h

Modified: 
lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py
lldb/test/API/tools/lldb-dap/io/TestDAP_io.py
lldb/tools/lldb-dap/CMakeLists.txt
lldb/tools/lldb-dap/DAP.cpp
lldb/tools/lldb-dap/DAP.h
lldb/tools/lldb-dap/Handler/InitializeRequestHandler.cpp
lldb/tools/lldb-dap/lldb-dap.cpp

Removed: 
lldb/tools/lldb-dap/IOStream.cpp
lldb/tools/lldb-dap/IOStream.h



diff  --git a/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py 
b/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py
index 9471594b66012..0fea3419d9725 100644
--- a/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py
+++ b/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py
@@ -337,7 +337,7 @@ def send_recv(self, command):
 self.send_packet(
 {
 "type": "response",
-"seq": -1,
+"seq": 0,
 "request_seq": response_or_request["seq"],
 "success": True,
 "command": "runInTerminal",
@@ -349,7 +349,7 @@ def send_recv(self, command):
 self.send_packet(
 {
 "type": "response",
-"seq": -1,
+"seq": 0,
 "request_seq": response_or_request["seq"],
 "success": True,
 "command": "startDebugging",

diff  --git a/lldb/test/API/tools/lldb-dap/io/TestDAP_io.py 
b/lldb/test/API/tools/lldb-dap/io/TestDAP_io.py
index 04414cd7a3cdf..f05f876e57b49 100644
--- a/lldb/test/API/tools/lldb-dap/io/TestDAP_io.py
+++ b/lldb/test/API/tools/lldb-dap/io/TestDAP_io.py
@@ -2,6 +2,8 @@
 Test lldb-dap IO handling.
 """
 
+import sys
+
 from lldbsuite.test.decorators import *
 import lldbdap_testcase
 import dap_server
@@ -19,18 +21,18 @@ def cleanup():
 if process.poll() is None:
 process.terminate()
 process.wait()
-stdout_data = process.stdout.read()
-stderr_data = process.stderr.read()
-print("= STDOUT =")
-print(stdout_data)
-print("= END =")
-print("= STDERR =")
-print(stderr_data)
-print("= END =")
-print("= DEBUG ADAPTER PROTOCOL LOGS =")
+stdout_data = process.stdout.read().decode()
+stderr_data = process.stderr.read().decode()
+print("= STDOUT =", file=sys.stderr)
+print(stdout_data, file=sys.stderr)
+print("= END =", file=sys.stderr)
+print("= STDERR =", file=sys.stderr)
+print(stderr_data, file=sys.stderr)
+print("= END =", file=sys.stderr)
+print("= DEBUG ADAPTER PROTOCOL LOGS =", 
file=sys.stderr)
 with open(log_file_path, "r") as file:
-print(file.read())
-print("= END =")
+print(file.read(), file=sys.stderr)
+print("= END =", file=sys.stderr)
 
 # Execute the cleanup function during test case tear down.
 self.addTearDownHook(cleanup)
@@ -45,6 +47,15 @@ def test_eof_immediately(self):
 process.stdin.close()
 self.assertEqual(process.wait(timeout=5.0), 0)
 
+def test_invalid_header(self):
+"""
+lldb-dap handles invalid message headers.
+"""
+process = self.launch()
+process.stdin.write(b"not the corret message header")
+process.stdin.close()
+self.assertEqual(process.wait(timeout=5.0), 1)
+
 def test_partial_header(self):
 """
 lldb-dap handles parital message headers.
@@ -52,7 +63,7 @@ def test_partial_header(self):
 process = self.launch()
 pro

[Lldb-commits] [lldb] [lldb] Support discontinuous functions in another Disasembler overload (PR #130987)

2025-03-12 Thread Pavel Labath via lldb-commits

https://github.com/labath created 
https://github.com/llvm/llvm-project/pull/130987

This overload is taking a StackFrame, so we just need to change how we obtain 
the ranges out of it. A slightly fiddly aspect is the code which tries to 
provide a default dissassembly range for the case where we don't have a real 
one. I believe this case is only relevant for symbol-based stack frames as 
debug info always has size/range for the functions (if it didn't we wouldn't 
even resolve the stack frame to a function), which is why I've split the 
handling of the two cases.

We already have a test case for disassembly of discontinuous functions (in 
test/Shell/Commands/command-disassemble.s), so I'm not creating another one as 
this is just a slightly different entry point into the same code.

>From 1f79d61274bb04aa37e043a7b33a1711dc66361d Mon Sep 17 00:00:00 2001
From: Pavel Labath 
Date: Wed, 12 Mar 2025 13:35:46 +0100
Subject: [PATCH] [lldb] Support discontinuous functions in another Disasembler
 overload

This overload is taking a StackFrame, so we just need to change how we
obtain the ranges out of it. A slightly fiddly aspect is the code which
tries to provide a default dissassembly range for the case where we don't
have a real one. I believe this case is only relevant for symbol-based
stack frames as debug info always has size/range for the functions (if
it didn't we wouldn't even resolve the stack frame to a function), which
is why I've split the handling of the two cases.

We already have a test case for disassembly of discontinuous functions
(in test/Shell/Commands/command-disassemble.s), so I'm not creating
another one as this is just a slightly different entry point into the
same code.
---
 lldb/source/Core/Disassembler.cpp | 29 ++---
 1 file changed, 18 insertions(+), 11 deletions(-)

diff --git a/lldb/source/Core/Disassembler.cpp 
b/lldb/source/Core/Disassembler.cpp
index b05be7e1a46d7..9b1d4e9316cb0 100644
--- a/lldb/source/Core/Disassembler.cpp
+++ b/lldb/source/Core/Disassembler.cpp
@@ -552,28 +552,35 @@ void Disassembler::PrintInstructions(Debugger &debugger, 
const ArchSpec &arch,
 
 bool Disassembler::Disassemble(Debugger &debugger, const ArchSpec &arch,
StackFrame &frame, Stream &strm) {
-  AddressRange range;
   SymbolContext sc(
   frame.GetSymbolContext(eSymbolContextFunction | eSymbolContextSymbol));
   if (sc.function) {
-range = sc.function->GetAddressRange();
-  } else if (sc.symbol && sc.symbol->ValueIsAddress()) {
+if (DisassemblerSP disasm_sp = DisassembleRange(
+arch, nullptr, nullptr, nullptr, nullptr, *frame.CalculateTarget(),
+sc.function->GetAddressRanges())) {
+  disasm_sp->PrintInstructions(debugger, arch, frame, false, 0, 0, strm);
+  return true;
+}
+return false;
+  }
+
+  AddressRange range;
+  if (sc.symbol && sc.symbol->ValueIsAddress()) {
 range.GetBaseAddress() = sc.symbol->GetAddressRef();
 range.SetByteSize(sc.symbol->GetByteSize());
   } else {
 range.GetBaseAddress() = frame.GetFrameCodeAddress();
   }
 
-if (range.GetBaseAddress().IsValid() && range.GetByteSize() == 0)
-  range.SetByteSize(DEFAULT_DISASM_BYTE_SIZE);
+  if (range.GetBaseAddress().IsValid() && range.GetByteSize() == 0)
+range.SetByteSize(DEFAULT_DISASM_BYTE_SIZE);
 
-Disassembler::Limit limit = {Disassembler::Limit::Bytes,
- range.GetByteSize()};
-if (limit.value == 0)
-  limit.value = DEFAULT_DISASM_BYTE_SIZE;
+  Disassembler::Limit limit = {Disassembler::Limit::Bytes, 
range.GetByteSize()};
+  if (limit.value == 0)
+limit.value = DEFAULT_DISASM_BYTE_SIZE;
 
-return Disassemble(debugger, arch, nullptr, nullptr, nullptr, nullptr,
-   frame, range.GetBaseAddress(), limit, false, 0, 0, 
strm);
+  return Disassemble(debugger, arch, nullptr, nullptr, nullptr, nullptr, frame,
+ range.GetBaseAddress(), limit, false, 0, 0, strm);
 }
 
 Instruction::Instruction(const Address &address, AddressClass addr_class)

___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb-dap] Refactoring IOStream into Transport handler. (PR #130026)

2025-03-12 Thread Jonas Devlieghere via lldb-commits


@@ -0,0 +1,126 @@
+//===-- Transport.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 "Transport.h"
+#include "DAPLog.h"
+#include "Protocol.h"
+#include "lldb/Utility/IOObject.h"
+#include "lldb/Utility/Status.h"
+#include "lldb/lldb-forward.h"
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Error.h"
+#include "llvm/Support/raw_ostream.h"
+#include 
+#include 
+
+using namespace llvm;
+using namespace lldb;
+using namespace lldb_private;
+using namespace lldb_dap;
+using namespace lldb_dap::protocol;
+
+/// ReadFull attempts to read the specified number of bytes. If EOF is
+/// encountered, '' is returned.

JDevlieghere wrote:

```suggestion
/// encountered, an empty string is returned.
```

https://github.com/llvm/llvm-project/pull/130026
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb-dap] Refactoring IOStream into Transport handler. (PR #130026)

2025-03-12 Thread Jonas Devlieghere via lldb-commits


@@ -221,52 +222,22 @@ void DAP::StopEventHandlers() {
   }
 }
 
-// Send the JSON in "json_str" to the "out" stream. Correctly send the
-// "Content-Length:" field followed by the length, followed by the raw
-// JSON bytes.
-void DAP::SendJSON(const std::string &json_str) {
-  output.write_full("Content-Length: ");
-  output.write_full(llvm::utostr(json_str.size()));
-  output.write_full("\r\n\r\n");
-  output.write_full(json_str);
-}
-
 // Serialize the JSON value into a string and send the JSON packet to
 // the "out" stream.
 void DAP::SendJSON(const llvm::json::Value &json) {
-  std::string json_str;
-  llvm::raw_string_ostream strm(json_str);
-  strm << json;
-  static std::mutex mutex;
-  std::lock_guard locker(mutex);
-  SendJSON(json_str);
-
-  DAP_LOG(log, "({0}) <-- {1}", client_name, json_str);
-}
-
-// Read a JSON packet from the "in" stream.
-std::string DAP::ReadJSON() {
-  std::string length_str;
-  std::string json_str;
-  int length;
-
-  if (!input.read_expected(log, "Content-Length: "))
-return json_str;
-
-  if (!input.read_line(log, length_str))
-return json_str;
-
-  if (!llvm::to_integer(length_str, length))
-return json_str;
-
-  if (!input.read_expected(log, "\r\n"))
-return json_str;
-
-  if (!input.read_full(log, length, json_str))
-return json_str;
-
-  DAP_LOG(log, "({0}) --> {1}", client_name, json_str);
-  return json_str;
+  // FIXME: Instead of parsing the output message from JSON, pass the `Message`
+  // as parameter to `SendJSON`.
+  protocol::Message message;
+  llvm::json::Path::Root root;
+  if (!fromJSON(json, message, root)) {
+DAP_LOG_ERROR(log, root.getError(), "({1}) encoding failed: {0}",
+  client_name);
+return;
+  }
+  auto err = transport.Write(message);
+  if (err) {
+DAP_LOG_ERROR(log, std::move(err), "({1}) write failed: {0}", client_name);
+  }

JDevlieghere wrote:

Nit: the type of `err` is not obvious from the RHS so I don't think `auto` is 
appropriate. Also no braces for single line `if`s:
```suggestion
  if (llvm::Error err = transport.Write(message)) 
DAP_LOG_ERROR(log, std::move(err), "({1}) write failed: {0}", client_name);
  ```

https://github.com/llvm/llvm-project/pull/130026
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb-dap] Refactoring IOStream into Transport handler. (PR #130026)

2025-03-12 Thread Jonas Devlieghere via lldb-commits

https://github.com/JDevlieghere edited 
https://github.com/llvm/llvm-project/pull/130026
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] Support discontinuous functions in another Disasembler overload (PR #130987)

2025-03-12 Thread Pavel Labath via lldb-commits

https://github.com/labath updated 
https://github.com/llvm/llvm-project/pull/130987

>From 1f79d61274bb04aa37e043a7b33a1711dc66361d Mon Sep 17 00:00:00 2001
From: Pavel Labath 
Date: Wed, 12 Mar 2025 13:35:46 +0100
Subject: [PATCH 1/2] [lldb] Support discontinuous functions in another
 Disasembler overload

This overload is taking a StackFrame, so we just need to change how we
obtain the ranges out of it. A slightly fiddly aspect is the code which
tries to provide a default dissassembly range for the case where we don't
have a real one. I believe this case is only relevant for symbol-based
stack frames as debug info always has size/range for the functions (if
it didn't we wouldn't even resolve the stack frame to a function), which
is why I've split the handling of the two cases.

We already have a test case for disassembly of discontinuous functions
(in test/Shell/Commands/command-disassemble.s), so I'm not creating
another one as this is just a slightly different entry point into the
same code.
---
 lldb/source/Core/Disassembler.cpp | 29 ++---
 1 file changed, 18 insertions(+), 11 deletions(-)

diff --git a/lldb/source/Core/Disassembler.cpp 
b/lldb/source/Core/Disassembler.cpp
index b05be7e1a46d7..9b1d4e9316cb0 100644
--- a/lldb/source/Core/Disassembler.cpp
+++ b/lldb/source/Core/Disassembler.cpp
@@ -552,28 +552,35 @@ void Disassembler::PrintInstructions(Debugger &debugger, 
const ArchSpec &arch,
 
 bool Disassembler::Disassemble(Debugger &debugger, const ArchSpec &arch,
StackFrame &frame, Stream &strm) {
-  AddressRange range;
   SymbolContext sc(
   frame.GetSymbolContext(eSymbolContextFunction | eSymbolContextSymbol));
   if (sc.function) {
-range = sc.function->GetAddressRange();
-  } else if (sc.symbol && sc.symbol->ValueIsAddress()) {
+if (DisassemblerSP disasm_sp = DisassembleRange(
+arch, nullptr, nullptr, nullptr, nullptr, *frame.CalculateTarget(),
+sc.function->GetAddressRanges())) {
+  disasm_sp->PrintInstructions(debugger, arch, frame, false, 0, 0, strm);
+  return true;
+}
+return false;
+  }
+
+  AddressRange range;
+  if (sc.symbol && sc.symbol->ValueIsAddress()) {
 range.GetBaseAddress() = sc.symbol->GetAddressRef();
 range.SetByteSize(sc.symbol->GetByteSize());
   } else {
 range.GetBaseAddress() = frame.GetFrameCodeAddress();
   }
 
-if (range.GetBaseAddress().IsValid() && range.GetByteSize() == 0)
-  range.SetByteSize(DEFAULT_DISASM_BYTE_SIZE);
+  if (range.GetBaseAddress().IsValid() && range.GetByteSize() == 0)
+range.SetByteSize(DEFAULT_DISASM_BYTE_SIZE);
 
-Disassembler::Limit limit = {Disassembler::Limit::Bytes,
- range.GetByteSize()};
-if (limit.value == 0)
-  limit.value = DEFAULT_DISASM_BYTE_SIZE;
+  Disassembler::Limit limit = {Disassembler::Limit::Bytes, 
range.GetByteSize()};
+  if (limit.value == 0)
+limit.value = DEFAULT_DISASM_BYTE_SIZE;
 
-return Disassemble(debugger, arch, nullptr, nullptr, nullptr, nullptr,
-   frame, range.GetBaseAddress(), limit, false, 0, 0, 
strm);
+  return Disassemble(debugger, arch, nullptr, nullptr, nullptr, nullptr, frame,
+ range.GetBaseAddress(), limit, false, 0, 0, strm);
 }
 
 Instruction::Instruction(const Address &address, AddressClass addr_class)

>From 0b629e15060e88f1f50e403cc34780f446de232c Mon Sep 17 00:00:00 2001
From: Pavel Labath 
Date: Wed, 12 Mar 2025 17:30:32 +0100
Subject: [PATCH 2/2] format

---
 lldb/source/Core/Disassembler.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/lldb/source/Core/Disassembler.cpp 
b/lldb/source/Core/Disassembler.cpp
index 9b1d4e9316cb0..0afc593fdb975 100644
--- a/lldb/source/Core/Disassembler.cpp
+++ b/lldb/source/Core/Disassembler.cpp
@@ -556,8 +556,8 @@ bool Disassembler::Disassemble(Debugger &debugger, const 
ArchSpec &arch,
   frame.GetSymbolContext(eSymbolContextFunction | eSymbolContextSymbol));
   if (sc.function) {
 if (DisassemblerSP disasm_sp = DisassembleRange(
-arch, nullptr, nullptr, nullptr, nullptr, *frame.CalculateTarget(),
-sc.function->GetAddressRanges())) {
+arch, nullptr, nullptr, nullptr, nullptr, *frame.CalculateTarget(),
+sc.function->GetAddressRanges())) {
   disasm_sp->PrintInstructions(debugger, arch, frame, false, 0, 0, strm);
   return true;
 }

___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] Support discontinuous functions in another Disasembler overload (PR #130987)

2025-03-12 Thread via lldb-commits

github-actions[bot] wrote:




:warning: C/C++ code formatter, clang-format found issues in your code. 
:warning:



You can test this locally with the following command:


``bash
git-clang-format --diff 1fe702fdecf79121346fe5374b418bc1dbf9362c 
1f79d61274bb04aa37e043a7b33a1711dc66361d --extensions cpp -- 
lldb/source/Core/Disassembler.cpp
``





View the diff from clang-format here.


``diff
diff --git a/lldb/source/Core/Disassembler.cpp 
b/lldb/source/Core/Disassembler.cpp
index 9b1d4e9316..0afc593fdb 100644
--- a/lldb/source/Core/Disassembler.cpp
+++ b/lldb/source/Core/Disassembler.cpp
@@ -556,8 +556,8 @@ bool Disassembler::Disassemble(Debugger &debugger, const 
ArchSpec &arch,
   frame.GetSymbolContext(eSymbolContextFunction | eSymbolContextSymbol));
   if (sc.function) {
 if (DisassemblerSP disasm_sp = DisassembleRange(
-arch, nullptr, nullptr, nullptr, nullptr, *frame.CalculateTarget(),
-sc.function->GetAddressRanges())) {
+arch, nullptr, nullptr, nullptr, nullptr, *frame.CalculateTarget(),
+sc.function->GetAddressRanges())) {
   disasm_sp->PrintInstructions(debugger, arch, frame, false, 0, 0, strm);
   return true;
 }

``




https://github.com/llvm/llvm-project/pull/130987
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] Remove Function::GetAddressRange usage from the gui (PR #130991)

2025-03-12 Thread Pavel Labath via lldb-commits

https://github.com/labath created 
https://github.com/llvm/llvm-project/pull/130991

m_disassembly_range was used only to prune the list of breakpoints to those 
that are in the current function. This isn't really necessary, as the list is 
only used to highlight instructions with breakpoints on them, and an unpruned 
list works just as well for that.

The shouldn't make things slower, since we still needed through iterate through 
all breakpoints to create the list, and I doubt anyone will notice the memory 
used to store the extra breakpoints.

>From 151c42bcd05cc9e0e327f64cba8137889cfc4fef Mon Sep 17 00:00:00 2001
From: Pavel Labath 
Date: Wed, 12 Mar 2025 17:45:53 +0100
Subject: [PATCH] [lldb] Remove Function::GetAddressRange usage from the gui

m_disassembly_range was used only to prune the list of breakpoints to
those that are in the current function. This isn't really necessary, as
the list is only used to highlight instructions with breakpoints on
them, and an unpruned list works just as well for that.

The shouldn't make things slower, since we still needed through iterate
through all breakpoints to create the list, and I doubt anyone will
notice the memory used to store the extra breakpoints.
---
 lldb/source/Core/IOHandlerCursesGUI.cpp | 26 -
 1 file changed, 4 insertions(+), 22 deletions(-)

diff --git a/lldb/source/Core/IOHandlerCursesGUI.cpp 
b/lldb/source/Core/IOHandlerCursesGUI.cpp
index ee6e847cdb688..7f0e0fc3b7293 100644
--- a/lldb/source/Core/IOHandlerCursesGUI.cpp
+++ b/lldb/source/Core/IOHandlerCursesGUI.cpp
@@ -6781,8 +6781,7 @@ class StatusBarWindowDelegate : public WindowDelegate {
 class SourceFileWindowDelegate : public WindowDelegate {
 public:
   SourceFileWindowDelegate(Debugger &debugger)
-  : WindowDelegate(), m_debugger(debugger), m_sc(), m_file_sp(),
-m_disassembly_sp(), m_disassembly_range(), m_title() {}
+  : WindowDelegate(), m_debugger(debugger) {}
 
   ~SourceFileWindowDelegate() override = default;
 
@@ -6939,12 +6938,8 @@ class SourceFileWindowDelegate : public WindowDelegate {
   m_disassembly_scope = m_sc.function;
   m_disassembly_sp = m_sc.function->GetInstructions(
   exe_ctx, nullptr, !prefer_file_cache);
-  if (m_disassembly_sp) {
+  if (m_disassembly_sp)
 set_selected_line_to_pc = true;
-m_disassembly_range = m_sc.function->GetAddressRange();
-  } else {
-m_disassembly_range.Clear();
-  }
 } else {
   set_selected_line_to_pc = context_changed;
 }
@@ -6953,14 +6948,8 @@ class SourceFileWindowDelegate : public WindowDelegate {
   m_disassembly_scope = m_sc.symbol;
   m_disassembly_sp = m_sc.symbol->GetInstructions(
   exe_ctx, nullptr, prefer_file_cache);
-  if (m_disassembly_sp) {
+  if (m_disassembly_sp)
 set_selected_line_to_pc = true;
-m_disassembly_range.GetBaseAddress() =
-m_sc.symbol->GetAddress();
-m_disassembly_range.SetByteSize(m_sc.symbol->GetByteSize());
-  } else {
-m_disassembly_range.Clear();
-  }
 } else {
   set_selected_line_to_pc = context_changed;
 }
@@ -7114,13 +7103,7 @@ class SourceFileWindowDelegate : public WindowDelegate {
  ++bp_loc_idx) {
   BreakpointLocationSP bp_loc_sp =
   bp_sp->GetLocationAtIndex(bp_loc_idx);
-  LineEntry bp_loc_line_entry;
-  const lldb::addr_t file_addr =
-  bp_loc_sp->GetAddress().GetFileAddress();
-  if (file_addr != LLDB_INVALID_ADDRESS) {
-if (m_disassembly_range.ContainsFileAddress(file_addr))
-  bp_file_addrs.insert(file_addr);
-  }
+  bp_file_addrs.insert(bp_loc_sp->GetAddress().GetFileAddress());
 }
   }
 }
@@ -7552,7 +7535,6 @@ class SourceFileWindowDelegate : public WindowDelegate {
   SourceManager::FileSP m_file_sp;
   SymbolContextScope *m_disassembly_scope = nullptr;
   lldb::DisassemblerSP m_disassembly_sp;
-  AddressRange m_disassembly_range;
   StreamString m_title;
   lldb::user_id_t m_tid = LLDB_INVALID_THREAD_ID;
   int m_line_width = 4;

___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb-dap] Updating RequestHandler to encode/decode arguments and response. (PR #130090)

2025-03-12 Thread Adrian Vogelsgesang via lldb-commits

https://github.com/vogelsgesang edited 
https://github.com/llvm/llvm-project/pull/130090
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [LLDB][Telemetry]Define TargetInfo for collecting data about a target (PR #127834)

2025-03-12 Thread Vy Nguyen via lldb-commits


@@ -1064,6 +1065,29 @@ const char *Process::GetExitDescription() {
 bool Process::SetExitStatus(int status, llvm::StringRef exit_string) {
   // Use a mutex to protect setting the exit status.
   std::lock_guard guard(m_exit_status_mutex);
+  telemetry::ScopedDispatcher helper;
+
+  // Find the executable-module's UUID, if available.
+  UUID exec_uuid;
+  // Check if there is (still) a valid target and get the debugger and 
exec_uuid
+  // from it.
+  TargetSP target_sp(Debugger::FindTargetWithProcessID(m_pid));
+  if (target_sp) {
+helper.SetDebugger(&(target_sp->GetDebugger()));
+exec_uuid = target_sp->GetExecModuleUUID();

oontvoo wrote:

We save the Target's exec-module's UUID in the Target object because the Module 
object is gone by the time we're here.

https://github.com/llvm/llvm-project/pull/127834
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [LLDB][Telemetry]Define TargetInfo for collecting data about a target (PR #127834)

2025-03-12 Thread Vy Nguyen via lldb-commits

oontvoo wrote:


> This is why I suggested way back to focus on SetExecutableModule, as that is 
> (one) place where all of these paths converge, and it covers the most 
> expensive part of the operation. I don't think it's the only way to capture 
> all this information, but I still think it's _a_ way to do it. However, it's 
> definitely not the same as "loading/creating a target".

Thanks for the example! THat makes a lot more sense now.
I've updated the patch to : 
 - Use separate entries for describing the Main-executable and for the 
process-exit
 - Rename the struct as suggested

About the `exec*()` use case, would be nice to be able to have *something* to 
uniquely identify each image ... but i'm not sure what it is ... for now they 
would just have to be duplicate entries (same module id)

https://github.com/llvm/llvm-project/pull/127834
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [LLDB][Telemetry]Define TargetInfo for collecting data about a target (PR #127834)

2025-03-12 Thread Vy Nguyen via lldb-commits

https://github.com/oontvoo updated 
https://github.com/llvm/llvm-project/pull/127834

>From 0d6a36d84df50ccb9eef9ef3dd6f59d4299edeac Mon Sep 17 00:00:00 2001
From: Vy Nguyen 
Date: Wed, 19 Feb 2025 12:47:57 -0500
Subject: [PATCH 01/18] [LLDB][Telemetry]Define TargetInfo for collecting data
 about a target

---
 lldb/include/lldb/Core/Telemetry.h | 86 +-
 lldb/source/Core/Telemetry.cpp | 99 ++
 2 files changed, 170 insertions(+), 15 deletions(-)

diff --git a/lldb/include/lldb/Core/Telemetry.h 
b/lldb/include/lldb/Core/Telemetry.h
index b72556ecaf3c9..4be81951254de 100644
--- a/lldb/include/lldb/Core/Telemetry.h
+++ b/lldb/include/lldb/Core/Telemetry.h
@@ -13,6 +13,7 @@
 #include "lldb/Interpreter/CommandReturnObject.h"
 #include "lldb/Utility/StructuredData.h"
 #include "lldb/lldb-forward.h"
+#include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/StringExtras.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/Support/JSON.h"
@@ -29,6 +30,9 @@ namespace telemetry {
 
 struct LLDBEntryKind : public ::llvm::telemetry::EntryKind {
   static const llvm::telemetry::KindType BaseInfo = 0b11000;
+  static const KindType TargetInfo = 0b11010;
+  // There are other entries in between (added in separate PRs)
+  static const llvm::telemetry::KindType MiscInfo = 0b0;
 };
 
 /// Defines a convenient type for timestamp of various events.
@@ -56,14 +60,88 @@ struct LLDBBaseTelemetryInfo : public 
llvm::telemetry::TelemetryInfo {
   void serialize(llvm::telemetry::Serializer &serializer) const override;
 };
 
+/// Describes an exit status.
+struct ExitDescription {
+  int exit_code;
+  std::string description;
+};
+
+struct TargetTelemetryInfo : public LldbBaseTelemetryInfo {
+  lldb::ModuleSP exec_mod;
+  Target *target_ptr;
+
+  // The same as the executable-module's UUID.
+  std::string target_uuid;
+  std::string file_format;
+
+  std::string binary_path;
+  size_t binary_size;
+
+  std::optional exit_desc;
+  TargetTelemetryInfo() = default;
+
+  TargetTelemetryInfo(const TargetTelemetryInfo &other) {
+exec_mod = other.exec_mod;
+target_uuid = other.target_uuid;
+file_format = other.file_format;
+binary_path = other.binary_path;
+binary_size = other.binary_size;
+exit_desc = other.exit_desc;
+  }
+
+  KindType getKind() const override { return LldbEntryKind::TargetInfo; }
+
+  static bool classof(const TelemetryInfo *T) {
+if (T == nullptr)
+  return false;
+return T->getKind() == LldbEntryKind::TargetInfo;
+  }
+
+  void serialize(Serializer &serializer) const override;
+};
+
+/// The "catch-all" entry to store a set of non-standard data, such as
+/// error-messages, etc.
+struct MiscTelemetryInfo : public LLDBBaseTelemetryInfo {
+  /// If the event is/can be associated with a target entry,
+  /// this field contains that target's UUID.
+  ///  otherwise.
+  std::string target_uuid;
+
+  /// Set of key-value pairs for any optional (or impl-specific) data
+  std::map meta_data;
+
+  MiscTelemetryInfo() = default;
+
+  MiscTelemetryInfo(const MiscTelemetryInfo &other) {
+target_uuid = other.target_uuid;
+meta_data = other.meta_data;
+  }
+
+  llvm::telemetry::KindType getKind() const override {
+return LLDBEntryKind::MiscInfo;
+  }
+
+  static bool classof(const llvm::telemetry::TelemetryInfo *T) {
+return T->getKind() == LLDBEntryKind::MiscInfo;
+  }
+
+  void serialize(llvm::telemetry::Serializer &serializer) const override;
+};
+
 /// The base Telemetry manager instance in LLDB.
 /// This class declares additional instrumentation points
 /// applicable to LLDB.
-class TelemetryManager : public llvm::telemetry::Manager {
+class TelemetryMager : public llvm::telemetry::Manager {
 public:
   llvm::Error preDispatch(llvm::telemetry::TelemetryInfo *entry) override;
 
-  virtual llvm::StringRef GetInstanceName() const = 0;
+  const llvm::telemetry::Config *getConfig();
+
+  virtual void AtMainExecutableLoadStart(TargetInfo * entry);
+  virtual void AtMainExecutableLoadEnd(TargetInfo *entry);
+
+  virtual llvm::StringRef GetInstanceName() const = 0;
   static TelemetryManager *getInstance();
 
 protected:
@@ -73,6 +151,10 @@ class TelemetryManager : public llvm::telemetry::Manager {
 
 private:
   std::unique_ptr m_config;
+  // Each debugger is assigned a unique ID (session_id).
+  // All TelemetryInfo entries emitted for the same debugger instance
+  // will get the same session_id.
+  llvm::DenseMap session_ids;
   static std::unique_ptr g_instance;
 };
 
diff --git a/lldb/source/Core/Telemetry.cpp b/lldb/source/Core/Telemetry.cpp
index 5222f76704f91..da7aee01680fc 100644
--- a/lldb/source/Core/Telemetry.cpp
+++ b/lldb/source/Core/Telemetry.cpp
@@ -10,14 +10,20 @@
 
 #ifdef LLVM_BUILD_TELEMETRY
 
-#include "lldb/Core/Telemetry.h"
 #include "lldb/Core/Debugger.h"
+#include "lldb/Core/Telemetry.h"
+#include "lldb/Host/FileSystem.h"
+#include "lldb/Host/HostInfo.h"
+#include "lldb/Target/Process.h"
+#include "l

[Lldb-commits] [lldb] [lldb] Remove Function::GetAddressRange usage from the gui (PR #130991)

2025-03-12 Thread Jonas Devlieghere via lldb-commits

https://github.com/JDevlieghere approved this pull request.


https://github.com/llvm/llvm-project/pull/130991
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [LLDB][Telemetry]Define TargetInfo for collecting data about a target (PR #127834)

2025-03-12 Thread Vy Nguyen via lldb-commits

https://github.com/oontvoo updated 
https://github.com/llvm/llvm-project/pull/127834

>From 0d6a36d84df50ccb9eef9ef3dd6f59d4299edeac Mon Sep 17 00:00:00 2001
From: Vy Nguyen 
Date: Wed, 19 Feb 2025 12:47:57 -0500
Subject: [PATCH 01/19] [LLDB][Telemetry]Define TargetInfo for collecting data
 about a target

---
 lldb/include/lldb/Core/Telemetry.h | 86 +-
 lldb/source/Core/Telemetry.cpp | 99 ++
 2 files changed, 170 insertions(+), 15 deletions(-)

diff --git a/lldb/include/lldb/Core/Telemetry.h 
b/lldb/include/lldb/Core/Telemetry.h
index b72556ecaf3c9..4be81951254de 100644
--- a/lldb/include/lldb/Core/Telemetry.h
+++ b/lldb/include/lldb/Core/Telemetry.h
@@ -13,6 +13,7 @@
 #include "lldb/Interpreter/CommandReturnObject.h"
 #include "lldb/Utility/StructuredData.h"
 #include "lldb/lldb-forward.h"
+#include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/StringExtras.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/Support/JSON.h"
@@ -29,6 +30,9 @@ namespace telemetry {
 
 struct LLDBEntryKind : public ::llvm::telemetry::EntryKind {
   static const llvm::telemetry::KindType BaseInfo = 0b11000;
+  static const KindType TargetInfo = 0b11010;
+  // There are other entries in between (added in separate PRs)
+  static const llvm::telemetry::KindType MiscInfo = 0b0;
 };
 
 /// Defines a convenient type for timestamp of various events.
@@ -56,14 +60,88 @@ struct LLDBBaseTelemetryInfo : public 
llvm::telemetry::TelemetryInfo {
   void serialize(llvm::telemetry::Serializer &serializer) const override;
 };
 
+/// Describes an exit status.
+struct ExitDescription {
+  int exit_code;
+  std::string description;
+};
+
+struct TargetTelemetryInfo : public LldbBaseTelemetryInfo {
+  lldb::ModuleSP exec_mod;
+  Target *target_ptr;
+
+  // The same as the executable-module's UUID.
+  std::string target_uuid;
+  std::string file_format;
+
+  std::string binary_path;
+  size_t binary_size;
+
+  std::optional exit_desc;
+  TargetTelemetryInfo() = default;
+
+  TargetTelemetryInfo(const TargetTelemetryInfo &other) {
+exec_mod = other.exec_mod;
+target_uuid = other.target_uuid;
+file_format = other.file_format;
+binary_path = other.binary_path;
+binary_size = other.binary_size;
+exit_desc = other.exit_desc;
+  }
+
+  KindType getKind() const override { return LldbEntryKind::TargetInfo; }
+
+  static bool classof(const TelemetryInfo *T) {
+if (T == nullptr)
+  return false;
+return T->getKind() == LldbEntryKind::TargetInfo;
+  }
+
+  void serialize(Serializer &serializer) const override;
+};
+
+/// The "catch-all" entry to store a set of non-standard data, such as
+/// error-messages, etc.
+struct MiscTelemetryInfo : public LLDBBaseTelemetryInfo {
+  /// If the event is/can be associated with a target entry,
+  /// this field contains that target's UUID.
+  ///  otherwise.
+  std::string target_uuid;
+
+  /// Set of key-value pairs for any optional (or impl-specific) data
+  std::map meta_data;
+
+  MiscTelemetryInfo() = default;
+
+  MiscTelemetryInfo(const MiscTelemetryInfo &other) {
+target_uuid = other.target_uuid;
+meta_data = other.meta_data;
+  }
+
+  llvm::telemetry::KindType getKind() const override {
+return LLDBEntryKind::MiscInfo;
+  }
+
+  static bool classof(const llvm::telemetry::TelemetryInfo *T) {
+return T->getKind() == LLDBEntryKind::MiscInfo;
+  }
+
+  void serialize(llvm::telemetry::Serializer &serializer) const override;
+};
+
 /// The base Telemetry manager instance in LLDB.
 /// This class declares additional instrumentation points
 /// applicable to LLDB.
-class TelemetryManager : public llvm::telemetry::Manager {
+class TelemetryMager : public llvm::telemetry::Manager {
 public:
   llvm::Error preDispatch(llvm::telemetry::TelemetryInfo *entry) override;
 
-  virtual llvm::StringRef GetInstanceName() const = 0;
+  const llvm::telemetry::Config *getConfig();
+
+  virtual void AtMainExecutableLoadStart(TargetInfo * entry);
+  virtual void AtMainExecutableLoadEnd(TargetInfo *entry);
+
+  virtual llvm::StringRef GetInstanceName() const = 0;
   static TelemetryManager *getInstance();
 
 protected:
@@ -73,6 +151,10 @@ class TelemetryManager : public llvm::telemetry::Manager {
 
 private:
   std::unique_ptr m_config;
+  // Each debugger is assigned a unique ID (session_id).
+  // All TelemetryInfo entries emitted for the same debugger instance
+  // will get the same session_id.
+  llvm::DenseMap session_ids;
   static std::unique_ptr g_instance;
 };
 
diff --git a/lldb/source/Core/Telemetry.cpp b/lldb/source/Core/Telemetry.cpp
index 5222f76704f91..da7aee01680fc 100644
--- a/lldb/source/Core/Telemetry.cpp
+++ b/lldb/source/Core/Telemetry.cpp
@@ -10,14 +10,20 @@
 
 #ifdef LLVM_BUILD_TELEMETRY
 
-#include "lldb/Core/Telemetry.h"
 #include "lldb/Core/Debugger.h"
+#include "lldb/Core/Telemetry.h"
+#include "lldb/Host/FileSystem.h"
+#include "lldb/Host/HostInfo.h"
+#include "lldb/Target/Process.h"
+#include "l

[Lldb-commits] [lldb] [lldb] Use Function::GetAddressRange*s* in "frame diagnose" (PR #130949)

2025-03-12 Thread via lldb-commits

llvmbot wrote:




@llvm/pr-subscribers-lldb

Author: Pavel Labath (labath)


Changes

No test because generating discontinous functions is tedious and there's 
nothing particularly interesting happening in here. As long as the analyzer 
stays within a single basic block. it doesn't really care whether the function 
is discontinous or not. I could create cases where the algorithm breaks when 
going across basic blocks, but that's more of inherent limitation of the 
algorithm (the inability to follow jumps "backwards") than something specific 
to discontinous functions.

At this point, I'm more interested in cleaning up the last few remaining uses 
of the deprecated function that I'm about improving "frame diagnose".

---
Full diff: https://github.com/llvm/llvm-project/pull/130949.diff


1 Files Affected:

- (modified) lldb/source/Target/StackFrame.cpp (+6-10) 


``diff
diff --git a/lldb/source/Target/StackFrame.cpp 
b/lldb/source/Target/StackFrame.cpp
index d92b7d8b9d899..bab36e9aa1033 100644
--- a/lldb/source/Target/StackFrame.cpp
+++ b/lldb/source/Target/StackFrame.cpp
@@ -1783,15 +1783,11 @@ lldb::ValueObjectSP 
StackFrame::GuessValueForRegisterAndOffset(ConstString reg,
 return ValueObjectSP();
   }
 
-  AddressRange pc_range = function->GetAddressRange();
-
-  if (GetFrameCodeAddress().GetFileAddress() <
-  pc_range.GetBaseAddress().GetFileAddress() ||
-  GetFrameCodeAddress().GetFileAddress() -
-  pc_range.GetBaseAddress().GetFileAddress() >=
-  pc_range.GetByteSize()) {
+  AddressRange unused_range;
+  if (!function->GetRangeContainingLoadAddress(
+  GetFrameCodeAddress().GetLoadAddress(target_sp.get()), *target_sp,
+  unused_range))
 return ValueObjectSP();
-  }
 
   const char *plugin_name = nullptr;
   const char *flavor = nullptr;
@@ -1799,8 +1795,8 @@ lldb::ValueObjectSP 
StackFrame::GuessValueForRegisterAndOffset(ConstString reg,
   const char *features = nullptr;
   const bool force_live_memory = true;
   DisassemblerSP disassembler_sp = Disassembler::DisassembleRange(
-  target_arch, plugin_name, flavor, cpu, features, *target_sp, pc_range,
-  force_live_memory);
+  target_arch, plugin_name, flavor, cpu, features, *target_sp,
+  function->GetAddressRanges(), force_live_memory);
 
   if (!disassembler_sp || !disassembler_sp->GetInstructionList().GetSize()) {
 return ValueObjectSP();

``




https://github.com/llvm/llvm-project/pull/130949
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb-dap] Support vscode launch URLs (PR #125843)

2025-03-12 Thread Adrian Vogelsgesang via lldb-commits

https://github.com/vogelsgesang updated 
https://github.com/llvm/llvm-project/pull/125843

>From 48e900c6a8bd24c7cbee057eb0d96b9f0b2b4f84 Mon Sep 17 00:00:00 2001
From: Adrian Vogelsgesang 
Date: Wed, 5 Feb 2025 10:11:38 +
Subject: [PATCH 1/4] [lldb-dap] Support vscode launch URLs

This commit adds support for starting debug sessions through special
`vscode://llvm-vs-code-extensions.lldb-dap/launch/config?config={launch-config}`
URIs. This allows tighter integration with custom scripts. One potential
use case is providing similar functionality to `xcdebug`, see #125777
for some discussion on that use case.

The functionality was inspired by @vadimcn's CodeLLDB extension, which
[provides similar 
functionality](https://github.com/vadimcn/codelldb/blob/master/MANUAL.md#debugging-externally-launched-code).
---
 lldb/tools/lldb-dap/README.md | 16 +++-
 lldb/tools/lldb-dap/package.json  |  3 +-
 lldb/tools/lldb-dap/src-ts/extension.ts   |  5 +++
 .../lldb-dap/src-ts/uri-launch-handler.ts | 37 +++
 4 files changed, 59 insertions(+), 2 deletions(-)
 create mode 100644 lldb/tools/lldb-dap/src-ts/uri-launch-handler.ts

diff --git a/lldb/tools/lldb-dap/README.md b/lldb/tools/lldb-dap/README.md
index 123869a033724..34876c4c37cb6 100644
--- a/lldb/tools/lldb-dap/README.md
+++ b/lldb/tools/lldb-dap/README.md
@@ -174,6 +174,20 @@ The default hostname being used `localhost`.
 }
 ```
 
+### Launching via `vscode://` URIs
+
+Debugging sessions can also be starting using special URIs.
+
+The 
`vscode://llvm-vs-code-extensions.lldb-dap/launch/config?config={launch-config}`
+URI accepts a [URL-encoded](https://en.wikipedia.org/wiki/Percent-encoding)
+JSON launch config.
+
+This is useful, e.g., to integrate with custom scripts which start debugging
+sessions. The URIs might be printed to the terminal, potentially using
+[OSC-8 
hyperlinks](https://gist.github.com/egmontkob/eb114294efbcd5adb1944c9f3cb5feda),
+or passed to `vscode --open-url` or `xdg-open`, although mileage may vary
+depending on your specific debugging setup.
+
 ### Configuration Settings Reference
 
 For both launch and attach configurations, lldb-dap accepts the following 
`lldb-dap`
@@ -328,4 +342,4 @@ The source code is part of the [LLVM 
repository](https://github.com/llvm/llvm-pr
 We use Github's [issue 
tracker](https://github.com/llvm/llvm-project/issues?q=label%3Alldb-dap) and 
patches can be submitted via [pull 
requests](https://github.com/llvm/llvm-project/pulls?q=label%3Alldb-dap).
 Furthermore, there is a [LLDB 
category](https://discourse.llvm.org/c/subprojects/lldb/8) on the LLVM 
discourse forum.
 
-For instructions on how to get started with development on lldb-dap, see the 
"[Contributing to lldb-dap](https://lldb.llvm.org/resources/lldbdap.html)"
+For instructions on how to get started with development on lldb-dap, see the 
"[Contributing to lldb-dap](https://lldb.llvm.org/resources/lldbdap.html)" 
guide.
diff --git a/lldb/tools/lldb-dap/package.json b/lldb/tools/lldb-dap/package.json
index cd450a614b3f7..428624f46feba 100644
--- a/lldb/tools/lldb-dap/package.json
+++ b/lldb/tools/lldb-dap/package.json
@@ -35,7 +35,8 @@
 "typescript": "^5.7.3"
   },
   "activationEvents": [
-"onDebug"
+"onDebug",
+"onUri"
   ],
   "main": "./out/extension",
   "scripts": {
diff --git a/lldb/tools/lldb-dap/src-ts/extension.ts 
b/lldb/tools/lldb-dap/src-ts/extension.ts
index a07bcdebcb68b..f0c7fb5bd1a71 100644
--- a/lldb/tools/lldb-dap/src-ts/extension.ts
+++ b/lldb/tools/lldb-dap/src-ts/extension.ts
@@ -5,6 +5,7 @@ import {
   isExecutable,
 } from "./debug-adapter-factory";
 import { DisposableContext } from "./disposable-context";
+import { LaunchUriHandler } from "./uri-launch-handler";
 
 /**
  * This class represents the extension and manages its life cycle. Other 
extensions
@@ -37,6 +38,10 @@ export class LLDBDapExtension extends DisposableContext {
 }
   }),
 );
+
+this.pushSubscription(
+  vscode.window.registerUriHandler(new LaunchUriHandler())
+);
   }
 }
 
diff --git a/lldb/tools/lldb-dap/src-ts/uri-launch-handler.ts 
b/lldb/tools/lldb-dap/src-ts/uri-launch-handler.ts
new file mode 100644
index 0..0a29ddda05713
--- /dev/null
+++ b/lldb/tools/lldb-dap/src-ts/uri-launch-handler.ts
@@ -0,0 +1,37 @@
+import * as vscode from "vscode";
+
+export class LaunchUriHandler implements vscode.UriHandler {
+async handleUri(uri: vscode.Uri) {
+try {
+const params = new URLSearchParams(uri.query);
+if (uri.path == '/launch/config') {
+const configJson = params.get("config");
+if (configJson === null) {
+throw new Error("Missing `config` URI parameter");
+}
+// Build the debug config
+let debugConfig: vscode.DebugConfiguration = {
+type: 'lldb-dap',
+request: 'launch',
+ 

[Lldb-commits] [lldb] [lldb-dap] Support vscode launch URLs (PR #125843)

2025-03-12 Thread Adrian Vogelsgesang via lldb-commits


@@ -0,0 +1,37 @@
+import * as vscode from "vscode";
+
+export class LaunchUriHandler implements vscode.UriHandler {
+async handleUri(uri: vscode.Uri) {
+try {
+const params = new URLSearchParams(uri.query);
+if (uri.path == '/launch/config') {

vogelsgesang wrote:

I decided to go with a hybrid solution: Support both `config` and separate URL 
parameters. The most commonly used arguments are supported via separate URL 
params. All other parameters can still be provided via the `config` parameter. 
That way, we don't necessarily need to keep the lists in sync

https://github.com/llvm/llvm-project/pull/125843
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb-dap] Refactoring IOStream into Transport handler. (PR #130026)

2025-03-12 Thread Pavel Labath via lldb-commits

https://github.com/labath approved this pull request.

LGTM

https://github.com/llvm/llvm-project/pull/130026
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb-dap] Refactoring IOStream into Transport handler. (PR #130026)

2025-03-12 Thread Pavel Labath via lldb-commits

https://github.com/labath edited 
https://github.com/llvm/llvm-project/pull/130026
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb][AIX] Added base files for NativeProcess Support for AIX (PR #118160)

2025-03-12 Thread Pavel Labath via lldb-commits


@@ -0,0 +1,256 @@
+//===-- NativeProcessAIX.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 "NativeProcessAIX.h"
+#include "Plugins/Process/POSIX/ProcessPOSIXLog.h"
+#include "lldb/Host/Host.h"
+#include "lldb/Host/HostProcess.h"
+#include "lldb/Host/ProcessLaunchInfo.h"
+#include "lldb/Host/posix/ProcessLauncherPosixFork.h"
+#include "lldb/Symbol/ObjectFile.h"
+#include "lldb/Utility/Log.h"
+#include "lldb/Utility/State.h"
+#include "lldb/Utility/Status.h"
+#include "llvm/Support/Errno.h"
+#include "llvm/Support/Error.h"
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+using namespace lldb;
+using namespace lldb_private;
+using namespace lldb_private::process_aix;
+using namespace llvm;
+
+static constexpr unsigned k_ptrace_word_size = sizeof(void *);
+static_assert(sizeof(long) >= k_ptrace_word_size,
+  "Size of long must be larger than ptrace word size");
+
+// Simple helper function to ensure flags are enabled on the given file
+// descriptor.
+static llvm::Error EnsureFDFlags(int fd, int flags) {
+  int status = fcntl(fd, F_GETFL);
+  if (status == -1)
+return errorCodeToError(errnoAsErrorCode());
+  if (fcntl(fd, F_SETFL, status | flags) == -1)
+return errorCodeToError(errnoAsErrorCode());
+  return Error::success();
+}
+
+NativeProcessAIX::Manager::Manager(MainLoop &mainloop)
+: NativeProcessProtocol::Manager(mainloop) {
+  Status status;
+  m_sigchld_handle = mainloop.RegisterSignal(
+  SIGCHLD, [this](MainLoopBase &) { SigchldHandler(); }, status);
+  assert(m_sigchld_handle && status.Success());
+}
+
+// Public Static Methods
+
+llvm::Expected>
+NativeProcessAIX::Manager::Launch(ProcessLaunchInfo &launch_info,
+  NativeDelegate &native_delegate) {
+  Log *log = GetLog(POSIXLog::Process);
+
+  Status status;
+  ::pid_t pid = ProcessLauncherPosixFork()
+.LaunchProcess(launch_info, status)
+.GetProcessId();
+  LLDB_LOG(log, "pid = {0:x}", pid);
+  if (status.Fail()) {
+LLDB_LOG(log, "failed to launch process: {0}", status);
+return status.ToError();
+  }
+
+  // Wait for the child process to trap on its call to execve.
+  int wstatus = 0;
+  ::pid_t wpid = llvm::sys::RetryAfterSignal(-1, ::waitpid, pid, &wstatus, 0);
+  assert(wpid == pid);
+  UNUSED_IF_ASSERT_DISABLED(wpid);
+  if (!WIFSTOPPED(wstatus)) {
+LLDB_LOG(log, "Could not sync with inferior process: wstatus={1}",
+ WaitStatus::Decode(wstatus));
+return llvm::make_error("Could not sync with inferior 
process",
+ llvm::inconvertibleErrorCode());
+  }
+  LLDB_LOG(log, "inferior started, now in stopped state");
+
+  ProcessInstanceInfo Info;
+  if (!Host::GetProcessInfo(pid, Info)) {
+return llvm::make_error("Cannot get process architectrue",
+ llvm::inconvertibleErrorCode());
+  }
+
+  // Set the architecture to the exe architecture.
+  LLDB_LOG(log, "pid = {0}, detected architecture {1}", pid,
+   Info.GetArchitecture().GetArchitectureName());
+
+  return std::unique_ptr(new NativeProcessAIX(
+  pid, launch_info.GetPTY().ReleasePrimaryFileDescriptor(), 
native_delegate,
+  Info.GetArchitecture(), *this, {pid}));
+}
+
+llvm::Expected>
+NativeProcessAIX::Manager::Attach(
+lldb::pid_t pid, NativeProcessProtocol::NativeDelegate &native_delegate) {
+  Log *log = GetLog(POSIXLog::Process);
+  LLDB_LOG(log, "pid = {0:x}", pid);
+
+  ProcessInstanceInfo Info;
+  if (!Host::GetProcessInfo(pid, Info)) {
+return llvm::make_error("Cannot get process architectrue",
+ llvm::inconvertibleErrorCode());
+  }
+  auto tids_or = NativeProcessAIX::Attach(pid);
+  if (!tids_or)
+return tids_or.takeError();
+
+  return std::unique_ptr(new NativeProcessAIX(
+  pid, -1, native_delegate, Info.GetArchitecture(), *this, *tids_or));
+}
+
+lldb::addr_t NativeProcessAIX::GetSharedLibraryInfoAddress() {
+  return LLDB_INVALID_ADDRESS;
+}
+
+NativeProcessAIX::Extension
+NativeProcessAIX::Manager::GetSupportedExtensions() const {
+  NativeProcessAIX::Extension supported = {};
+
+  return supported;
+}
+
+void NativeProcessAIX::Manager::SigchldHandler() {}
+
+void NativeProcessAIX::Manager::CollectThread(::pid_t tid) {}
+
+// Public Instance Methods
+
+NativeProcessAIX::NativeProcessAIX(::pid_t pid, int terminal_fd,
+   NativeDelegate &delegate,
+   const ArchSpec &arch, Manager &manager,
+   llvm::ArrayRef<::pid_t> tids)
+: NativeProcessProtoc

[Lldb-commits] [lldb] [lldb][AIX] Added base files for NativeProcess Support for AIX (PR #118160)

2025-03-12 Thread Pavel Labath via lldb-commits


@@ -0,0 +1,256 @@
+//===-- NativeProcessAIX.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 "NativeProcessAIX.h"
+#include "Plugins/Process/POSIX/ProcessPOSIXLog.h"
+#include "lldb/Host/Host.h"
+#include "lldb/Host/HostProcess.h"
+#include "lldb/Host/ProcessLaunchInfo.h"
+#include "lldb/Host/posix/ProcessLauncherPosixFork.h"
+#include "lldb/Symbol/ObjectFile.h"
+#include "lldb/Utility/Log.h"
+#include "lldb/Utility/State.h"
+#include "lldb/Utility/Status.h"
+#include "llvm/Support/Errno.h"
+#include "llvm/Support/Error.h"
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+using namespace lldb;
+using namespace lldb_private;
+using namespace lldb_private::process_aix;
+using namespace llvm;
+
+static constexpr unsigned k_ptrace_word_size = sizeof(void *);
+static_assert(sizeof(long) >= k_ptrace_word_size,
+  "Size of long must be larger than ptrace word size");
+
+// Simple helper function to ensure flags are enabled on the given file
+// descriptor.
+static llvm::Error EnsureFDFlags(int fd, int flags) {
+  int status = fcntl(fd, F_GETFL);
+  if (status == -1)
+return errorCodeToError(errnoAsErrorCode());
+  if (fcntl(fd, F_SETFL, status | flags) == -1)
+return errorCodeToError(errnoAsErrorCode());
+  return Error::success();
+}
+
+NativeProcessAIX::Manager::Manager(MainLoop &mainloop)
+: NativeProcessProtocol::Manager(mainloop) {
+  Status status;
+  m_sigchld_handle = mainloop.RegisterSignal(
+  SIGCHLD, [this](MainLoopBase &) { SigchldHandler(); }, status);
+  assert(m_sigchld_handle && status.Success());
+}
+
+// Public Static Methods
+
+llvm::Expected>
+NativeProcessAIX::Manager::Launch(ProcessLaunchInfo &launch_info,
+  NativeDelegate &native_delegate) {
+  Log *log = GetLog(POSIXLog::Process);
+
+  Status status;
+  ::pid_t pid = ProcessLauncherPosixFork()
+.LaunchProcess(launch_info, status)
+.GetProcessId();
+  LLDB_LOG(log, "pid = {0:x}", pid);
+  if (status.Fail()) {
+LLDB_LOG(log, "failed to launch process: {0}", status);
+return status.ToError();
+  }
+
+  // Wait for the child process to trap on its call to execve.
+  int wstatus = 0;
+  ::pid_t wpid = llvm::sys::RetryAfterSignal(-1, ::waitpid, pid, &wstatus, 0);
+  assert(wpid == pid);
+  UNUSED_IF_ASSERT_DISABLED(wpid);
+  if (!WIFSTOPPED(wstatus)) {
+LLDB_LOG(log, "Could not sync with inferior process: wstatus={1}",
+ WaitStatus::Decode(wstatus));
+return llvm::make_error("Could not sync with inferior 
process",
+ llvm::inconvertibleErrorCode());
+  }
+  LLDB_LOG(log, "inferior started, now in stopped state");
+
+  ProcessInstanceInfo Info;
+  if (!Host::GetProcessInfo(pid, Info)) {
+return llvm::make_error("Cannot get process architectrue",
+ llvm::inconvertibleErrorCode());
+  }
+
+  // Set the architecture to the exe architecture.
+  LLDB_LOG(log, "pid = {0}, detected architecture {1}", pid,
+   Info.GetArchitecture().GetArchitectureName());
+
+  return std::unique_ptr(new NativeProcessAIX(
+  pid, launch_info.GetPTY().ReleasePrimaryFileDescriptor(), 
native_delegate,
+  Info.GetArchitecture(), *this, {pid}));
+}
+
+llvm::Expected>
+NativeProcessAIX::Manager::Attach(
+lldb::pid_t pid, NativeProcessProtocol::NativeDelegate &native_delegate) {
+  Log *log = GetLog(POSIXLog::Process);
+  LLDB_LOG(log, "pid = {0:x}", pid);
+
+  ProcessInstanceInfo Info;
+  if (!Host::GetProcessInfo(pid, Info)) {
+return llvm::make_error("Cannot get process architectrue",
+ llvm::inconvertibleErrorCode());
+  }
+  auto tids_or = NativeProcessAIX::Attach(pid);
+  if (!tids_or)
+return tids_or.takeError();
+
+  return std::unique_ptr(new NativeProcessAIX(
+  pid, -1, native_delegate, Info.GetArchitecture(), *this, *tids_or));
+}
+
+lldb::addr_t NativeProcessAIX::GetSharedLibraryInfoAddress() {
+  return LLDB_INVALID_ADDRESS;
+}
+
+NativeProcessAIX::Extension
+NativeProcessAIX::Manager::GetSupportedExtensions() const {
+  NativeProcessAIX::Extension supported = {};
+
+  return supported;
+}
+
+void NativeProcessAIX::Manager::SigchldHandler() {}
+
+void NativeProcessAIX::Manager::CollectThread(::pid_t tid) {}
+
+// Public Instance Methods
+
+NativeProcessAIX::NativeProcessAIX(::pid_t pid, int terminal_fd,
+   NativeDelegate &delegate,
+   const ArchSpec &arch, Manager &manager,
+   llvm::ArrayRef<::pid_t> tids)
+: NativeProcessProtoc

[Lldb-commits] [lldb] 78c9fa3 - [lldb] Implement ANSI & Unicode aware string stripping & padding (#130878)

2025-03-12 Thread via lldb-commits

Author: Jonas Devlieghere
Date: 2025-03-12T10:20:21-07:00
New Revision: 78c9fa3a380eb2af32d4856be6d6cba36b776516

URL: 
https://github.com/llvm/llvm-project/commit/78c9fa3a380eb2af32d4856be6d6cba36b776516
DIFF: 
https://github.com/llvm/llvm-project/commit/78c9fa3a380eb2af32d4856be6d6cba36b776516.diff

LOG: [lldb] Implement ANSI & Unicode aware string stripping & padding (#130878)

This PR implements a unicode and ANSI escape code aware function to trim
and pad strings. This is a break-out from #121860.

Added: 


Modified: 
lldb/include/lldb/Utility/AnsiTerminal.h
lldb/unittests/Utility/AnsiTerminalTest.cpp

Removed: 




diff  --git a/lldb/include/lldb/Utility/AnsiTerminal.h 
b/lldb/include/lldb/Utility/AnsiTerminal.h
index 1939c49c7b859..5c99341ad888a 100644
--- a/lldb/include/lldb/Utility/AnsiTerminal.h
+++ b/lldb/include/lldb/Utility/AnsiTerminal.h
@@ -70,9 +70,12 @@
 #define ANSI_1_CTRL(ctrl1) "\033["##ctrl1 ANSI_ESC_END
 #define ANSI_2_CTRL(ctrl1, ctrl2) "\033["##ctrl1 ";"##ctrl2 ANSI_ESC_END
 
+#define ANSI_ESC_START_LEN 2
+
 #include "llvm/ADT/ArrayRef.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Locale.h"
 
 #include 
 
@@ -172,28 +175,89 @@ inline std::string 
FormatAnsiTerminalCodes(llvm::StringRef format,
   return fmt;
 }
 
+inline std::tuple
+FindNextAnsiSequence(llvm::StringRef str) {
+  llvm::StringRef left;
+  llvm::StringRef right = str;
+
+  while (!right.empty()) {
+const size_t start = right.find(ANSI_ESC_START);
+
+// ANSI_ESC_START not found.
+if (start == llvm::StringRef::npos)
+  return {str, {}, {}};
+
+// Split the string around the current ANSI_ESC_START.
+left = str.take_front(left.size() + start);
+llvm::StringRef escape = right.substr(start);
+right = right.substr(start + ANSI_ESC_START_LEN + 1);
+
+const size_t end = right.find_first_not_of("0123456789;");
+
+// ANSI_ESC_END found.
+if (end < right.size() && (right[end] == 'm' || right[end] == 'G'))
+  return {left, escape.take_front(ANSI_ESC_START_LEN + 1 + end + 1),
+  right.substr(end + 1)};
+
+// Maintain the invariant that str == left + right at the start of the 
loop.
+left = str.take_front(left.size() + ANSI_ESC_START_LEN + 1);
+  }
+
+  return {str, {}, {}};
+}
+
 inline std::string StripAnsiTerminalCodes(llvm::StringRef str) {
   std::string stripped;
   while (!str.empty()) {
-llvm::StringRef left, right;
-
-std::tie(left, right) = str.split(ANSI_ESC_START);
+auto [left, escape, right] = FindNextAnsiSequence(str);
 stripped += left;
+str = right;
+  }
+  return stripped;
+}
 
-// ANSI_ESC_START not found.
-if (left == str && right.empty())
-  break;
+inline std::string TrimAndPad(llvm::StringRef str, size_t visible_length,
+  char padding = ' ') {
+  std::string result;
+  result.reserve(visible_length);
+  size_t result_visibile_length = 0;
 
-size_t end = right.find_first_not_of("0123456789;");
-if (end < right.size() && (right[end] == 'm' || right[end] == 'G')) {
-  str = right.substr(end + 1);
-} else {
-  // ANSI_ESC_END not found.
-  stripped += ANSI_ESC_START;
-  str = right;
+  // Trim the string to the given visible length.
+  while (!str.empty()) {
+auto [left, escape, right] = FindNextAnsiSequence(str);
+str = right;
+
+// Compute the length of the string without escape codes. If it fits, 
append
+// it together with the invisible escape code.
+size_t column_width = llvm::sys::locale::columnWidth(left);
+if (result_visibile_length + column_width <= visible_length) {
+  result.append(left).append(escape);
+  result_visibile_length += column_width;
+  continue;
+}
+
+// The string might contain unicode which means it's not safe to truncate.
+// Repeatedly trim the string until it its valid unicode and fits.
+llvm::StringRef trimmed = left;
+while (!trimmed.empty()) {
+  // This relies on columnWidth returning -2 for invalid/partial unicode
+  // characters, which after conversion to size_t will be larger than the
+  // visible width.
+  column_width = llvm::sys::locale::columnWidth(trimmed);
+  if (result_visibile_length + column_width <= visible_length) {
+result.append(trimmed);
+result_visibile_length += column_width;
+break;
+  }
+  trimmed = trimmed.drop_back();
 }
   }
-  return stripped;
+
+  // Pad the string.
+  if (result_visibile_length < visible_length)
+result.append(visible_length - result_visibile_length, padding);
+
+  return result;
 }
 
 } // namespace ansi

diff  --git a/lldb/unittests/Utility/AnsiTerminalTest.cpp 
b/lldb/unittests/Utility/AnsiTerminalTest.cpp
index 1ba9565c3f6af..cef73ffaf9136 100644
--- a/lldb/unittests/Utility/AnsiTerminalTest.cpp
+++ b/lldb/unittests/Utility

[Lldb-commits] [lldb] [lldb-dap] Refactoring IOStream into Transport handler. (PR #130026)

2025-03-12 Thread John Harrison via lldb-commits


@@ -210,12 +209,33 @@ struct DAP {
   // will contain that expression.
   std::string last_nonempty_var_expression;
 
-  DAP(llvm::StringRef client_name, llvm::StringRef path, std::ofstream *log,
-  lldb::IOObjectSP input, lldb::IOObjectSP output, ReplMode repl_mode,
-  std::vector pre_init_commands);
+  /// Creates a new DAP sessions.
+  ///
+  /// \param[in] path
+  /// Path to the lldb-dap binary.
+  /// \param[in] log
+  /// Log file stream, if configured.
+  /// \param[in] default_repl_mode
+  /// Default repl mode behavior, as configured by the binary.
+  /// \param[in] pre_init_commands
+  /// LLDB commands to execute as soon as the debugger instance is 
allocaed.
+  /// \param[in] client_name
+  /// Debug session client name, for example 'stdin/stdout' or 'client_1'.

ashgti wrote:

> What's the reason for moving the `path` and `client_name` apart?

I tried to reorganize the parameters into more constant between DAP sessions to 
more unique per DAP session. i.e. 

* `path` is basically a constant (its the path to `lldb-dap` itself)
* `log` is also either setup or not at launch
* `default_repl_mode` and `pre_init_commands` are CLI flags that affect the 
starting conditions of the DAP session
* `client_name` and `transport` are the most unique values for the DAP session.

> If the `client_name` is stored in the `Transport` class, do we need to 
> duplicate it in the `DAP` object? Does it (not) make sense to get it from the 
> transport instance?

I'll update this to access the client name from the transport.

https://github.com/llvm/llvm-project/pull/130026
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] Implement a statusline in LLDB (PR #121860)

2025-03-12 Thread Jonas Devlieghere via lldb-commits


@@ -172,6 +172,14 @@ let Definition = "debugger" in {
 Global,
 DefaultStringValue<"${ansi.normal}">,
 Desc<"When displaying progress in a color-enabled terminal, use the ANSI 
terminal code specified in this format immediately after the progress 
message.">;
+  def ShowStatusline: Property<"show-statusline", "Boolean">,
+Global,
+DefaultTrue,
+Desc<"Whether to show a statusline at the bottom of the terminal.">;
+  def StatuslineFormat: Property<"statusline-format", "FormatEntity">,
+Global,
+
DefaultStringValue<"${ansi.bg.blue}${ansi.fg.black}{${target.file.basename}}{ | 
${line.file.basename}:${line.number}:${line.column}}{ | ${thread.stop-reason}}{ 
| {${progress.count} }${progress.message}}">,
+Desc<"The default statusline format string.">;

JDevlieghere wrote:

I've filed https://github.com/llvm/llvm-project/issues/130997 

https://github.com/llvm/llvm-project/pull/121860
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb][AIX] Host.cpp for AIX (PR #130582)

2025-03-12 Thread Pavel Labath via lldb-commits


@@ -0,0 +1,66 @@
+//===-- source/Host/aix/Host.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 "lldb/Host/Host.h"
+#include "lldb/Utility/ProcessInfo.h"
+#include "lldb/Utility/Status.h"
+#include 
+
+using namespace llvm;
+using namespace lldb;
+using namespace lldb_private;
+
+namespace {
+enum class ProcessState {
+  Unknown,
+  Dead,
+  DiskSleep,
+  Idle,
+  Paging,
+  Parked,
+  Running,
+  Sleeping,
+  TracedOrStopped,
+  Zombie,
+};
+}
+
+namespace lldb_private {
+class ProcessLaunchInfo;
+}
+
+static bool GetStatusInfo(::pid_t Pid, ProcessInstanceInfo &ProcessInfo,
+  ProcessState &State, ::pid_t &TracerPid,
+  ::pid_t &Tgid) {
+  return false;
+}
+
+static void GetProcessArgs(::pid_t pid, ProcessInstanceInfo &process_info) {}
+
+static bool GetProcessAndStatInfo(::pid_t pid,
+  ProcessInstanceInfo &process_info,
+  ProcessState &State, ::pid_t &tracerpid) {
+  return false;
+}

labath wrote:

delete

https://github.com/llvm/llvm-project/pull/130582
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] Make breakpoint stop reason more accurate for function breakpoints (PR #130841)

2025-03-12 Thread via lldb-commits

https://github.com/satyajanga updated 
https://github.com/llvm/llvm-project/pull/130841

>From 55d3b7d0ecf103cc97942c1406926853c35356c1 Mon Sep 17 00:00:00 2001
From: satya janga 
Date: Tue, 11 Mar 2025 13:39:08 -0700
Subject: [PATCH 1/2] Make breakpoint stop reason more accurate

---
 .../test/tools/lldb-dap/lldbdap_testcase.py   |  3 ++-
 lldb/tools/lldb-dap/DAP.cpp   | 26 +++
 lldb/tools/lldb-dap/DAP.h | 12 ++---
 lldb/tools/lldb-dap/JSONUtils.cpp | 12 ++---
 4 files changed, 46 insertions(+), 7 deletions(-)

diff --git 
a/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/lldbdap_testcase.py 
b/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/lldbdap_testcase.py
index 70b04b051e0ec..5faf83ca826a0 100644
--- a/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/lldbdap_testcase.py
+++ b/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/lldbdap_testcase.py
@@ -86,6 +86,7 @@ def verify_breakpoint_hit(self, breakpoint_ids):
 if (
 body["reason"] != "breakpoint"
 and body["reason"] != "instruction breakpoint"
+and body["reason"] != "function breakpoint"
 ):
 continue
 if "description" not in body:
@@ -100,7 +101,7 @@ def verify_breakpoint_hit(self, breakpoint_ids):
 # location.
 description = body["description"]
 for breakpoint_id in breakpoint_ids:
-match_desc = "breakpoint %s." % (breakpoint_id)
+match_desc = "%s %s." % (body["reason"], breakpoint_id)
 if match_desc in description:
 return
 self.assertTrue(False, "breakpoint not hit")
diff --git a/lldb/tools/lldb-dap/DAP.cpp b/lldb/tools/lldb-dap/DAP.cpp
index edd3b31be8ff7..485c420dc59e8 100644
--- a/lldb/tools/lldb-dap/DAP.cpp
+++ b/lldb/tools/lldb-dap/DAP.cpp
@@ -1128,6 +1128,32 @@ DAP::GetInstructionBPFromStopReason(lldb::SBThread 
&thread) {
   return inst_bp;
 }
 
+FunctionBreakpoint *DAP::GetFunctionBPFromStopReason(lldb::SBThread &thread) {
+  const auto num = thread.GetStopReasonDataCount();
+  FunctionBreakpoint *func_bp = nullptr;
+  for (size_t i = 0; i < num; i += 2) {
+// thread.GetStopReasonDataAtIndex(i) will return the bp ID and
+// thread.GetStopReasonDataAtIndex(i+1) will return the location
+// within that breakpoint. We only care about the bp ID so we can
+// see if this is an function breakpoint that is getting hit.
+lldb::break_id_t bp_id = thread.GetStopReasonDataAtIndex(i);
+func_bp = GetFunctionBreakPoint(bp_id);
+// If any breakpoint is not an function breakpoint, then stop and
+// report this as a normal breakpoint
+if (func_bp == nullptr)
+  return nullptr;
+  }
+  return func_bp;
+}
+
+FunctionBreakpoint *DAP::GetFunctionBreakPoint(const lldb::break_id_t bp_id) {
+  for (auto &bp : function_breakpoints) {
+if (bp.second.bp.GetID() == bp_id)
+  return &bp.second;
+  }
+  return nullptr;
+}
+
 lldb::SBValueList *Variables::GetTopLevelScope(int64_t variablesReference) {
   switch (variablesReference) {
   case VARREF_LOCALS:
diff --git a/lldb/tools/lldb-dap/DAP.h b/lldb/tools/lldb-dap/DAP.h
index 3ff1992b61f5b..ea72b41d02516 100644
--- a/lldb/tools/lldb-dap/DAP.h
+++ b/lldb/tools/lldb-dap/DAP.h
@@ -125,21 +125,21 @@ struct Variables {
 
 struct StartDebuggingRequestHandler : public lldb::SBCommandPluginInterface {
   DAP &dap;
-  explicit StartDebuggingRequestHandler(DAP &d) : dap(d) {};
+  explicit StartDebuggingRequestHandler(DAP &d) : dap(d){};
   bool DoExecute(lldb::SBDebugger debugger, char **command,
  lldb::SBCommandReturnObject &result) override;
 };
 
 struct ReplModeRequestHandler : public lldb::SBCommandPluginInterface {
   DAP &dap;
-  explicit ReplModeRequestHandler(DAP &d) : dap(d) {};
+  explicit ReplModeRequestHandler(DAP &d) : dap(d){};
   bool DoExecute(lldb::SBDebugger debugger, char **command,
  lldb::SBCommandReturnObject &result) override;
 };
 
 struct SendEventRequestHandler : public lldb::SBCommandPluginInterface {
   DAP &dap;
-  explicit SendEventRequestHandler(DAP &d) : dap(d) {};
+  explicit SendEventRequestHandler(DAP &d) : dap(d){};
   bool DoExecute(lldb::SBDebugger debugger, char **command,
  lldb::SBCommandReturnObject &result) override;
 };
@@ -383,6 +383,12 @@ struct DAP {
 
   InstructionBreakpoint *GetInstructionBPFromStopReason(lldb::SBThread 
&thread);
 
+  FunctionBreakpoint *GetFunctionBPFromStopReason(lldb::SBThread &thread);
+
+  FunctionBreakpoint *GetFunctionBreakPoint(const lldb::break_id_t bp_id);
+
+  void WaitWorkerThreadsToExit();
+
 private:
   // Send the JSON in "json_str" to the "out" stream. Correctly send the
   // "Content-Length:" field followed by the length, followed by the raw
diff --git a/lldb/tools/lldb-dap/JSONUtils.cpp 
b/lldb/tools

[Lldb-commits] [lldb] f62e168 - [lldb-dap] Validate server mode support prior to invoking lldb-dap. (#130855)

2025-03-12 Thread via lldb-commits

Author: John Harrison
Date: 2025-03-12T10:43:09-07:00
New Revision: f62e168d3f1ddbeff408d8f7ff1dd0fc0cd70029

URL: 
https://github.com/llvm/llvm-project/commit/f62e168d3f1ddbeff408d8f7ff1dd0fc0cd70029
DIFF: 
https://github.com/llvm/llvm-project/commit/f62e168d3f1ddbeff408d8f7ff1dd0fc0cd70029.diff

LOG: [lldb-dap] Validate server mode support prior to invoking lldb-dap. 
(#130855)

This should ensure the extension only uses server mode if the binary
supports the feature, otherwise it will fallback to the existing
behavior.

Fixes #130854

Added: 


Modified: 
lldb/tools/lldb-dap/src-ts/debug-adapter-factory.ts

Removed: 




diff  --git a/lldb/tools/lldb-dap/src-ts/debug-adapter-factory.ts 
b/lldb/tools/lldb-dap/src-ts/debug-adapter-factory.ts
index 1f76fe31b00ad..c2244dcbde8f2 100644
--- a/lldb/tools/lldb-dap/src-ts/debug-adapter-factory.ts
+++ b/lldb/tools/lldb-dap/src-ts/debug-adapter-factory.ts
@@ -93,6 +93,11 @@ async function getDAPExecutable(
   return undefined;
 }
 
+async function isServerModeSupported(exe: string): Promise {
+  const { stdout } = await exec(exe, ['--help']);
+  return /--connection/.test(stdout);
+}
+
 /**
  * This class defines a factory used to find the lldb-dap binary to use
  * depending on the session configuration.
@@ -145,7 +150,7 @@ export class LLDBDapDescriptorFactory
 const dbgArgs = executable?.args ?? [];
 
 const serverMode = config.get('serverMode', false);
-if (serverMode) {
+if (serverMode && await isServerModeSupported(dapPath)) {
   const { host, port } = await this.startServer(dapPath, dbgArgs, 
dbgOptions);
   return new vscode.DebugAdapterServer(port, host);
 }



___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] Support discontinuous functions in another Disasembler overload (PR #130987)

2025-03-12 Thread via lldb-commits

llvmbot wrote:




@llvm/pr-subscribers-lldb

Author: Pavel Labath (labath)


Changes

This overload is taking a StackFrame, so we just need to change how we obtain 
the ranges out of it. A slightly fiddly aspect is the code which tries to 
provide a default dissassembly range for the case where we don't have a real 
one. I believe this case is only relevant for symbol-based stack frames as 
debug info always has size/range for the functions (if it didn't we wouldn't 
even resolve the stack frame to a function), which is why I've split the 
handling of the two cases.

We already have a test case for disassembly of discontinuous functions (in 
test/Shell/Commands/command-disassemble.s), so I'm not creating another one as 
this is just a slightly different entry point into the same code.

---
Full diff: https://github.com/llvm/llvm-project/pull/130987.diff


1 Files Affected:

- (modified) lldb/source/Core/Disassembler.cpp (+18-11) 


``diff
diff --git a/lldb/source/Core/Disassembler.cpp 
b/lldb/source/Core/Disassembler.cpp
index b05be7e1a46d7..9b1d4e9316cb0 100644
--- a/lldb/source/Core/Disassembler.cpp
+++ b/lldb/source/Core/Disassembler.cpp
@@ -552,28 +552,35 @@ void Disassembler::PrintInstructions(Debugger &debugger, 
const ArchSpec &arch,
 
 bool Disassembler::Disassemble(Debugger &debugger, const ArchSpec &arch,
StackFrame &frame, Stream &strm) {
-  AddressRange range;
   SymbolContext sc(
   frame.GetSymbolContext(eSymbolContextFunction | eSymbolContextSymbol));
   if (sc.function) {
-range = sc.function->GetAddressRange();
-  } else if (sc.symbol && sc.symbol->ValueIsAddress()) {
+if (DisassemblerSP disasm_sp = DisassembleRange(
+arch, nullptr, nullptr, nullptr, nullptr, *frame.CalculateTarget(),
+sc.function->GetAddressRanges())) {
+  disasm_sp->PrintInstructions(debugger, arch, frame, false, 0, 0, strm);
+  return true;
+}
+return false;
+  }
+
+  AddressRange range;
+  if (sc.symbol && sc.symbol->ValueIsAddress()) {
 range.GetBaseAddress() = sc.symbol->GetAddressRef();
 range.SetByteSize(sc.symbol->GetByteSize());
   } else {
 range.GetBaseAddress() = frame.GetFrameCodeAddress();
   }
 
-if (range.GetBaseAddress().IsValid() && range.GetByteSize() == 0)
-  range.SetByteSize(DEFAULT_DISASM_BYTE_SIZE);
+  if (range.GetBaseAddress().IsValid() && range.GetByteSize() == 0)
+range.SetByteSize(DEFAULT_DISASM_BYTE_SIZE);
 
-Disassembler::Limit limit = {Disassembler::Limit::Bytes,
- range.GetByteSize()};
-if (limit.value == 0)
-  limit.value = DEFAULT_DISASM_BYTE_SIZE;
+  Disassembler::Limit limit = {Disassembler::Limit::Bytes, 
range.GetByteSize()};
+  if (limit.value == 0)
+limit.value = DEFAULT_DISASM_BYTE_SIZE;
 
-return Disassemble(debugger, arch, nullptr, nullptr, nullptr, nullptr,
-   frame, range.GetBaseAddress(), limit, false, 0, 0, 
strm);
+  return Disassemble(debugger, arch, nullptr, nullptr, nullptr, nullptr, frame,
+ range.GetBaseAddress(), limit, false, 0, 0, strm);
 }
 
 Instruction::Instruction(const Address &address, AddressClass addr_class)

``




https://github.com/llvm/llvm-project/pull/130987
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] Parallelize module loading in POSIX dyld code (PR #130912)

2025-03-12 Thread Tom Yang via lldb-commits

https://github.com/zhyty edited https://github.com/llvm/llvm-project/pull/130912
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb][DWARFASTParserClang] Adjust language type for conflicting Objective-C++ forward declarations (PR #130768)

2025-03-12 Thread Michael Buch via lldb-commits

Michael137 wrote:

> I'm not sure how creating a new type would help, since at that point the c++ 
> type already exists and could be referred to from a bunch of places. I was 
> imagining we would just recognise that we did not find a _**C++**_ definition 
> for this type and then do whatever we do when we don't find a definition 
> (leave the type incomplete? forcefully complete it?...). Later, if we reach 
> the type through an ObjC declaration, we find the ObjC defintion and complete 
> it using that.
> 
> I think the tricky part is what happens with types like your `struct Request 
> { NSString * m_request;};`. If we parse the definition of `Request` from a 
> c++ unit, it will end up referring the the (incomplete) C++ version of 
> `NSString`, which will prevent us from inspecting it, even if we happen to be 
> in objc code. It might be possible to do some switcheroos in the AST 
> importer, similar to how we replace a "forcefully completed" type from one 
> module with an actual definition from another one. Or we could say people get 
> what they deserve (I don't know how much you care about actually supporting 
> this use case vs. simply not crashing).

Good point, yea ideally we do want to support showing the value. Unfortunately 
that's something users have been relying upon. Modelling this similar to how we 
do forceful completion logic hasn't crossed my mind, but now I'm more inclined 
to go with the DWARF search route you suggested

> What would help is if we could short-circuit this code in the (common, on 
> linux) situation where you don't have any ObjC code in your module. I'm not 
> sure if we have a way to do that. (I don't know if we're currently parsing 
> all CU dies, but if we are, we could check if any of them is an ObjC unit). I 
> also think the FindTypes call is unnecessarily heavy (and dangerously 
> recursive) for this. Since, in this world, we want to treat the two types as 
> equivalent, I don't think we need to find all possible definitions of that 
> type. I think it should be sufficient to settle on a canonical definition for 
> the type (per the ODR rule and all), so we can just pick the first one we 
> find. And we can do the search at the DWARF DIE level -- and then also record 
> the definition die in the unique type map, so that we pick the same one when 
> its time to complete the type.

Essentially you're suggesting going back to 
pre-https://github.com/llvm/llvm-project/pull/90663, but only if we have 
ObjC/ObjC++ CUs in the current module? Seems sensible to me. Will also help 
prevent similar issues from creeping up in the future

https://github.com/llvm/llvm-project/pull/130768
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] Parallelize module loading in POSIX dyld code (PR #130912)

2025-03-12 Thread Tom Yang via lldb-commits

https://github.com/zhyty created 
https://github.com/llvm/llvm-project/pull/130912

This patch improves the time performance of LLDB launch on Linux machines, 
particularly for executables with a lot of shared library dependencies (or 
modules). 



The commits have some context on their specific changes as well -- hopefully 
this helps the review.

# Testing

>From fbf25b1cd4f6d527944fb85fc4d2d03498755a05 Mon Sep 17 00:00:00 2001
From: Tom Yang 
Date: Mon, 10 Mar 2025 17:58:17 -0700
Subject: [PATCH 1/3] Add option for enabling/disabling parallel load

Add a setting to gate the new parallel dynamic library loading feature in the 
next diff. I followed the example of 
`lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp` and 
`lldb/source/Plugins/StructuredData/DarwinLog/StructuredDataDarwinLog.cpp` to 
create a scoped setting for the new feature.

NOTE: this setting defaults to FALSE.

Users should be able to enable the new feature as easily as adding a line to 
their .lldbinit file, or manually setting it in their session.

```
(lldb) apropos "POSIX dynamic"
No commands found pertaining to 'POSIX dynamic'. Try 'help' to see a complete 
list of debugger commands.

The following settings variables may relate to 'POSIX dynamic':
  plugin.dynamic-loader.posix-dyld.parallel-module-load -- Enable experimental 
loading of modules in parallel for the POSIX dynamic loader.
(lldb) settings show plugin.dynamic-loader.posix-dyld.parallel-module-load
plugin.dynamic-loader.posix-dyld.parallel-module-load (boolean) = false
(lldb) settings set plugin.dynamic-loader.posix-dyld.parallel-module-load true
(lldb) settings show plugin.dynamic-loader.posix-dyld.parallel-module-load
plugin.dynamic-loader.posix-dyld.parallel-module-load (boolean) = true
```
---
 .../DynamicLoader/POSIX-DYLD/CMakeLists.txt   | 12 +
 .../POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp | 49 ++-
 .../POSIX-DYLD/DynamicLoaderPOSIXDYLD.h   |  2 +
 .../DynamicLoaderPOSIXDYLDProperties.td   |  8 +++
 4 files changed, 70 insertions(+), 1 deletion(-)
 create mode 100644 
lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLDProperties.td

diff --git a/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/CMakeLists.txt 
b/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/CMakeLists.txt
index c1e00b2dd444f..532bfb20ea0f1 100644
--- a/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/CMakeLists.txt
+++ b/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/CMakeLists.txt
@@ -1,3 +1,11 @@
+lldb_tablegen(DynamicLoaderPOSIXDYLDProperties.inc -gen-lldb-property-defs
+  SOURCE DynamicLoaderPOSIXDYLDProperties.td
+  TARGET LLDBPluginDynamicLoaderPOSIXDYLDPropertiesGen)
+
+lldb_tablegen(DynamicLoaderPOSIXDYLDPropertiesEnum.inc 
-gen-lldb-property-enum-defs
+  SOURCE DynamicLoaderPOSIXDYLDProperties.td
+  TARGET LLDBPluginDynamicLoaderPOSIXDYLDPropertiesEnumGen)
+
 add_lldb_library(lldbPluginDynamicLoaderPosixDYLD PLUGIN
   DYLDRendezvous.cpp
   DynamicLoaderPOSIXDYLD.cpp
@@ -13,3 +21,7 @@ add_lldb_library(lldbPluginDynamicLoaderPosixDYLD PLUGIN
   LINK_COMPONENTS
 Support
   )
+
+add_dependencies(lldbPluginDynamicLoaderPosixDYLD
+  LLDBPluginDynamicLoaderPOSIXDYLDPropertiesGen
+  LLDBPluginDynamicLoaderPOSIXDYLDPropertiesEnumGen)
diff --git 
a/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp 
b/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp
index 53ba11ac21bd3..c89d16649922d 100644
--- a/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp
+++ b/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp
@@ -34,9 +34,56 @@ using namespace lldb_private;
 
 LLDB_PLUGIN_DEFINE_ADV(DynamicLoaderPOSIXDYLD, DynamicLoaderPosixDYLD)
 
+namespace {
+
+#define LLDB_PROPERTIES_dynamicloaderposixdyld
+#include "DynamicLoaderPOSIXDYLDProperties.inc"
+
+enum {
+#define LLDB_PROPERTIES_dynamicloaderposixdyld
+#include "DynamicLoaderPOSIXDYLDPropertiesEnum.inc"
+};
+
+class PluginProperties : public Properties {
+public:
+  static llvm::StringRef GetSettingName() {
+return DynamicLoaderPOSIXDYLD::GetPluginNameStatic();
+  }
+
+  PluginProperties() : Properties() {
+m_collection_sp = 
std::make_shared(GetSettingName());
+m_collection_sp->Initialize(g_dynamicloaderposixdyld_properties);
+  }
+
+  ~PluginProperties() override = default;
+
+  bool GetParallelModuleLoad() const {
+const uint32_t idx = ePropertyParallelModuleLoad;
+return GetPropertyAtIndexAs(idx, true);
+  }
+};
+
+} // namespace
+
+static PluginProperties &GetGlobalPluginProperties() {
+  static PluginProperties g_settings;
+  return g_settings;
+}
+
 void DynamicLoaderPOSIXDYLD::Initialize() {
   PluginManager::RegisterPlugin(GetPluginNameStatic(),
-GetPluginDescriptionStatic(), CreateInstance);
+GetPluginDescriptionStatic(), CreateInstance,
+&DebuggerInitialize);
+}
+
+void DynamicLoaderPOSIXDYLD::Debugg

[Lldb-commits] [lldb] Parallelize module loading in POSIX dyld code (PR #130912)

2025-03-12 Thread Tom Yang via lldb-commits

https://github.com/zhyty updated 
https://github.com/llvm/llvm-project/pull/130912

>From fbf25b1cd4f6d527944fb85fc4d2d03498755a05 Mon Sep 17 00:00:00 2001
From: Tom Yang 
Date: Mon, 10 Mar 2025 17:58:17 -0700
Subject: [PATCH 1/3] Add option for enabling/disabling parallel load

Add a setting to gate the new parallel dynamic library loading feature in the 
next diff. I followed the example of 
`lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp` and 
`lldb/source/Plugins/StructuredData/DarwinLog/StructuredDataDarwinLog.cpp` to 
create a scoped setting for the new feature.

NOTE: this setting defaults to FALSE.

Users should be able to enable the new feature as easily as adding a line to 
their .lldbinit file, or manually setting it in their session.

```
(lldb) apropos "POSIX dynamic"
No commands found pertaining to 'POSIX dynamic'. Try 'help' to see a complete 
list of debugger commands.

The following settings variables may relate to 'POSIX dynamic':
  plugin.dynamic-loader.posix-dyld.parallel-module-load -- Enable experimental 
loading of modules in parallel for the POSIX dynamic loader.
(lldb) settings show plugin.dynamic-loader.posix-dyld.parallel-module-load
plugin.dynamic-loader.posix-dyld.parallel-module-load (boolean) = false
(lldb) settings set plugin.dynamic-loader.posix-dyld.parallel-module-load true
(lldb) settings show plugin.dynamic-loader.posix-dyld.parallel-module-load
plugin.dynamic-loader.posix-dyld.parallel-module-load (boolean) = true
```
---
 .../DynamicLoader/POSIX-DYLD/CMakeLists.txt   | 12 +
 .../POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp | 49 ++-
 .../POSIX-DYLD/DynamicLoaderPOSIXDYLD.h   |  2 +
 .../DynamicLoaderPOSIXDYLDProperties.td   |  8 +++
 4 files changed, 70 insertions(+), 1 deletion(-)
 create mode 100644 
lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLDProperties.td

diff --git a/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/CMakeLists.txt 
b/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/CMakeLists.txt
index c1e00b2dd444f..532bfb20ea0f1 100644
--- a/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/CMakeLists.txt
+++ b/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/CMakeLists.txt
@@ -1,3 +1,11 @@
+lldb_tablegen(DynamicLoaderPOSIXDYLDProperties.inc -gen-lldb-property-defs
+  SOURCE DynamicLoaderPOSIXDYLDProperties.td
+  TARGET LLDBPluginDynamicLoaderPOSIXDYLDPropertiesGen)
+
+lldb_tablegen(DynamicLoaderPOSIXDYLDPropertiesEnum.inc 
-gen-lldb-property-enum-defs
+  SOURCE DynamicLoaderPOSIXDYLDProperties.td
+  TARGET LLDBPluginDynamicLoaderPOSIXDYLDPropertiesEnumGen)
+
 add_lldb_library(lldbPluginDynamicLoaderPosixDYLD PLUGIN
   DYLDRendezvous.cpp
   DynamicLoaderPOSIXDYLD.cpp
@@ -13,3 +21,7 @@ add_lldb_library(lldbPluginDynamicLoaderPosixDYLD PLUGIN
   LINK_COMPONENTS
 Support
   )
+
+add_dependencies(lldbPluginDynamicLoaderPosixDYLD
+  LLDBPluginDynamicLoaderPOSIXDYLDPropertiesGen
+  LLDBPluginDynamicLoaderPOSIXDYLDPropertiesEnumGen)
diff --git 
a/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp 
b/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp
index 53ba11ac21bd3..c89d16649922d 100644
--- a/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp
+++ b/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp
@@ -34,9 +34,56 @@ using namespace lldb_private;
 
 LLDB_PLUGIN_DEFINE_ADV(DynamicLoaderPOSIXDYLD, DynamicLoaderPosixDYLD)
 
+namespace {
+
+#define LLDB_PROPERTIES_dynamicloaderposixdyld
+#include "DynamicLoaderPOSIXDYLDProperties.inc"
+
+enum {
+#define LLDB_PROPERTIES_dynamicloaderposixdyld
+#include "DynamicLoaderPOSIXDYLDPropertiesEnum.inc"
+};
+
+class PluginProperties : public Properties {
+public:
+  static llvm::StringRef GetSettingName() {
+return DynamicLoaderPOSIXDYLD::GetPluginNameStatic();
+  }
+
+  PluginProperties() : Properties() {
+m_collection_sp = 
std::make_shared(GetSettingName());
+m_collection_sp->Initialize(g_dynamicloaderposixdyld_properties);
+  }
+
+  ~PluginProperties() override = default;
+
+  bool GetParallelModuleLoad() const {
+const uint32_t idx = ePropertyParallelModuleLoad;
+return GetPropertyAtIndexAs(idx, true);
+  }
+};
+
+} // namespace
+
+static PluginProperties &GetGlobalPluginProperties() {
+  static PluginProperties g_settings;
+  return g_settings;
+}
+
 void DynamicLoaderPOSIXDYLD::Initialize() {
   PluginManager::RegisterPlugin(GetPluginNameStatic(),
-GetPluginDescriptionStatic(), CreateInstance);
+GetPluginDescriptionStatic(), CreateInstance,
+&DebuggerInitialize);
+}
+
+void DynamicLoaderPOSIXDYLD::DebuggerInitialize(Debugger &debugger) {
+  if (!PluginManager::GetSettingForDynamicLoaderPlugin(
+  debugger, PluginProperties::GetSettingName())) {
+const bool is_global_setting = true;
+PluginManager::CreateSettingForDynamicLoaderPlugin(
+debugger, GetGlobal

[Lldb-commits] [lldb] Parallelize module loading in POSIX dyld code (PR #130912)

2025-03-12 Thread Tom Yang via lldb-commits

https://github.com/zhyty edited https://github.com/llvm/llvm-project/pull/130912
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb][DWARFASTParserClang] Adjust language type for conflicting Objective-C++ forward declarations (PR #130768)

2025-03-12 Thread Pavel Labath via lldb-commits

labath wrote:

> > So what would happen if we treated `class NSString` and `@class NSString` 
> > as two distinct types? I guess that would be a problem because then we 
> > could end up with duplicate versions of everything that depends on that 
> > type (two `void foo(NSString)`s, depending on whether it's parsed in a C++ 
> > or ObjC CU)? (I'm guessing the reason that it uses this hack is because it 
> > wants to refer to NSString from generic code.)
> 
> I'll try giving this a shot. If we can pull this off that'd be great. We'll 
> probably need to modify the `CompleteRecordType` logic to realize that the 
> definition DIE we found for a forward declaration is actually objective-c, 
> and if so, create a new type from it. In theory I'd prefer this much more 
> over what I proposed. Though can't say how feasible it is to do yet, let me 
> try

I'm not sure how creating a new type would help, since at that point the c++ 
type already exists and could be referred to from a bunch of places. I was 
imagining we would just recognise that we did not find a ***C++*** definition 
for this type and then do whatever we do when we don't find a definition (leave 
the type incomplete? forcefully complete it?...). Later, if we reach the type 
through an ObjC declaration, we find the ObjC defintion and complete it using 
that.

I think the tricky part is what happens with types like your `struct Request { 
NSString * m_request;};`. If we parse the definition of `Request` from a c++ 
unit, it will end up referring the the (incomplete) C++ version of `NSString`, 
which will prevent us from inspecting it, even if we happen to be in objc code. 
It might be possible to do some switcheroos in the AST importer, similar to how 
we replace a "forcefully completed" type from one module with an actual 
definition from another one. Or we could say people get what they deserve (I 
don't know how much you care about actually supporting this use case vs. simply 
not crashing).

> 
> > Since this makes lldb to do type searching more aggressively, I want to get 
> > a sense of performance impact on simplified template names from this PR
> 
> If we were to go down the route I proposed, I would only do a `FindTypes` 
> call for DIEs at the root namespace. And since this is only searching within 
> the current module/library, not across all modules in the target, I suspect 
> the performance cost wouldn't be an issue. But I'll try to get some numbers 
> (if the approach Pavel suggested doesn't work out)

For our use cases, ~all of the code is in a single module anyway, so not 
searching in other modules doesn't help much. Limiting it to the global 
namespace definitely helps, but due to how the accelerator tables work, it 
still means that you have to iterate through all DIEs with the given name 
anywhere in the program, just to find out whether they are at the top level or 
not. I don't know what how much of a performance hit would that be in practice.

What would help is if we could short-circuit this code in the (common, on 
linux) situation where you don't have any ObjC code in your module. I'm not 
sure if we have a way to do that. (I don't know if we're currently parsing all 
CU dies, but if we are, we could check if any of them is an ObjC unit)

I also think the FindTypes call is unnecessarily heavy (and dangerously 
recursive) for this. Since, in this world, we *want* to treat the two types as 
equivalent, I don't think we need to find all possible definitions of that 
type. I think it should be sufficient to settle on *a* canonical definition for 
the type (per the ODR rule and all), so we can just pick the first one we find. 
And we can do the search at the DWARF DIE level -- and then also record the 
definition die in the unique type map, so that we pick the same one when its 
time to complete the type.

https://github.com/llvm/llvm-project/pull/130768
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb-dap] Updating RequestHandler to encode/decode arguments and response. (PR #130090)

2025-03-12 Thread John Harrison via lldb-commits

https://github.com/ashgti updated 
https://github.com/llvm/llvm-project/pull/130090

>From f26c9a79ca234bee77ec1a9694bf8be2d0e3745c Mon Sep 17 00:00:00 2001
From: John Harrison 
Date: Thu, 6 Mar 2025 13:21:10 +0100
Subject: [PATCH 1/2] [lldb-dap] Updating RequestHandler to encode/decode
 arguments and response.

This is a work in progress refactor to add explicit types instead of
generic 'llvm::json::Value' types to the DAP protocol.

This updates RequestHandler to have take the type of the arguments and
response body for serialization for requests.

The 'source' request is updated to show how the new flow works.
---
 lldb/tools/lldb-dap/DAP.cpp   |  57 +++--
 lldb/tools/lldb-dap/DAP.h |   4 +-
 lldb/tools/lldb-dap/DAPForward.h  |   2 +
 .../tools/lldb-dap/Handler/RequestHandler.cpp |  11 +-
 lldb/tools/lldb-dap/Handler/RequestHandler.h  | 214 --
 .../lldb-dap/Handler/SourceRequestHandler.cpp | 104 ++---
 lldb/tools/lldb-dap/Protocol.cpp  |  44 
 lldb/tools/lldb-dap/Protocol.h| 131 +++
 8 files changed, 381 insertions(+), 186 deletions(-)

diff --git a/lldb/tools/lldb-dap/DAP.cpp b/lldb/tools/lldb-dap/DAP.cpp
index 4080e2c211035..9d42af2d7091f 100644
--- a/lldb/tools/lldb-dap/DAP.cpp
+++ b/lldb/tools/lldb-dap/DAP.cpp
@@ -8,10 +8,12 @@
 
 #include "DAP.h"
 #include "DAPLog.h"
+#include "Handler/RequestHandler.h"
 #include "Handler/ResponseHandler.h"
 #include "JSONUtils.h"
 #include "LLDBUtils.h"
 #include "OutputRedirector.h"
+#include "Protocol.h"
 #include "Transport.h"
 #include "lldb/API/SBBreakpoint.h"
 #include "lldb/API/SBCommandInterpreter.h"
@@ -25,6 +27,7 @@
 #include "lldb/lldb-defines.h"
 #include "lldb/lldb-enumerations.h"
 #include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/ScopeExit.h"
 #include "llvm/ADT/StringExtras.h"
 #include "llvm/ADT/StringRef.h"
@@ -41,6 +44,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 
 #if defined(_WIN32)
@@ -663,31 +667,23 @@ void DAP::SetTarget(const lldb::SBTarget target) {
 }
 
 bool DAP::HandleObject(const protocol::Message &M) {
-  // FIXME: Directly handle `Message` instead of serializing to JSON.
-  llvm::json::Value v = toJSON(M);
-  llvm::json::Object object = *v.getAsObject();
-  const auto packet_type = GetString(object, "type");
-  if (packet_type == "request") {
-const auto command = GetString(object, "command");
-
-auto new_handler_pos = request_handlers.find(command);
+  if (const auto *req = std::get_if(&M)) {
+auto new_handler_pos = request_handlers.find(req->command);
 if (new_handler_pos != request_handlers.end()) {
-  (*new_handler_pos->second)(object);
+  (*new_handler_pos->second)(*req);
   return true; // Success
 }
 
 DAP_LOG(log, "({0}) error: unhandled command '{1}'",
-transport.GetClientName(), command);
+transport.GetClientName(), req->command);
 return false; // Fail
   }
 
-  if (packet_type == "response") {
-auto id = GetInteger(object, "request_seq").value_or(0);
-
+  if (const auto *resp = std::get_if(&M)) {
 std::unique_ptr response_handler;
 {
   std::lock_guard locker(call_mutex);
-  auto inflight = inflight_reverse_requests.find(id);
+  auto inflight = inflight_reverse_requests.find(resp->request_seq);
   if (inflight != inflight_reverse_requests.end()) {
 response_handler = std::move(inflight->second);
 inflight_reverse_requests.erase(inflight);
@@ -695,19 +691,31 @@ bool DAP::HandleObject(const protocol::Message &M) {
 }
 
 if (!response_handler)
-  response_handler = std::make_unique("", id);
+  response_handler =
+  std::make_unique("", resp->request_seq);
 
 // Result should be given, use null if not.
-if (GetBoolean(object, "success").value_or(false)) {
-  llvm::json::Value Result = nullptr;
-  if (auto *B = object.get("body"))
-Result = std::move(*B);
-  (*response_handler)(Result);
+if (resp->success) {
+  (*response_handler)(resp->rawBody);
 } else {
-  llvm::StringRef message = GetString(object, "message");
-  if (message.empty()) {
-message = "Unknown error, response failed";
+  std::string message = "Unknown error, response failed";
+  if (resp->message) {
+message = std::visit(
+llvm::makeVisitor(
+[](const std::string &message) -> std::string {
+  return message;
+},
+[](const protocol::Response::Message &message) -> std::string {
+  switch (message) {
+  case protocol::Response::Message::cancelled:
+return "cancelled";
+  case protocol::Response::Message::notStopped:
+return "notStopped";
+  }
+}),
+*resp->message);
   }
+
   (*response_handler)(l

[Lldb-commits] [lldb] [lldb-dap] Updating RequestHandler to encode/decode arguments and response. (PR #130090)

2025-03-12 Thread John Harrison via lldb-commits


@@ -240,6 +240,137 @@ using Message = std::variant;
 bool fromJSON(const llvm::json::Value &, Message &, llvm::json::Path);
 llvm::json::Value toJSON(const Message &);
 
+// MARK: Types
+
+// "Source": {
+//   "type": "object",
+//   "description": "A `Source` is a descriptor for source code.\nIt is 
returned
+//   from the debug adapter as part of a `StackFrame` and it is used by clients
+//   when specifying breakpoints.", "properties": {
+// "name": {
+//   "type": "string",
+//   "description": "The short name of the source. Every source returned
+//   from the debug adapter has a name.\nWhen sending a source to the debug
+//   adapter this name is optional."
+// },
+// "path": {
+//   "type": "string",
+//   "description": "The path of the source to be shown in the UI.\nIt is
+//   only used to locate and load the content of the source if no
+//   `sourceReference` is specified (or its value is 0)."
+// },
+// "sourceReference": {
+//   "type": "integer",
+//   "description": "If the value > 0 the contents of the source must be
+//   retrieved through the `source` request (even if a path is
+//   specified).\nSince a `sourceReference` is only valid for a session, it
+//   can not be used to persist a source.\nThe value should be less than or
+//   equal to 2147483647 (2^31-1)."
+// },
+// "presentationHint": {
+//   "type": "string",
+//   "description": "A hint for how to present the source in the UI.\nA
+//   value of `deemphasize` can be used to indicate that the source is not
+//   available or that it is skipped on stepping.", "enum": [ "normal",
+//   "emphasize", "deemphasize" ]
+// },
+// "origin": {
+//   "type": "string",
+//   "description": "The origin of this source. For example, 'internal
+//   module', 'inlined content from source map', etc."
+// },
+// "sources": {
+//   "type": "array",
+//   "items": {
+// "$ref": "#/definitions/Source"
+//   },
+//   "description": "A list of sources that are related to this source.
+//   These may be the source that generated this source."
+// },
+// "adapterData": {
+//   "type": [ "array", "boolean", "integer", "null", "number", "object",
+//   "string" ], "description": "Additional data that a debug adapter might
+//   want to loop through the client.\nThe client should leave the data
+//   intact and persist it across sessions. The client should not interpret
+//   the data."
+// },
+// "checksums": {
+//   "type": "array",
+//   "items": {
+// "$ref": "#/definitions/Checksum"
+//   },
+//   "description": "The checksums associated with this file."
+// }
+//   }
+// },
+struct Source {
+  enum class PresentationHint { normal, emphasize, deemphasize };
+
+  std::optional name;
+  std::optional path;
+  std::optional sourceReference;
+  std::optional presentationHint;
+
+  // unsupproted keys origin, sources, adapterData, checksums
+};
+bool fromJSON(const llvm::json::Value &, Source &, llvm::json::Path);
+llvm::json::Value toJSON(const Source &);

ashgti wrote:

Source is used in both requests and responses, so having both will be useful. 
Only the fromJSON is used today.

https://github.com/llvm/llvm-project/pull/130090
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb-dap] Updating RequestHandler to encode/decode arguments and response. (PR #130090)

2025-03-12 Thread John Harrison via lldb-commits


@@ -240,6 +240,137 @@ using Message = std::variant;
 bool fromJSON(const llvm::json::Value &, Message &, llvm::json::Path);
 llvm::json::Value toJSON(const Message &);
 
+// MARK: Types
+
+// "Source": {
+//   "type": "object",
+//   "description": "A `Source` is a descriptor for source code.\nIt is 
returned
+//   from the debug adapter as part of a `StackFrame` and it is used by clients
+//   when specifying breakpoints.", "properties": {
+// "name": {
+//   "type": "string",
+//   "description": "The short name of the source. Every source returned
+//   from the debug adapter has a name.\nWhen sending a source to the debug
+//   adapter this name is optional."
+// },
+// "path": {
+//   "type": "string",
+//   "description": "The path of the source to be shown in the UI.\nIt is
+//   only used to locate and load the content of the source if no
+//   `sourceReference` is specified (or its value is 0)."
+// },
+// "sourceReference": {
+//   "type": "integer",
+//   "description": "If the value > 0 the contents of the source must be
+//   retrieved through the `source` request (even if a path is
+//   specified).\nSince a `sourceReference` is only valid for a session, it
+//   can not be used to persist a source.\nThe value should be less than or
+//   equal to 2147483647 (2^31-1)."
+// },
+// "presentationHint": {
+//   "type": "string",
+//   "description": "A hint for how to present the source in the UI.\nA
+//   value of `deemphasize` can be used to indicate that the source is not
+//   available or that it is skipped on stepping.", "enum": [ "normal",
+//   "emphasize", "deemphasize" ]
+// },
+// "origin": {
+//   "type": "string",
+//   "description": "The origin of this source. For example, 'internal
+//   module', 'inlined content from source map', etc."
+// },
+// "sources": {
+//   "type": "array",
+//   "items": {
+// "$ref": "#/definitions/Source"
+//   },
+//   "description": "A list of sources that are related to this source.
+//   These may be the source that generated this source."
+// },
+// "adapterData": {
+//   "type": [ "array", "boolean", "integer", "null", "number", "object",
+//   "string" ], "description": "Additional data that a debug adapter might
+//   want to loop through the client.\nThe client should leave the data
+//   intact and persist it across sessions. The client should not interpret
+//   the data."
+// },
+// "checksums": {
+//   "type": "array",
+//   "items": {
+// "$ref": "#/definitions/Checksum"
+//   },
+//   "description": "The checksums associated with this file."
+// }
+//   }
+// },
+struct Source {
+  enum class PresentationHint { normal, emphasize, deemphasize };
+
+  std::optional name;
+  std::optional path;
+  std::optional sourceReference;
+  std::optional presentationHint;
+
+  // unsupproted keys origin, sources, adapterData, checksums
+};
+bool fromJSON(const llvm::json::Value &, Source &, llvm::json::Path);
+llvm::json::Value toJSON(const Source &);
+
+// MARK: Requests
+
+// "SourceArguments": {
+//   "type": "object",
+//   "description": "Arguments for `source` request.",
+//   "properties": {
+// "source": {
+//   "$ref": "#/definitions/Source",
+//   "description": "Specifies the source content to load. Either
+//   `source.path` or `source.sourceReference` must be specified."
+// },
+// "sourceReference": {
+//   "type": "integer",
+//   "description": "The reference to the source. This is the same as
+//   `source.sourceReference`.\nThis is provided for backward compatibility
+//   since old clients do not understand the `source` attribute."
+// }
+//   },
+//   "required": [ "sourceReference" ]
+// },
+struct SourceArguments {
+  std::optional source;
+  int64_t sourceReference;
+};
+bool fromJSON(const llvm::json::Value &, SourceArguments &, llvm::json::Path);
+
+// "SourceResponse": {
+//   "allOf": [ { "$ref": "#/definitions/Response" }, {
+// "type": "object",
+// "description": "Response to `source` request.",
+// "properties": {
+//   "body": {
+// "type": "object",
+// "properties": {
+//   "content": {
+// "type": "string",
+// "description": "Content of the source reference."
+//   },
+//   "mimeType": {
+// "type": "string",
+// "description": "Content type (MIME type) of the source."
+//   }
+// },
+// "required": [ "content" ]
+//   }
+// },
+// "required": [ "body" ]
+//   }]
+// },
+struct SourceResponseBody {
+  std::string content;
+  std::optional mimeType;
+};

ashgti wrote:

Removed the json schema and instead moved comments to the individual c++ reprs.

https://github.com/llvm/llvm-proje

[Lldb-commits] [lldb] [lldb] Implement ANSI & Unicode aware string stripping & padding (PR #130878)

2025-03-12 Thread Jonas Devlieghere via lldb-commits

https://github.com/JDevlieghere closed 
https://github.com/llvm/llvm-project/pull/130878
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb-dap] Updating RequestHandler to encode/decode arguments and response. (PR #130090)

2025-03-12 Thread John Harrison via lldb-commits


@@ -240,6 +240,137 @@ using Message = std::variant;
 bool fromJSON(const llvm::json::Value &, Message &, llvm::json::Path);
 llvm::json::Value toJSON(const Message &);
 
+// MARK: Types
+
+// "Source": {
+//   "type": "object",
+//   "description": "A `Source` is a descriptor for source code.\nIt is 
returned
+//   from the debug adapter as part of a `StackFrame` and it is used by clients
+//   when specifying breakpoints.", "properties": {
+// "name": {
+//   "type": "string",
+//   "description": "The short name of the source. Every source returned
+//   from the debug adapter has a name.\nWhen sending a source to the debug
+//   adapter this name is optional."
+// },
+// "path": {
+//   "type": "string",
+//   "description": "The path of the source to be shown in the UI.\nIt is
+//   only used to locate and load the content of the source if no
+//   `sourceReference` is specified (or its value is 0)."
+// },
+// "sourceReference": {
+//   "type": "integer",
+//   "description": "If the value > 0 the contents of the source must be
+//   retrieved through the `source` request (even if a path is
+//   specified).\nSince a `sourceReference` is only valid for a session, it
+//   can not be used to persist a source.\nThe value should be less than or
+//   equal to 2147483647 (2^31-1)."
+// },
+// "presentationHint": {
+//   "type": "string",
+//   "description": "A hint for how to present the source in the UI.\nA
+//   value of `deemphasize` can be used to indicate that the source is not
+//   available or that it is skipped on stepping.", "enum": [ "normal",
+//   "emphasize", "deemphasize" ]
+// },
+// "origin": {
+//   "type": "string",
+//   "description": "The origin of this source. For example, 'internal
+//   module', 'inlined content from source map', etc."
+// },
+// "sources": {
+//   "type": "array",
+//   "items": {
+// "$ref": "#/definitions/Source"
+//   },
+//   "description": "A list of sources that are related to this source.
+//   These may be the source that generated this source."
+// },
+// "adapterData": {
+//   "type": [ "array", "boolean", "integer", "null", "number", "object",
+//   "string" ], "description": "Additional data that a debug adapter might
+//   want to loop through the client.\nThe client should leave the data
+//   intact and persist it across sessions. The client should not interpret
+//   the data."
+// },
+// "checksums": {
+//   "type": "array",
+//   "items": {
+// "$ref": "#/definitions/Checksum"
+//   },
+//   "description": "The checksums associated with this file."
+// }
+//   }
+// },
+struct Source {
+  enum class PresentationHint { normal, emphasize, deemphasize };
+
+  std::optional name;
+  std::optional path;
+  std::optional sourceReference;
+  std::optional presentationHint;
+
+  // unsupproted keys origin, sources, adapterData, checksums

ashgti wrote:

Done.

https://github.com/llvm/llvm-project/pull/130090
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb-dap] Updating RequestHandler to encode/decode arguments and response. (PR #130090)

2025-03-12 Thread John Harrison via lldb-commits


@@ -57,235 +68,288 @@ class RequestHandler {
   DAP &dap;
 };
 
-class AttachRequestHandler : public RequestHandler {
-public:
-  using RequestHandler::RequestHandler;
+/// Base class for handling DAP requests. Handlers should declare their
+/// arguments and response body types like:
+///
+/// class MyRequestHandler : public RequestHandler {
+///   
+/// };
+template 
+class RequestHandler : public BaseRequestHandler {
+  using BaseRequestHandler::BaseRequestHandler;
+
+  void operator()(const llvm::json::Object &request) const override {
+/* no-op, the other overload handles json coding. */
+  }
+
+  void operator()(const protocol::Request &request) const override {
+protocol::Response response;
+response.request_seq = request.seq;
+response.command = request.command;
+Args arguments;
+llvm::json::Path::Root root;
+if (request.rawArguments &&
+!fromJSON(request.rawArguments, arguments, root)) {

ashgti wrote:

Technically, they're optional, although all the existing request's require an 
argument today.

https://github.com/llvm/llvm-project/pull/130090
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb-dap] Updating RequestHandler to encode/decode arguments and response. (PR #130090)

2025-03-12 Thread John Harrison via lldb-commits

https://github.com/ashgti updated 
https://github.com/llvm/llvm-project/pull/130090

>From f26c9a79ca234bee77ec1a9694bf8be2d0e3745c Mon Sep 17 00:00:00 2001
From: John Harrison 
Date: Thu, 6 Mar 2025 13:21:10 +0100
Subject: [PATCH 1/3] [lldb-dap] Updating RequestHandler to encode/decode
 arguments and response.

This is a work in progress refactor to add explicit types instead of
generic 'llvm::json::Value' types to the DAP protocol.

This updates RequestHandler to have take the type of the arguments and
response body for serialization for requests.

The 'source' request is updated to show how the new flow works.
---
 lldb/tools/lldb-dap/DAP.cpp   |  57 +++--
 lldb/tools/lldb-dap/DAP.h |   4 +-
 lldb/tools/lldb-dap/DAPForward.h  |   2 +
 .../tools/lldb-dap/Handler/RequestHandler.cpp |  11 +-
 lldb/tools/lldb-dap/Handler/RequestHandler.h  | 214 --
 .../lldb-dap/Handler/SourceRequestHandler.cpp | 104 ++---
 lldb/tools/lldb-dap/Protocol.cpp  |  44 
 lldb/tools/lldb-dap/Protocol.h| 131 +++
 8 files changed, 381 insertions(+), 186 deletions(-)

diff --git a/lldb/tools/lldb-dap/DAP.cpp b/lldb/tools/lldb-dap/DAP.cpp
index 4080e2c211035..9d42af2d7091f 100644
--- a/lldb/tools/lldb-dap/DAP.cpp
+++ b/lldb/tools/lldb-dap/DAP.cpp
@@ -8,10 +8,12 @@
 
 #include "DAP.h"
 #include "DAPLog.h"
+#include "Handler/RequestHandler.h"
 #include "Handler/ResponseHandler.h"
 #include "JSONUtils.h"
 #include "LLDBUtils.h"
 #include "OutputRedirector.h"
+#include "Protocol.h"
 #include "Transport.h"
 #include "lldb/API/SBBreakpoint.h"
 #include "lldb/API/SBCommandInterpreter.h"
@@ -25,6 +27,7 @@
 #include "lldb/lldb-defines.h"
 #include "lldb/lldb-enumerations.h"
 #include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/ScopeExit.h"
 #include "llvm/ADT/StringExtras.h"
 #include "llvm/ADT/StringRef.h"
@@ -41,6 +44,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 
 #if defined(_WIN32)
@@ -663,31 +667,23 @@ void DAP::SetTarget(const lldb::SBTarget target) {
 }
 
 bool DAP::HandleObject(const protocol::Message &M) {
-  // FIXME: Directly handle `Message` instead of serializing to JSON.
-  llvm::json::Value v = toJSON(M);
-  llvm::json::Object object = *v.getAsObject();
-  const auto packet_type = GetString(object, "type");
-  if (packet_type == "request") {
-const auto command = GetString(object, "command");
-
-auto new_handler_pos = request_handlers.find(command);
+  if (const auto *req = std::get_if(&M)) {
+auto new_handler_pos = request_handlers.find(req->command);
 if (new_handler_pos != request_handlers.end()) {
-  (*new_handler_pos->second)(object);
+  (*new_handler_pos->second)(*req);
   return true; // Success
 }
 
 DAP_LOG(log, "({0}) error: unhandled command '{1}'",
-transport.GetClientName(), command);
+transport.GetClientName(), req->command);
 return false; // Fail
   }
 
-  if (packet_type == "response") {
-auto id = GetInteger(object, "request_seq").value_or(0);
-
+  if (const auto *resp = std::get_if(&M)) {
 std::unique_ptr response_handler;
 {
   std::lock_guard locker(call_mutex);
-  auto inflight = inflight_reverse_requests.find(id);
+  auto inflight = inflight_reverse_requests.find(resp->request_seq);
   if (inflight != inflight_reverse_requests.end()) {
 response_handler = std::move(inflight->second);
 inflight_reverse_requests.erase(inflight);
@@ -695,19 +691,31 @@ bool DAP::HandleObject(const protocol::Message &M) {
 }
 
 if (!response_handler)
-  response_handler = std::make_unique("", id);
+  response_handler =
+  std::make_unique("", resp->request_seq);
 
 // Result should be given, use null if not.
-if (GetBoolean(object, "success").value_or(false)) {
-  llvm::json::Value Result = nullptr;
-  if (auto *B = object.get("body"))
-Result = std::move(*B);
-  (*response_handler)(Result);
+if (resp->success) {
+  (*response_handler)(resp->rawBody);
 } else {
-  llvm::StringRef message = GetString(object, "message");
-  if (message.empty()) {
-message = "Unknown error, response failed";
+  std::string message = "Unknown error, response failed";
+  if (resp->message) {
+message = std::visit(
+llvm::makeVisitor(
+[](const std::string &message) -> std::string {
+  return message;
+},
+[](const protocol::Response::Message &message) -> std::string {
+  switch (message) {
+  case protocol::Response::Message::cancelled:
+return "cancelled";
+  case protocol::Response::Message::notStopped:
+return "notStopped";
+  }
+}),
+*resp->message);
   }
+
   (*response_handler)(l

[Lldb-commits] [lldb] [lldb-dap] Updating RequestHandler to encode/decode arguments and response. (PR #130090)

2025-03-12 Thread via lldb-commits

llvmbot wrote:




@llvm/pr-subscribers-lldb

Author: John Harrison (ashgti)


Changes

This is a work in progress refactor to add explicit types instead of
generic 'llvm::json::Value' types to the DAP protocol.

This updates RequestHandler to have take the type of the arguments and
response body for serialization for requests.

The 'source' request is updated to show how the new flow works.

This is built on top of #130026

---

Patch is 43.12 KiB, truncated to 20.00 KiB below, full version: 
https://github.com/llvm/llvm-project/pull/130090.diff


8 Files Affected:

- (modified) lldb/tools/lldb-dap/DAP.cpp (+34-23) 
- (modified) lldb/tools/lldb-dap/DAP.h (+1-3) 
- (modified) lldb/tools/lldb-dap/DAPForward.h (+2) 
- (modified) lldb/tools/lldb-dap/Handler/RequestHandler.cpp (+6-5) 
- (modified) lldb/tools/lldb-dap/Handler/RequestHandler.h (+139-75) 
- (modified) lldb/tools/lldb-dap/Handler/SourceRequestHandler.cpp (+26-97) 
- (modified) lldb/tools/lldb-dap/Protocol.cpp (+44) 
- (modified) lldb/tools/lldb-dap/Protocol.h (+117-163) 


``diff
diff --git a/lldb/tools/lldb-dap/DAP.cpp b/lldb/tools/lldb-dap/DAP.cpp
index 4080e2c211035..9d42af2d7091f 100644
--- a/lldb/tools/lldb-dap/DAP.cpp
+++ b/lldb/tools/lldb-dap/DAP.cpp
@@ -8,10 +8,12 @@
 
 #include "DAP.h"
 #include "DAPLog.h"
+#include "Handler/RequestHandler.h"
 #include "Handler/ResponseHandler.h"
 #include "JSONUtils.h"
 #include "LLDBUtils.h"
 #include "OutputRedirector.h"
+#include "Protocol.h"
 #include "Transport.h"
 #include "lldb/API/SBBreakpoint.h"
 #include "lldb/API/SBCommandInterpreter.h"
@@ -25,6 +27,7 @@
 #include "lldb/lldb-defines.h"
 #include "lldb/lldb-enumerations.h"
 #include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/ScopeExit.h"
 #include "llvm/ADT/StringExtras.h"
 #include "llvm/ADT/StringRef.h"
@@ -41,6 +44,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 
 #if defined(_WIN32)
@@ -663,31 +667,23 @@ void DAP::SetTarget(const lldb::SBTarget target) {
 }
 
 bool DAP::HandleObject(const protocol::Message &M) {
-  // FIXME: Directly handle `Message` instead of serializing to JSON.
-  llvm::json::Value v = toJSON(M);
-  llvm::json::Object object = *v.getAsObject();
-  const auto packet_type = GetString(object, "type");
-  if (packet_type == "request") {
-const auto command = GetString(object, "command");
-
-auto new_handler_pos = request_handlers.find(command);
+  if (const auto *req = std::get_if(&M)) {
+auto new_handler_pos = request_handlers.find(req->command);
 if (new_handler_pos != request_handlers.end()) {
-  (*new_handler_pos->second)(object);
+  (*new_handler_pos->second)(*req);
   return true; // Success
 }
 
 DAP_LOG(log, "({0}) error: unhandled command '{1}'",
-transport.GetClientName(), command);
+transport.GetClientName(), req->command);
 return false; // Fail
   }
 
-  if (packet_type == "response") {
-auto id = GetInteger(object, "request_seq").value_or(0);
-
+  if (const auto *resp = std::get_if(&M)) {
 std::unique_ptr response_handler;
 {
   std::lock_guard locker(call_mutex);
-  auto inflight = inflight_reverse_requests.find(id);
+  auto inflight = inflight_reverse_requests.find(resp->request_seq);
   if (inflight != inflight_reverse_requests.end()) {
 response_handler = std::move(inflight->second);
 inflight_reverse_requests.erase(inflight);
@@ -695,19 +691,31 @@ bool DAP::HandleObject(const protocol::Message &M) {
 }
 
 if (!response_handler)
-  response_handler = std::make_unique("", id);
+  response_handler =
+  std::make_unique("", resp->request_seq);
 
 // Result should be given, use null if not.
-if (GetBoolean(object, "success").value_or(false)) {
-  llvm::json::Value Result = nullptr;
-  if (auto *B = object.get("body"))
-Result = std::move(*B);
-  (*response_handler)(Result);
+if (resp->success) {
+  (*response_handler)(resp->rawBody);
 } else {
-  llvm::StringRef message = GetString(object, "message");
-  if (message.empty()) {
-message = "Unknown error, response failed";
+  std::string message = "Unknown error, response failed";
+  if (resp->message) {
+message = std::visit(
+llvm::makeVisitor(
+[](const std::string &message) -> std::string {
+  return message;
+},
+[](const protocol::Response::Message &message) -> std::string {
+  switch (message) {
+  case protocol::Response::Message::cancelled:
+return "cancelled";
+  case protocol::Response::Message::notStopped:
+return "notStopped";
+  }
+}),
+*resp->message);
   }
+
   (*response_handler)(llvm::createStringError(
   std::error_code(-1, std::generic_category()), message));
 }
@@

[Lldb-commits] [lldb] [lldb-dap] Updating RequestHandler to encode/decode arguments and response. (PR #130090)

2025-03-12 Thread John Harrison via lldb-commits

https://github.com/ashgti ready_for_review 
https://github.com/llvm/llvm-project/pull/130090
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] Remove Function::GetAddressRange usage from the gui (PR #130991)

2025-03-12 Thread via lldb-commits

llvmbot wrote:




@llvm/pr-subscribers-lldb

Author: Pavel Labath (labath)


Changes

m_disassembly_range was used only to prune the list of breakpoints to those 
that are in the current function. This isn't really necessary, as the list is 
only used to highlight instructions with breakpoints on them, and an unpruned 
list works just as well for that.

The shouldn't make things slower, since we still needed through iterate through 
all breakpoints to create the list, and I doubt anyone will notice the memory 
used to store the extra breakpoints.

---
Full diff: https://github.com/llvm/llvm-project/pull/130991.diff


1 Files Affected:

- (modified) lldb/source/Core/IOHandlerCursesGUI.cpp (+4-22) 


``diff
diff --git a/lldb/source/Core/IOHandlerCursesGUI.cpp 
b/lldb/source/Core/IOHandlerCursesGUI.cpp
index ee6e847cdb688..7f0e0fc3b7293 100644
--- a/lldb/source/Core/IOHandlerCursesGUI.cpp
+++ b/lldb/source/Core/IOHandlerCursesGUI.cpp
@@ -6781,8 +6781,7 @@ class StatusBarWindowDelegate : public WindowDelegate {
 class SourceFileWindowDelegate : public WindowDelegate {
 public:
   SourceFileWindowDelegate(Debugger &debugger)
-  : WindowDelegate(), m_debugger(debugger), m_sc(), m_file_sp(),
-m_disassembly_sp(), m_disassembly_range(), m_title() {}
+  : WindowDelegate(), m_debugger(debugger) {}
 
   ~SourceFileWindowDelegate() override = default;
 
@@ -6939,12 +6938,8 @@ class SourceFileWindowDelegate : public WindowDelegate {
   m_disassembly_scope = m_sc.function;
   m_disassembly_sp = m_sc.function->GetInstructions(
   exe_ctx, nullptr, !prefer_file_cache);
-  if (m_disassembly_sp) {
+  if (m_disassembly_sp)
 set_selected_line_to_pc = true;
-m_disassembly_range = m_sc.function->GetAddressRange();
-  } else {
-m_disassembly_range.Clear();
-  }
 } else {
   set_selected_line_to_pc = context_changed;
 }
@@ -6953,14 +6948,8 @@ class SourceFileWindowDelegate : public WindowDelegate {
   m_disassembly_scope = m_sc.symbol;
   m_disassembly_sp = m_sc.symbol->GetInstructions(
   exe_ctx, nullptr, prefer_file_cache);
-  if (m_disassembly_sp) {
+  if (m_disassembly_sp)
 set_selected_line_to_pc = true;
-m_disassembly_range.GetBaseAddress() =
-m_sc.symbol->GetAddress();
-m_disassembly_range.SetByteSize(m_sc.symbol->GetByteSize());
-  } else {
-m_disassembly_range.Clear();
-  }
 } else {
   set_selected_line_to_pc = context_changed;
 }
@@ -7114,13 +7103,7 @@ class SourceFileWindowDelegate : public WindowDelegate {
  ++bp_loc_idx) {
   BreakpointLocationSP bp_loc_sp =
   bp_sp->GetLocationAtIndex(bp_loc_idx);
-  LineEntry bp_loc_line_entry;
-  const lldb::addr_t file_addr =
-  bp_loc_sp->GetAddress().GetFileAddress();
-  if (file_addr != LLDB_INVALID_ADDRESS) {
-if (m_disassembly_range.ContainsFileAddress(file_addr))
-  bp_file_addrs.insert(file_addr);
-  }
+  bp_file_addrs.insert(bp_loc_sp->GetAddress().GetFileAddress());
 }
   }
 }
@@ -7552,7 +7535,6 @@ class SourceFileWindowDelegate : public WindowDelegate {
   SourceManager::FileSP m_file_sp;
   SymbolContextScope *m_disassembly_scope = nullptr;
   lldb::DisassemblerSP m_disassembly_sp;
-  AddressRange m_disassembly_range;
   StreamString m_title;
   lldb::user_id_t m_tid = LLDB_INVALID_THREAD_ID;
   int m_line_width = 4;

``




https://github.com/llvm/llvm-project/pull/130991
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb-dap] Updating RequestHandler to encode/decode arguments and response. (PR #130090)

2025-03-12 Thread John Harrison via lldb-commits


@@ -57,235 +68,288 @@ class RequestHandler {
   DAP &dap;
 };
 
-class AttachRequestHandler : public RequestHandler {
-public:
-  using RequestHandler::RequestHandler;
+/// Base class for handling DAP requests. Handlers should declare their
+/// arguments and response body types like:
+///
+/// class MyRequestHandler : public RequestHandler {
+///   
+/// };
+template 
+class RequestHandler : public BaseRequestHandler {
+  using BaseRequestHandler::BaseRequestHandler;
+
+  void operator()(const llvm::json::Object &request) const override {
+/* no-op, the other overload handles json coding. */
+  }
+
+  void operator()(const protocol::Request &request) const override {
+protocol::Response response;
+response.request_seq = request.seq;
+response.command = request.command;
+Args arguments;
+llvm::json::Path::Root root;
+if (request.rawArguments &&
+!fromJSON(request.rawArguments, arguments, root)) {
+  std::string parseFailure;
+  llvm::raw_string_ostream OS(parseFailure);
+  root.printErrorContext(request.rawArguments, OS);
+  response.success = false;
+  response.message = parseFailure;

ashgti wrote:

I have a FIXME for addressing this, but to minimize the changes I kept this 
mostly backwards compatible with the current approach.

I can follow up this PR with a `DAPError` type for enhanced error reporting.

https://github.com/llvm/llvm-project/pull/130090
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [LLDB][Minidump]Update MinidumpFileBuilder to read and write in chunks (PR #129307)

2025-03-12 Thread Jacob Lalonde via lldb-commits


@@ -969,6 +969,83 @@ Status MinidumpFileBuilder::DumpDirectories() const {
   return error;
 }
 
+Status MinidumpFileBuilder::ReadWriteMemoryInChunks(
+const std::unique_ptr &data_up,
+const lldb_private::CoreFileMemoryRange &range, uint64_t *bytes_read) {
+  if (!data_up)
+return Status::FromErrorString("No buffer supplied to read memory.");
+
+  if (!bytes_read)
+return Status::FromErrorString("Bytes read pointer cannot be null.");
+  Log *log = GetLog(LLDBLog::Object);
+  const lldb::addr_t addr = range.range.start();
+  const lldb::addr_t size = range.range.size();
+  // First we set the byte tally to 0, so if we do exit gracefully
+  // the caller doesn't think the random garbage on the stack is a
+  // success.
+  *bytes_read = 0;
+
+  uint64_t bytes_remaining = size;
+  Status error;
+  while (bytes_remaining > 0) {
+// Get the next read chunk size as the minimum of the remaining bytes and
+// the write chunk max size.
+const size_t bytes_to_read =
+std::min(bytes_remaining, data_up->GetByteSize());
+const size_t bytes_read_for_chunk =
+m_process_sp->ReadMemory(range.range.start() + *bytes_read,
+ data_up->GetBytes(), bytes_to_read, error);
+if (error.Fail() || bytes_read_for_chunk == 0) {
+  LLDB_LOGF(log,
+"Failed to read memory region at: %" PRIx64
+". Bytes read: %zu, error: %s",
+addr, bytes_read_for_chunk, error.AsCString());
+  // If we've read nothing, and get an error or fail to read
+  // we can just give up early.
+  if (*bytes_read == 0)
+return Status();
+
+  // If we've read some bytes, we stop trying to read more and return
+  // this best effort attempt
+  bytes_remaining = 0;

Jlalond wrote:

Hey @jeffreytan81, my thought process here is we managed to read any bytes, we 
should append those to the buffer and return bytes read up to the point.

So in my hypothetical we try to read 1000 bytes from an address, and only read 
500. I still wanted to save off those 500. Are you against this proposal? It's 
why in error conditions other than `AddData()` I just set the loop to not 
continue.

https://github.com/llvm/llvm-project/pull/129307
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [LLDB][Minidump]Update MinidumpFileBuilder to read and write in chunks (PR #129307)

2025-03-12 Thread Jacob Lalonde via lldb-commits


@@ -969,6 +969,83 @@ Status MinidumpFileBuilder::DumpDirectories() const {
   return error;
 }
 
+Status MinidumpFileBuilder::ReadWriteMemoryInChunks(
+const std::unique_ptr &data_up,
+const lldb_private::CoreFileMemoryRange &range, uint64_t *bytes_read) {
+  if (!data_up)
+return Status::FromErrorString("No buffer supplied to read memory.");
+
+  if (!bytes_read)
+return Status::FromErrorString("Bytes read pointer cannot be null.");
+  Log *log = GetLog(LLDBLog::Object);
+  const lldb::addr_t addr = range.range.start();
+  const lldb::addr_t size = range.range.size();
+  // First we set the byte tally to 0, so if we do exit gracefully
+  // the caller doesn't think the random garbage on the stack is a
+  // success.
+  *bytes_read = 0;
+
+  uint64_t bytes_remaining = size;
+  Status error;
+  while (bytes_remaining > 0) {
+// Get the next read chunk size as the minimum of the remaining bytes and
+// the write chunk max size.
+const size_t bytes_to_read =
+std::min(bytes_remaining, data_up->GetByteSize());
+const size_t bytes_read_for_chunk =
+m_process_sp->ReadMemory(range.range.start() + *bytes_read,
+ data_up->GetBytes(), bytes_to_read, error);
+if (error.Fail() || bytes_read_for_chunk == 0) {
+  LLDB_LOGF(log,
+"Failed to read memory region at: %" PRIx64
+". Bytes read: %zu, error: %s",
+addr, bytes_read_for_chunk, error.AsCString());
+  // If we've read nothing, and get an error or fail to read
+  // we can just give up early.
+  if (*bytes_read == 0)
+return Status();
+
+  // If we've read some bytes, we stop trying to read more and return
+  // this best effort attempt
+  bytes_remaining = 0;

Jlalond wrote:

I'm okay with another exit statement, the `bytes_remaining == 0` does feel 
quite brittle. But my primary concern here is do we include or exclude partial 
reads. In the existing system we would just skip them. So there is a precedence 
for it, I think by trying to include the extra bytes we can improve the user 
experience.

I will update the check that if `bytes_read_for_chunk == 0` we also just quick 
return.

https://github.com/llvm/llvm-project/pull/129307
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] Split TestGdbRemoteFork test to avoid timeout (PR #129614)

2025-03-12 Thread David Peixotto via lldb-commits

https://github.com/dmpots edited 
https://github.com/llvm/llvm-project/pull/129614
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] Split some tests to avoid timeout (PR #129614)

2025-03-12 Thread David Peixotto via lldb-commits

https://github.com/dmpots edited 
https://github.com/llvm/llvm-project/pull/129614
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] Synchronize interrupt and resume signals in debugserver (PR #131073)

2025-03-12 Thread Jonas Devlieghere via lldb-commits

https://github.com/JDevlieghere updated 
https://github.com/llvm/llvm-project/pull/131073

>From 48ab516f56328fe101fe3fe1cd22a06ec1a033e2 Mon Sep 17 00:00:00 2001
From: Jonas Devlieghere 
Date: Wed, 12 Mar 2025 22:07:41 -0700
Subject: [PATCH] [lldb] Synchronize interrupt and resume signals in
 debugserver

This PR fixes a race condition in debugserver where the main thread
calls MachProcess::Interrupt, setting `m_sent_interrupt_signo` while
the exception monitoring thread is checking value of the variable.

I was on the fence between introducing a new mutex and reusing the
existing exception mutex. With the notable exception of
MachProcess::Interrupt, all the other places where we were already
locking this mutex before accessing the variable. I renamed the mutex to
make it clear that it's now protecting more than the exception messages.

Jason, while investigating a real issue, had a suspicion there was race
condition related to interrupts and I was able to narrow it down by
building debugserver with TSan.
---
 .../debugserver/source/MacOSX/MachProcess.h   |  6 +++---
 .../debugserver/source/MacOSX/MachProcess.mm  | 19 ---
 2 files changed, 15 insertions(+), 10 deletions(-)

diff --git a/lldb/tools/debugserver/source/MacOSX/MachProcess.h 
b/lldb/tools/debugserver/source/MacOSX/MachProcess.h
index db673693a1b21..ec0a13b482267 100644
--- a/lldb/tools/debugserver/source/MacOSX/MachProcess.h
+++ b/lldb/tools/debugserver/source/MacOSX/MachProcess.h
@@ -427,7 +427,7 @@ class MachProcess {
   m_profile_data_mutex; // Multithreaded protection for profile info data
   std::vector
   m_profile_data; // Profile data, must be protected by 
m_profile_data_mutex
-  PThreadEvent m_profile_events; // Used for the profile thread cancellable 
wait  
+  PThreadEvent m_profile_events; // Used for the profile thread cancellable 
wait
   DNBThreadResumeActions m_thread_actions; // The thread actions for the 
current
// MachProcess::Resume() call
   MachException::Message::collection m_exception_messages; // A collection of
@@ -435,8 +435,8 @@ class MachProcess {
// caught when
// listening to the
// exception port
-  PThreadMutex m_exception_messages_mutex; // Multithreaded protection for
-   // m_exception_messages
+  PThreadMutex m_exception_and_signal_mutex; // Multithreaded protection for
+ // exceptions and signals.
 
   MachThreadList m_thread_list; // A list of threads that is maintained/updated
 // after each stop
diff --git a/lldb/tools/debugserver/source/MacOSX/MachProcess.mm 
b/lldb/tools/debugserver/source/MacOSX/MachProcess.mm
index a2179bf2f91e5..7dcc04c07bbff 100644
--- a/lldb/tools/debugserver/source/MacOSX/MachProcess.mm
+++ b/lldb/tools/debugserver/source/MacOSX/MachProcess.mm
@@ -528,7 +528,7 @@ static bool FBSAddEventDataToOptions(NSMutableDictionary 
*options,
   m_profile_data_mutex(PTHREAD_MUTEX_RECURSIVE), m_profile_data(),
   m_profile_events(0, eMachProcessProfileCancel), m_thread_actions(),
   m_exception_messages(),
-  m_exception_messages_mutex(PTHREAD_MUTEX_RECURSIVE), m_thread_list(),
+  m_exception_and_signal_mutex(PTHREAD_MUTEX_RECURSIVE), m_thread_list(),
   m_activities(), m_state(eStateUnloaded),
   m_state_mutex(PTHREAD_MUTEX_RECURSIVE), m_events(0, kAllEventsMask),
   m_private_events(0, kAllEventsMask), m_breakpoints(), m_watchpoints(),
@@ -1338,8 +1338,11 @@ static bool mach_header_validity_test(uint32_t magic, 
uint32_t cputype) {
   m_stop_count = 0;
   m_thread_list.Clear();
   {
-PTHREAD_MUTEX_LOCKER(locker, m_exception_messages_mutex);
+PTHREAD_MUTEX_LOCKER(locker, m_exception_and_signal_mutex);
 m_exception_messages.clear();
+m_sent_interrupt_signo = 0;
+m_auto_resume_signo = 0;
+
   }
   m_activities.Clear();
   StopProfileThread();
@@ -1573,6 +1576,8 @@ static uint64_t bits(uint64_t value, uint32_t msbit, 
uint32_t lsbit) {
 }
 
 bool MachProcess::Interrupt() {
+  PTHREAD_MUTEX_LOCKER(locker, m_exception_and_signal_mutex);
+
   nub_state_t state = GetState();
   if (IsRunning(state)) {
 if (m_sent_interrupt_signo == 0) {
@@ -1728,7 +1733,7 @@ static uint64_t bits(uint64_t value, uint32_t msbit, 
uint32_t lsbit) {
 m_thread_actions.Append(thread_action);
 m_thread_actions.SetDefaultThreadActionIfNeeded(eStateRunning, 0);
 
-PTHREAD_MUTEX_LOCKER(locker, m_exception_messages_mutex);
+PTHREAD_MUTEX_LOCKER(locker, m_exception_and_signal_mutex);
 
 ReplyToAllExceptions();
   }
@@ -1854,7 +1859,7 @@ static uint64_t bits(uint64_t value, uint32_t msbit, 
uint32_t lsbit) {
 }
 
 void MachProcess::ReplyToAllExceptions() {
-  PTHREAD_MUTEX_LOCKER(locker, m_exc

[Lldb-commits] [lldb] [lldb][AIX] Added base files for NativeProcess Support for AIX (PR #118160)

2025-03-12 Thread Dhruv Srivastava via lldb-commits

https://github.com/DhruvSrivastavaX updated 
https://github.com/llvm/llvm-project/pull/118160

>From 03a290e9c748540b69ca6df7fa9c4481f9cdd3d0 Mon Sep 17 00:00:00 2001
From: Dhruv-Srivastava 
Date: Sat, 30 Nov 2024 01:14:15 -0600
Subject: [PATCH 01/11] Added base files for NativeProcess for AIX

---
 .../source/Plugins/Process/AIX/CMakeLists.txt |  14 +
 .../Plugins/Process/AIX/NativeProcessAIX.cpp  | 288 ++
 .../Plugins/Process/AIX/NativeProcessAIX.h| 134 
 lldb/source/Plugins/Process/CMakeLists.txt|   3 +
 4 files changed, 439 insertions(+)
 create mode 100644 lldb/source/Plugins/Process/AIX/CMakeLists.txt
 create mode 100644 lldb/source/Plugins/Process/AIX/NativeProcessAIX.cpp
 create mode 100644 lldb/source/Plugins/Process/AIX/NativeProcessAIX.h

diff --git a/lldb/source/Plugins/Process/AIX/CMakeLists.txt 
b/lldb/source/Plugins/Process/AIX/CMakeLists.txt
new file mode 100644
index 0..4fabbe9302287
--- /dev/null
+++ b/lldb/source/Plugins/Process/AIX/CMakeLists.txt
@@ -0,0 +1,14 @@
+add_lldb_library(lldbPluginProcessAIX
+  NativeProcessAIX.cpp
+
+  LINK_LIBS
+lldbCore
+lldbHost
+lldbSymbol
+lldbTarget
+lldbUtility
+lldbPluginProcessPOSIX
+lldbPluginProcessUtility
+  LINK_COMPONENTS
+Support
+  )
diff --git a/lldb/source/Plugins/Process/AIX/NativeProcessAIX.cpp 
b/lldb/source/Plugins/Process/AIX/NativeProcessAIX.cpp
new file mode 100644
index 0..6661693b2fc02
--- /dev/null
+++ b/lldb/source/Plugins/Process/AIX/NativeProcessAIX.cpp
@@ -0,0 +1,288 @@
+//===-- NativeProcessAIX.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 "NativeProcessAIX.h"
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include "NativeThreadAIX.h"
+#include "Plugins/Process/POSIX/ProcessPOSIXLog.h"
+#include "lldb/Core/ModuleSpec.h"
+#include "lldb/Host/Host.h"
+#include "lldb/Host/HostProcess.h"
+#include "lldb/Host/ProcessLaunchInfo.h"
+#include "lldb/Host/PseudoTerminal.h"
+#include "lldb/Host/ThreadLauncher.h"
+#include "lldb/Host/common/NativeRegisterContext.h"
+#include "lldb/Host/aix/Ptrace.h"
+#include "lldb/Host/posix/ProcessLauncherPosixFork.h"
+#include "lldb/Symbol/ObjectFile.h"
+#include "lldb/Target/Process.h"
+#include "lldb/Target/Target.h"
+#include "lldb/Utility/LLDBAssert.h"
+#include "lldb/Utility/LLDBLog.h"
+#include "lldb/Utility/RegisterValue.h"
+#include "lldb/Utility/State.h"
+#include "lldb/Utility/Status.h"
+#include "lldb/Utility/StringExtractor.h"
+#include "llvm/ADT/ScopeExit.h"
+#include "llvm/Support/Errno.h"
+#include "llvm/Support/Error.h"
+#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/Threading.h"
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#ifdef __aarch64__
+#include 
+#include 
+#endif
+
+// Support hardware breakpoints in case it has not been defined
+#ifndef TRAP_HWBKPT
+#define TRAP_HWBKPT 4
+#endif
+
+#ifndef HWCAP2_MTE
+#define HWCAP2_MTE (1 << 18)
+#endif
+
+using namespace lldb;
+using namespace lldb_private;
+using namespace lldb_private::process_aix;
+using namespace llvm;
+
+static constexpr unsigned k_ptrace_word_size = sizeof(void *);
+static_assert(sizeof(long) >= k_ptrace_word_size,
+  "Size of long must be larger than ptrace word size");
+
+// Simple helper function to ensure flags are enabled on the given file
+// descriptor.
+static Status EnsureFDFlags(int fd, int flags) {
+  Status error;
+
+  int status = fcntl(fd, F_GETFL);
+  if (status == -1) {
+error = Status::FromErrno();
+return error;
+  }
+
+  if (fcntl(fd, F_SETFL, status | flags) == -1) {
+error = Status::FromErrno();
+return error;
+  }
+
+  return error;
+}
+
+NativeProcessAIX::Manager::Manager(MainLoop &mainloop)
+: NativeProcessProtocol::Manager(mainloop) {
+  Status status;
+  m_sigchld_handle = mainloop.RegisterSignal(
+  SIGCHLD, [this](MainLoopBase &) { SigchldHandler(); }, status);
+  assert(m_sigchld_handle && status.Success());
+}
+
+// Public Static Methods
+
+llvm::Expected>
+NativeProcessAIX::Manager::Launch(ProcessLaunchInfo &launch_info,
+NativeDelegate &native_delegate) {
+  Log *log = GetLog(POSIXLog::Process);
+
+  Status status;
+  ::pid_t pid = ProcessLauncherPosixFork()
+.LaunchProcess(launch_info, status)
+.GetProcessId();
+  LLDB_LOG(log, "pid = {0:x}", pid);
+  if (status.Fail()) {
+LLDB_LOG(log, "failed to launch process: {0}", status);
+return status.ToError();
+  }
+
+  // Wait for the child process to trap on its call to execve.
+  int wstatus = 0;
+  ::pid

[Lldb-commits] [lldb] Make breakpoint stop reason more accurate for function breakpoints (PR #130841)

2025-03-12 Thread via lldb-commits


@@ -383,6 +383,12 @@ struct DAP {
 
   InstructionBreakpoint *GetInstructionBPFromStopReason(lldb::SBThread 
&thread);
 
+  FunctionBreakpoint *GetFunctionBPFromStopReason(lldb::SBThread &thread);
+
+  FunctionBreakpoint *GetFunctionBreakPoint(const lldb::break_id_t bp_id);
+
+  void WaitWorkerThreadsToExit();

satyajanga wrote:

Removed it, it got added when resolving the merge conflict.

https://github.com/llvm/llvm-project/pull/130841
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] Synchronize interrupt and resume signals in debugserver (PR #131073)

2025-03-12 Thread via lldb-commits

llvmbot wrote:




@llvm/pr-subscribers-lldb

Author: Jonas Devlieghere (JDevlieghere)


Changes

This PR fixes a race condition in debugserver where the main thread calls 
MachProcess::Interrupt, setting `m_sent_interrupt_signo` while the exception 
monitoring thread is checking value of the variable.

I was on the fence between introducing a new mutex and reusing the existing 
exception mutex. With the notable exception of MachProcess::Interrupt, all the 
other places where we were already locking this mutex before accessing the 
variable. I renamed the mutex to make it clear that it's now protecting more 
than the exception messages.

Jason, while investigating a real issue, had a suspicion there was race 
condition related to interrupts and I was able to narrow it down by building 
debugserver with TSan.

---
Full diff: https://github.com/llvm/llvm-project/pull/131073.diff


2 Files Affected:

- (modified) lldb/tools/debugserver/source/MacOSX/MachProcess.h (+2-2) 
- (modified) lldb/tools/debugserver/source/MacOSX/MachProcess.mm (+12-7) 


``diff
diff --git a/lldb/tools/debugserver/source/MacOSX/MachProcess.h 
b/lldb/tools/debugserver/source/MacOSX/MachProcess.h
index db673693a1b21..d7fa859863162 100644
--- a/lldb/tools/debugserver/source/MacOSX/MachProcess.h
+++ b/lldb/tools/debugserver/source/MacOSX/MachProcess.h
@@ -435,8 +435,8 @@ class MachProcess {
// caught when
// listening to the
// exception port
-  PThreadMutex m_exception_messages_mutex; // Multithreaded protection for
-   // m_exception_messages
+  PThreadMutex m_exception_and_signal_mutex; // Multithreaded protection for
+   // exceptions and signals.
 
   MachThreadList m_thread_list; // A list of threads that is maintained/updated
 // after each stop
diff --git a/lldb/tools/debugserver/source/MacOSX/MachProcess.mm 
b/lldb/tools/debugserver/source/MacOSX/MachProcess.mm
index a2179bf2f91e5..7dcc04c07bbff 100644
--- a/lldb/tools/debugserver/source/MacOSX/MachProcess.mm
+++ b/lldb/tools/debugserver/source/MacOSX/MachProcess.mm
@@ -528,7 +528,7 @@ static bool FBSAddEventDataToOptions(NSMutableDictionary 
*options,
   m_profile_data_mutex(PTHREAD_MUTEX_RECURSIVE), m_profile_data(),
   m_profile_events(0, eMachProcessProfileCancel), m_thread_actions(),
   m_exception_messages(),
-  m_exception_messages_mutex(PTHREAD_MUTEX_RECURSIVE), m_thread_list(),
+  m_exception_and_signal_mutex(PTHREAD_MUTEX_RECURSIVE), m_thread_list(),
   m_activities(), m_state(eStateUnloaded),
   m_state_mutex(PTHREAD_MUTEX_RECURSIVE), m_events(0, kAllEventsMask),
   m_private_events(0, kAllEventsMask), m_breakpoints(), m_watchpoints(),
@@ -1338,8 +1338,11 @@ static bool mach_header_validity_test(uint32_t magic, 
uint32_t cputype) {
   m_stop_count = 0;
   m_thread_list.Clear();
   {
-PTHREAD_MUTEX_LOCKER(locker, m_exception_messages_mutex);
+PTHREAD_MUTEX_LOCKER(locker, m_exception_and_signal_mutex);
 m_exception_messages.clear();
+m_sent_interrupt_signo = 0;
+m_auto_resume_signo = 0;
+
   }
   m_activities.Clear();
   StopProfileThread();
@@ -1573,6 +1576,8 @@ static uint64_t bits(uint64_t value, uint32_t msbit, 
uint32_t lsbit) {
 }
 
 bool MachProcess::Interrupt() {
+  PTHREAD_MUTEX_LOCKER(locker, m_exception_and_signal_mutex);
+
   nub_state_t state = GetState();
   if (IsRunning(state)) {
 if (m_sent_interrupt_signo == 0) {
@@ -1728,7 +1733,7 @@ static uint64_t bits(uint64_t value, uint32_t msbit, 
uint32_t lsbit) {
 m_thread_actions.Append(thread_action);
 m_thread_actions.SetDefaultThreadActionIfNeeded(eStateRunning, 0);
 
-PTHREAD_MUTEX_LOCKER(locker, m_exception_messages_mutex);
+PTHREAD_MUTEX_LOCKER(locker, m_exception_and_signal_mutex);
 
 ReplyToAllExceptions();
   }
@@ -1854,7 +1859,7 @@ static uint64_t bits(uint64_t value, uint32_t msbit, 
uint32_t lsbit) {
 }
 
 void MachProcess::ReplyToAllExceptions() {
-  PTHREAD_MUTEX_LOCKER(locker, m_exception_messages_mutex);
+  PTHREAD_MUTEX_LOCKER(locker, m_exception_and_signal_mutex);
   if (!m_exception_messages.empty()) {
 MachException::Message::iterator pos;
 MachException::Message::iterator begin = m_exception_messages.begin();
@@ -1888,7 +1893,7 @@ static uint64_t bits(uint64_t value, uint32_t msbit, 
uint32_t lsbit) {
   }
 }
 void MachProcess::PrivateResume() {
-  PTHREAD_MUTEX_LOCKER(locker, m_exception_messages_mutex);
+  PTHREAD_MUTEX_LOCKER(locker, m_exception_and_signal_mutex);
 
   m_auto_resume_signo = m_sent_interrupt_signo;
   if (m_auto_resume_signo)
@@ -2290,7 +2295,7 @@ static uint64_t bits(uint64_t value, uint32_t msbit, 
uint32_t lsbit) {
 // data has already been copied.
 void MachProcess::ExceptionMessageReceived

[Lldb-commits] [lldb] [lldb] Synchronize interrupt and resume signals in debugserver (PR #131073)

2025-03-12 Thread Jonas Devlieghere via lldb-commits

https://github.com/JDevlieghere created 
https://github.com/llvm/llvm-project/pull/131073

This PR fixes a race condition in debugserver where the main thread calls 
MachProcess::Interrupt, setting `m_sent_interrupt_signo` while the exception 
monitoring thread is checking value of the variable.

I was on the fence between introducing a new mutex and reusing the existing 
exception mutex. With the notable exception of MachProcess::Interrupt, all the 
other places where we were already locking this mutex before accessing the 
variable. I renamed the mutex to make it clear that it's now protecting more 
than the exception messages.

Jason, while investigating a real issue, had a suspicion there was race 
condition related to interrupts and I was able to narrow it down by building 
debugserver with TSan.

>From 4c435f07fa6c59ea3d1fb46e65cf62a3d2253d54 Mon Sep 17 00:00:00 2001
From: Jonas Devlieghere 
Date: Wed, 12 Mar 2025 22:07:41 -0700
Subject: [PATCH] [lldb] Synchronize interrupt and resume signals in
 debugserver

This PR fixes a race condition in debugserver where the main thread
calls MachProcess::Interrupt, setting `m_sent_interrupt_signo` while
the exception monitoring thread is checking value of the variable.

I was on the fence between introducing a new mutex and reusing the
existing exception mutex. With the notable exception of
MachProcess::Interrupt, all the other places where we were already
locking this mutex before accessing the variable. I renamed the mutex to
make it clear that it's now protecting more than the exception messages.

Jason, while investigating a real issue, had a suspicion there was race
condition related to interrupts and I was able to narrow it down by
building debugserver with TSan.
---
 .../debugserver/source/MacOSX/MachProcess.h   |  4 ++--
 .../debugserver/source/MacOSX/MachProcess.mm  | 19 ---
 2 files changed, 14 insertions(+), 9 deletions(-)

diff --git a/lldb/tools/debugserver/source/MacOSX/MachProcess.h 
b/lldb/tools/debugserver/source/MacOSX/MachProcess.h
index db673693a1b21..d7fa859863162 100644
--- a/lldb/tools/debugserver/source/MacOSX/MachProcess.h
+++ b/lldb/tools/debugserver/source/MacOSX/MachProcess.h
@@ -435,8 +435,8 @@ class MachProcess {
// caught when
// listening to the
// exception port
-  PThreadMutex m_exception_messages_mutex; // Multithreaded protection for
-   // m_exception_messages
+  PThreadMutex m_exception_and_signal_mutex; // Multithreaded protection for
+   // exceptions and signals.
 
   MachThreadList m_thread_list; // A list of threads that is maintained/updated
 // after each stop
diff --git a/lldb/tools/debugserver/source/MacOSX/MachProcess.mm 
b/lldb/tools/debugserver/source/MacOSX/MachProcess.mm
index a2179bf2f91e5..7dcc04c07bbff 100644
--- a/lldb/tools/debugserver/source/MacOSX/MachProcess.mm
+++ b/lldb/tools/debugserver/source/MacOSX/MachProcess.mm
@@ -528,7 +528,7 @@ static bool FBSAddEventDataToOptions(NSMutableDictionary 
*options,
   m_profile_data_mutex(PTHREAD_MUTEX_RECURSIVE), m_profile_data(),
   m_profile_events(0, eMachProcessProfileCancel), m_thread_actions(),
   m_exception_messages(),
-  m_exception_messages_mutex(PTHREAD_MUTEX_RECURSIVE), m_thread_list(),
+  m_exception_and_signal_mutex(PTHREAD_MUTEX_RECURSIVE), m_thread_list(),
   m_activities(), m_state(eStateUnloaded),
   m_state_mutex(PTHREAD_MUTEX_RECURSIVE), m_events(0, kAllEventsMask),
   m_private_events(0, kAllEventsMask), m_breakpoints(), m_watchpoints(),
@@ -1338,8 +1338,11 @@ static bool mach_header_validity_test(uint32_t magic, 
uint32_t cputype) {
   m_stop_count = 0;
   m_thread_list.Clear();
   {
-PTHREAD_MUTEX_LOCKER(locker, m_exception_messages_mutex);
+PTHREAD_MUTEX_LOCKER(locker, m_exception_and_signal_mutex);
 m_exception_messages.clear();
+m_sent_interrupt_signo = 0;
+m_auto_resume_signo = 0;
+
   }
   m_activities.Clear();
   StopProfileThread();
@@ -1573,6 +1576,8 @@ static uint64_t bits(uint64_t value, uint32_t msbit, 
uint32_t lsbit) {
 }
 
 bool MachProcess::Interrupt() {
+  PTHREAD_MUTEX_LOCKER(locker, m_exception_and_signal_mutex);
+
   nub_state_t state = GetState();
   if (IsRunning(state)) {
 if (m_sent_interrupt_signo == 0) {
@@ -1728,7 +1733,7 @@ static uint64_t bits(uint64_t value, uint32_t msbit, 
uint32_t lsbit) {
 m_thread_actions.Append(thread_action);
 m_thread_actions.SetDefaultThreadActionIfNeeded(eStateRunning, 0);
 
-PTHREAD_MUTEX_LOCKER(locker, m_exception_messages_mutex);
+PTHREAD_MUTEX_LOCKER(locker, m_exception_and_signal_mutex);
 
 ReplyToAllExceptions();
   }
@@ -1854,7 +1859,7 @@ static uint64_t bits(uint64_t value, uint32_t msbit, 
uint32_

[Lldb-commits] [lldb] [debugserver] Synchronize interrupt and resume signals (PR #131073)

2025-03-12 Thread Jonas Devlieghere via lldb-commits

https://github.com/JDevlieghere edited 
https://github.com/llvm/llvm-project/pull/131073
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb][lldb-dap] Implement jump to cursor (PR #130503)

2025-03-12 Thread Ebuka Ezike via lldb-commits

https://github.com/da-viper updated 
https://github.com/llvm/llvm-project/pull/130503

>From 63c0d5071146893b485dd4d2665e55fc697e1352 Mon Sep 17 00:00:00 2001
From: Ezike Ebuka 
Date: Sun, 9 Mar 2025 12:46:54 +
Subject: [PATCH 01/13] [lldb-dap] implement jump to cursor.

---
 lldb/cmake/modules/LLDBConfig.cmake   |   2 +-
 lldb/tools/lldb-dap/CMakeLists.txt|   2 +
 lldb/tools/lldb-dap/DAP.cpp   |  23 +++-
 lldb/tools/lldb-dap/DAP.h |  27 +++-
 .../lldb-dap/Handler/GoToRequestHandler.cpp   | 103 +++
 .../Handler/GoToTargetsRequestHandler.cpp | 120 ++
 .../Handler/InitializeRequestHandler.cpp  |   2 +-
 lldb/tools/lldb-dap/Handler/RequestHandler.h  |  14 ++
 lldb/tools/lldb-dap/lldb-dap.cpp  |   2 +
 9 files changed, 291 insertions(+), 4 deletions(-)
 create mode 100644 lldb/tools/lldb-dap/Handler/GoToRequestHandler.cpp
 create mode 100644 lldb/tools/lldb-dap/Handler/GoToTargetsRequestHandler.cpp

diff --git a/lldb/cmake/modules/LLDBConfig.cmake 
b/lldb/cmake/modules/LLDBConfig.cmake
index 747f7e6038181..8d02088548634 100644
--- a/lldb/cmake/modules/LLDBConfig.cmake
+++ b/lldb/cmake/modules/LLDBConfig.cmake
@@ -57,7 +57,7 @@ add_optional_dependency(LLDB_ENABLE_CURSES "Enable curses 
support in LLDB" Curse
 add_optional_dependency(LLDB_ENABLE_LZMA "Enable LZMA compression support in 
LLDB" LibLZMA LIBLZMA_FOUND)
 add_optional_dependency(LLDB_ENABLE_LUA "Enable Lua scripting support in LLDB" 
LuaAndSwig LUAANDSWIG_FOUND)
 add_optional_dependency(LLDB_ENABLE_PYTHON "Enable Python scripting support in 
LLDB" PythonAndSwig PYTHONANDSWIG_FOUND)
-add_optional_dependency(LLDB_ENABLE_LIBXML2 "Enable Libxml 2 support in LLDB" 
LibXml2 LIBXML2_FOUND VERSION 2.8)
+add_optional_dependency(LLDB_ENABLE_LIBXML2 "Enable Libxml 2 support in LLDB" 
LibXml2 LIBXML2_FOUND VERSION)
 add_optional_dependency(LLDB_ENABLE_FBSDVMCORE "Enable libfbsdvmcore support 
in LLDB" FBSDVMCore FBSDVMCore_FOUND QUIET)
 
 option(LLDB_USE_ENTITLEMENTS "When codesigning, use entitlements if available" 
ON)
diff --git a/lldb/tools/lldb-dap/CMakeLists.txt 
b/lldb/tools/lldb-dap/CMakeLists.txt
index 9a2d604f4d573..ff7e413c4bb1c 100644
--- a/lldb/tools/lldb-dap/CMakeLists.txt
+++ b/lldb/tools/lldb-dap/CMakeLists.txt
@@ -50,6 +50,8 @@ add_lldb_tool(lldb-dap
   Handler/DisconnectRequestHandler.cpp
   Handler/EvaluateRequestHandler.cpp
   Handler/ExceptionInfoRequestHandler.cpp
+Handler/GoToRequestHandler.cpp
+Handler/GoToTargetsRequestHandler.cpp
   Handler/InitializeRequestHandler.cpp
   Handler/LaunchRequestHandler.cpp
   Handler/LocationsRequestHandler.cpp
diff --git a/lldb/tools/lldb-dap/DAP.cpp b/lldb/tools/lldb-dap/DAP.cpp
index 1f7b25e7c5bcc..f72bc34d52b53 100644
--- a/lldb/tools/lldb-dap/DAP.cpp
+++ b/lldb/tools/lldb-dap/DAP.cpp
@@ -76,7 +76,7 @@ DAP::DAP(std::string name, llvm::StringRef path, 
std::ofstream *log,
   configuration_done_sent(false), waiting_for_run_in_terminal(false),
   progress_event_reporter(
   [&](const ProgressEvent &event) { SendJSON(event.ToJSON()); }),
-  reverse_request_seq(0), repl_mode(repl_mode) {}
+  reverse_request_seq(0), repl_mode(repl_mode), goto_id_map() {}
 
 DAP::~DAP() = default;
 
@@ -899,6 +899,27 @@ lldb::SBError DAP::WaitForProcessToStop(uint32_t seconds) {
   return error;
 }
 
+std::optional Gotos::GetLineEntry(uint64_t id) const {
+  const auto iter = line_entries.find(id);
+  if (iter != line_entries.end())
+return iter->second;
+
+  return std::nullopt;
+}
+
+uint64_t Gotos::InsertLineEntry(lldb::SBLineEntry line_entry) {
+  const auto spec_id = this->NewSpecId();
+  line_entries.insert(std::make_pair(spec_id, line_entry));
+  return spec_id;
+}
+
+void Gotos::Clear() {
+  new_id = 0UL;
+  line_entries.clear();
+}
+
+uint64_t Gotos::NewSpecId() { return new_id++; }
+
 void Variables::Clear() {
   locals.Clear();
   globals.Clear();
diff --git a/lldb/tools/lldb-dap/DAP.h b/lldb/tools/lldb-dap/DAP.h
index 8b2e498a28c95..693908016fdc9 100644
--- a/lldb/tools/lldb-dap/DAP.h
+++ b/lldb/tools/lldb-dap/DAP.h
@@ -79,6 +79,27 @@ enum class PacketStatus {
 
 enum class ReplMode { Variable = 0, Command, Auto };
 
+class Gotos {
+public:
+  /// \return the line_entry corresponding with \p id
+  ///
+  /// If \p id is invalid std::nullopt is returned.
+  std::optional GetLineEntry(uint64_t id) const;
+
+  /// Insert a new \p line_entry.
+  /// \return id assigned to this line_entry.
+  uint64_t InsertLineEntry(lldb::SBLineEntry line_entry);
+
+  /// clears all line entries and reset the generated ids.
+  void Clear();
+
+private:
+  uint64_t NewSpecId();
+
+  llvm::DenseMap line_entries;
+  uint64_t new_id = 0ul;
+};
+
 struct Variables {
   /// Variable_reference start index of permanent expandable variable.
   static constexpr int64_t PermanentVariableStartIndex = (1ll << 32);
@@ -209,6 +230,7 @@ struct DAP {
   // empty; if the previous expression was a varia

[Lldb-commits] [lldb] Parallelize module loading in POSIX dyld code (PR #130912)

2025-03-12 Thread Tom Yang via lldb-commits

https://github.com/zhyty edited https://github.com/llvm/llvm-project/pull/130912
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


  1   2   >