Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[LLDB][Telemetry]Define TargetInfo for collecting data about a target #127834

Merged
merged 39 commits into from
Mar 19, 2025

Conversation

oontvoo
Copy link
Member

@oontvoo oontvoo commented Feb 19, 2025

No description provided.

@oontvoo oontvoo requested review from labath and cmtice February 19, 2025 17:49
@oontvoo oontvoo marked this pull request as draft February 19, 2025 17:49
@llvmbot llvmbot added the lldb label Feb 19, 2025
@llvmbot
Copy link
Member

llvmbot commented Feb 19, 2025

@llvm/pr-subscribers-lldb

Author: Vy Nguyen (oontvoo)

Changes

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

2 Files Affected:

  • (modified) lldb/include/lldb/Core/Telemetry.h (+84-2)
  • (modified) lldb/source/Core/Telemetry.cpp (+86-13)
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 = 0b11110;
 };
 
 /// 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<ExitDescription> 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.
+  /// <EMPTY> otherwise.
+  std::string target_uuid;
+
+  /// Set of key-value pairs for any optional (or impl-specific) data
+  std::map<std::string, std::string> 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<llvm::telemetry::Config> 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<Debugger *, std::string> session_ids;
   static std::unique_ptr<TelemetryManager> 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 "lldb/Target/Statistics.h"
 #include "lldb/Utility/LLDBLog.h"
 #include "lldb/Utility/UUID.h"
+#include "lldb/Version/Version.h"
 #include "lldb/lldb-enumerations.h"
 #include "lldb/lldb-forward.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/Support/Error.h"
+#include "llvm/Support/Path.h"
 #include "llvm/Support/RandomNumberGenerator.h"
 #include "llvm/Telemetry/Telemetry.h"
 #include <chrono>
@@ -35,15 +41,7 @@ static uint64_t ToNanosec(const SteadyTimePoint Point) {
   return std::chrono::nanoseconds(Point.time_since_epoch()).count();
 }
 
-void LLDBBaseTelemetryInfo::serialize(Serializer &serializer) const {
-  serializer.write("entry_kind", getKind());
-  serializer.write("session_id", SessionId);
-  serializer.write("start_time", ToNanosec(start_time));
-  if (end_time.has_value())
-    serializer.write("end_time", ToNanosec(end_time.value()));
-}
-
-[[maybe_unused]] static std::string MakeUUID(Debugger *debugger) {
+static std::string MakeUUID(Debugger *debugger) {
   uint8_t random_bytes[16];
   if (auto ec = llvm::getRandomBytes(random_bytes, 16)) {
     LLDB_LOG(GetLog(LLDBLog::Object),
@@ -56,16 +54,91 @@ void LLDBBaseTelemetryInfo::serialize(Serializer &serializer) const {
   return UUID(random_bytes).GetAsString();
 }
 
+void LLDBBaseTelemetryInfo::serialize(Serializer &serializer) const {
+  serializer.write("entry_kind", getKind());
+  serializer.write("session_id", SessionId);
+  serializer.write("start_time", ToNanosec(start_time));
+  if (end_time.has_value())
+    serializer.write("end_time", ToNanosec(end_time.value()));
+}
+
+void TargetInfo::serialize(Serializer &serializer) const {
+  LLDBBaseTelemetryInfo::serialize(serializer);
+
+  serializer.write("username", username);
+  serializer.write("lldb_git_sha", lldb_git_sha);
+  serializer.write("lldb_path", lldb_path);
+  serializer.write("cwd", cwd);
+  if (exit_desc.has_value()) {
+    serializer.write("exit_code", exit_desc->exit_code);
+    serializer.write("exit_desc", exit_desc->description);
+  }
+}
+
+void MiscTelemetryInfo::serialize(Serializer &serializer) const {
+  LLDBBaseTelemetryInfo::serialize(serializer);
+  serializer.write("target_uuid", target_uuid);
+  serializer.beginObject("meta_data");
+  for (const auto &kv : meta_data)
+    serializer.write(kv.first, kv.second);
+  serializer.endObject();
+}
+
 TelemetryManager::TelemetryManager(std::unique_ptr<Config> config)
     : m_config(std::move(config)) {}
 
 llvm::Error TelemetryManager::preDispatch(TelemetryInfo *entry) {
-  // Do nothing for now.
-  // In up-coming patch, this would be where the manager
-  // attach the session_uuid to the entry.
+  LLDBBaseTelemetryInfo *lldb_entry =
+      llvm::dyn_cast<LLDBBaseTelemetryInfo>(entry);
+  std::string session_id = "";
+  if (Debugger *debugger = lldb_entry->debugger) {
+    auto session_id_pos = session_ids.find(debugger);
+    if (session_id_pos != session_ids.end())
+      session_id = session_id_pos->second;
+    else
+      session_id_pos->second = session_id = MakeUUID(debugger);
+  }
+  lldb_entry->SessionId = session_id;
+
   return llvm::Error::success();
 }
 
+const Config *getConfig() { return m_config.get(); }
+
+void TelemetryManager::AtMainExecutableLoadStart(TargetInfo *entry) {
+  UserIDResolver &resolver = lldb_private::HostInfo::GetUserIDResolver();
+  std::optional<llvm::StringRef> opt_username =
+      resolver.GetUserName(lldb_private::HostInfo::GetUserID());
+  if (opt_username)
+    entry->username = *opt_username;
+
+  entry->lldb_git_sha =
+      lldb_private::GetVersion(); // TODO: find the real git sha?
+
+  entry->lldb_path = HostInfo::GetProgramFileSpec().GetPath();
+
+  llvm::SmallString<64> cwd;
+  if (!llvm::sys::fs::current_path(cwd)) {
+    entry->cwd = cwd.c_str();
+  } else {
+    MiscTelemetryInfo misc_info;
+    misc_info.meta_data["internal_errors"] = "Cannot determine CWD";
+    if (auto er = dispatch(&misc_info)) {
+      LLDB_LOG(GetLog(LLDBLog::Object),
+               "Failed to dispatch misc-info at startup");
+    }
+  }
+
+  if (auto er = dispatch(entry)) {
+    LLDB_LOG(GetLog(LLDBLog::Object), "Failed to dispatch entry at startup");
+  }
+}
+
+void TelemetryManager::AtMainExecutableLoadEnd(TargetInfo *entry) {
+  // ....
+  dispatch(entry);
+}
+
 std::unique_ptr<TelemetryManager> TelemetryManager::g_instance = nullptr;
 TelemetryManager *TelemetryManager::getInstance() { return g_instance.get(); }
 

Copy link

github-actions bot commented Feb 19, 2025

✅ With the latest revision this PR passed the C/C++ code formatter.

@oontvoo oontvoo marked this pull request as ready for review February 24, 2025 21:03
@oontvoo
Copy link
Member Author

oontvoo commented Feb 24, 2025

(This PR assumes that we can rely on PR/128534 - that is, we always build the telemetry library. Whether it is enabled is dictated by Config::EnableTelemetry)

@oontvoo
Copy link
Member Author

oontvoo commented Mar 3, 2025

Hi @labath @JDevlieghere , just FYI that both this PR and PR/129354 have common change (which is modifying the ScopedDispatcher) Feel free to review either of these PR first, but probably easier to not review them at the same time (since you may be repeating the same comment/feedback) .
Thanks!

@labath
Copy link
Collaborator

labath commented Mar 12, 2025

Define "target".

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

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 and later set the executable once you've attached to the running process. 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: 0x00007ffff7fe2bc0 ld-linux-x86-64.so.2`_start
ld-linux-x86-64.so.2`_start:
->  0x7ffff7fe2bc0 <+0>: movq   %rsp, %rdi
    0x7ffff7fe2bc3 <+3>: callq  0x7ffff7fe38c0 ; _dl_start

ld-linux-x86-64.so.2`_dl_start_user:
    0x7ffff7fe2bc8 <+0>: movq   %rax, %r12
    0x7ffff7fe2bcb <+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: 0x00007ffff7fe2bc0 ld-linux-x86-64.so.2`_start
ld-linux-x86-64.so.2`_start:
->  0x7ffff7fe2bc0 <+0>: movq   %rsp, %rdi
    0x7ffff7fe2bc3 <+3>: callq  0x7ffff7fe38c0 ; _dl_start

ld-linux-x86-64.so.2`_dl_start_user:
    0x7ffff7fe2bc8 <+0>: movq   %rax, %r12
    0x7ffff7fe2bcb <+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: 0x00007ffff7fe2bc0 ld-linux-x86-64.so.2`_start
ld-linux-x86-64.so.2`_start:
->  0x7ffff7fe2bc0 <+0>: movq   %rsp, %rdi
    0x7ffff7fe2bc3 <+3>: callq  0x7ffff7fe38c0 ; _dl_start

ld-linux-x86-64.so.2`_dl_start_user:
    0x7ffff7fe2bc8 <+0>: movq   %rax, %r12
    0x7ffff7fe2bcb <+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
  1. 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: 0x00007f337699c1d1 libc.so.6`read + 17
libc.so.6`read:
->  0x7f337699c1d1 <+17>: cmpq   $-0x1000, %rax ; imm = 0xF000 
    0x7f337699c1d7 <+23>: ja     0x7f337699c230 ; <+112>
    0x7f337699c1d9 <+25>: retq   
    0x7f337699c1da <+26>: nopw   (%rax,%rax)
warning: Executable module changed from "/bin/ls" to "/bin/cat".
# And another one here
  1. Bare metal debugging where you don't actually have an image to debug (or you just don't know/have access to that image). It's too fiddly to set up now, but in this case you can have a target (and a process), but no executable image (no SetExecutableModule calls)

Neither of these scenarios is particularly common, so I don't think they'll skew the data if you present them as "creating a target". And in a way they're correct, since in e.g., the execve case, you actually have to reparse all of the debug info for the new image so, in a sense, you are creating a new target. However, I think we should be very explicit in the code about what we are doing.

oontvoo added 2 commits March 12, 2025 13:43
 - Use separate entries for Process and Main Executable module
 - Rename for clarity
@oontvoo
Copy link
Member Author

oontvoo commented Mar 12, 2025

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)

TargetSP target_sp(Debugger::FindTargetWithProcessID(m_pid));
if (target_sp) {
helper.SetDebugger(&(target_sp->GetDebugger()));
exec_uuid = target_sp->GetExecModuleUUID();
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are you sure about that. Modules normally exist long after the process exits:

$ lldb echo
(lldb) target create "echo"
Current executable set to '/bin/echo' (x86_64).
(lldb) r
Process 15996 launched: '/bin/echo' (x86_64)

Process 15996 exited with status = 0 (0x00000000) 
(lldb) image list
[  0] 676F00F7 0x0000555555554000 /bin/echo 
[  1] D626A570 0x00007ffff7fc6000 /lib64/ld-linux-x86-64.so.2 
[  2] 421DCFD2-138A-B321-D6F1-7AFD7B7FC999-F79CA445 0x00007ffff7fc5000 [vdso] (0x00007ffff7fc5000)
[  3] C88DE6C8 0x00007ffff7d99000 /lib64/libc.so.6 
      /usr/lib/debug/lib64/libc.so.6.debug

It's possible this happens in some exceptional exit scenarios, but in that case, I'd like to know what they are. In general, you cannot assume that a target will always have an executable module due to the scenarios I mentioned before.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can't seem to reproduce it now but I was getting a crash (due to accessing the ModuleSP object here), hence the check on the TargetSP and the code to save it.

But anyway, i'll revert that back to the simple case. We can fix the crash if/when it manifest again

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@labath Ah, I've found the test that crashed! (See the build log on this PR). Without the check for the validity of the Target pointer and the module pointer, the test crashed/timedout. By contrast, if we added this check, the whole test suite passed:

  TargetSP target_sp(Debugger::FindTargetWithProcessID(m_pid));
   if (target_sp) {
    helper.SetDebugger(&(target_sp->GetDebugger()));
    if (ModuleSP mod = target_sp->GetExecutableModule())
      module_uuid = mod->GetUUID();
   }

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That sort of makes sense. The target would not be available if it was already being destroyed. However, Debugger::FindTargetWithProcessID is still a very roundabout way to check for target validity. You should be able to achieve the same thing with:

if (TargetSP target_sp = m_target_wp.lock()) {
  ...
}

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, ok - thanks! will apply this in the rollforward patch.

Copy link
Collaborator

@labath labath left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is better, though I'm not particularly fond of the addition of the new Target field. I'd like to see if we could remove that.

TargetSP target_sp(Debugger::FindTargetWithProcessID(m_pid));
if (target_sp) {
helper.SetDebugger(&(target_sp->GetDebugger()));
exec_uuid = target_sp->GetExecModuleUUID();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are you sure about that. Modules normally exist long after the process exits:

$ lldb echo
(lldb) target create "echo"
Current executable set to '/bin/echo' (x86_64).
(lldb) r
Process 15996 launched: '/bin/echo' (x86_64)

Process 15996 exited with status = 0 (0x00000000) 
(lldb) image list
[  0] 676F00F7 0x0000555555554000 /bin/echo 
[  1] D626A570 0x00007ffff7fc6000 /lib64/ld-linux-x86-64.so.2 
[  2] 421DCFD2-138A-B321-D6F1-7AFD7B7FC999-F79CA445 0x00007ffff7fc5000 [vdso] (0x00007ffff7fc5000)
[  3] C88DE6C8 0x00007ffff7d99000 /lib64/libc.so.6 
      /usr/lib/debug/lib64/libc.so.6.debug

It's possible this happens in some exceptional exit scenarios, but in that case, I'd like to know what they are. In general, you cannot assume that a target will always have an executable module due to the scenarios I mentioned before.

Copy link
Collaborator

@labath labath left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is fine now. Time to call in @JDevlieghere :)

@oontvoo
Copy link
Member Author

oontvoo commented Mar 18, 2025

Hi, friendly ping? @JDevlieghere thanks!

Copy link
Member

@JDevlieghere JDevlieghere left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM modulo nits.

Comment on lines 88 to 89
std::string target_uuid;
std::string arch_name;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
std::string target_uuid;
std::string arch_name;
UUID target_uuid;
ArchSpec arch_name;

struct TargetInfo : public LLDBBaseTelemetryInfo {
lldb::ModuleSP exec_mod;

// The same as the executable-module's UUID.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// The same as the executable-module's UUID.
/// The same as the executable-module's UUID.

Comment on lines 91 to 94
// If true, this entry was emitted at the beginning of an event (eg., before
// the executable laod). Otherwise, it was emitted at the end of an event
// (eg., after the module and any dependency were loaded.)
bool is_start_entry;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// If true, this entry was emitted at the beginning of an event (eg., before
// the executable laod). Otherwise, it was emitted at the end of an event
// (eg., after the module and any dependency were loaded.)
bool is_start_entry;
/// If true, this entry was emitted at the beginning of an event (eg., before
/// the executable laod). Otherwise, it was emitted at the end of an event
/// (eg., after the module and any dependency were loaded.)
bool is_start_entry;

// (eg., after the module and any dependency were loaded.)
bool is_start_entry;

// Describes the exit of the executable module.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// Describes the exit of the executable module.
/// Describes the exit of the executable module.

@@ -146,6 +155,59 @@ struct DebuggerInfo : public LLDBBaseTelemetryInfo {
void serialize(llvm::telemetry::Serializer &serializer) const override;
};

struct ExecModuleInfo : public LLDBBaseTelemetryInfo {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
struct ExecModuleInfo : public LLDBBaseTelemetryInfo {
struct ExecutableModuleInfo : public LLDBBaseTelemetryInfo {

}

static bool classof(const TelemetryInfo *T) {
// Subclasses of this is also acceptable
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// Subclasses of this is also acceptable
// Subclasses of this is also acceptable.


/// Describes an exit status.
struct ExitDescription {
int exit_code;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Contrary to my other comments I think we can keep the exit_ prefix here as "exit code" is a fairly well understood term.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

@@ -76,15 +76,36 @@ void CommandInfo::serialize(Serializer &serializer) const {
serializer.write("error_data", error_data.value());
}

std::atomic<uint64_t> CommandInfo::g_command_id_seed = 0;
uint64_t CommandInfo::GetNextId() { return g_command_id_seed.fetch_add(1); }
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
uint64_t CommandInfo::GetNextId() { return g_command_id_seed.fetch_add(1); }
uint64_t CommandInfo::GetNextID() { return g_command_id_seed.fetch_add(1); }

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done


// Find the executable-module's UUID, if available.
Target &target = GetTarget();
helper.SetDebugger(&(target.GetDebugger()));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
helper.SetDebugger(&(target.GetDebugger()));
helper.SetDebugger(&target.GetDebugger());

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

Comment on lines 1568 to 1570
lldb::pid_t pid;
if (ProcessSP proc = GetProcessSP())
pid = proc->GetID();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
lldb::pid_t pid;
if (ProcessSP proc = GetProcessSP())
pid = proc->GetID();
lldb::pid_t pid = LLDB_INVALID_PROCESS_ID;
if (ProcessSP proc = GetProcessSP())
pid = proc->GetID();

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

@oontvoo
Copy link
Member Author

oontvoo commented Mar 19, 2025

Thanks!

@oontvoo oontvoo merged commit 04e39ce into llvm:main Mar 19, 2025
7 of 9 checks passed
@llvm-ci
Copy link
Collaborator

llvm-ci commented Mar 19, 2025

LLVM Buildbot has detected a new failure on builder lldb-x86_64-debian running on lldb-x86_64-debian while building lldb at step 6 "test".

Full details are available at: https://lab.llvm.org/buildbot/#/builders/162/builds/18394

Here is the relevant piece of the build log for the reference
Step 6 (test) failure: build (failure)
...
PASS: lldb-api :: tools/lldb-dap/memory/TestDAP_memory.py (97 of 2798)
PASS: lldb-api :: types/TestLongTypesExpr.py (98 of 2798)
PASS: lldb-api :: types/TestShortTypeExpr.py (99 of 2798)
PASS: lldb-api :: types/TestIntegerTypeExpr.py (100 of 2798)
PASS: lldb-api :: functionalities/return-value/TestReturnValue.py (101 of 2798)
PASS: lldb-api :: functionalities/data-formatter/data-formatter-stl/generic/multiset/TestDataFormatterGenericMultiSet.py (102 of 2798)
PASS: lldb-api :: tools/lldb-dap/console/TestDAP_console.py (103 of 2798)
PASS: lldb-api :: python_api/frame/TestFrames.py (104 of 2798)
PASS: lldb-api :: commands/expression/fixits/TestFixIts.py (105 of 2798)
UNRESOLVED: lldb-api :: functionalities/step-avoids-no-debug/TestStepNoDebug.py (106 of 2798)
******************** TEST 'lldb-api :: functionalities/step-avoids-no-debug/TestStepNoDebug.py' FAILED ********************
Script:
--
/usr/bin/python3 /home/worker/2.0.1/lldb-x86_64-debian/llvm-project/lldb/test/API/dotest.py -u CXXFLAGS -u CFLAGS --env LLVM_LIBS_DIR=/home/worker/2.0.1/lldb-x86_64-debian/build/./lib --env LLVM_INCLUDE_DIR=/home/worker/2.0.1/lldb-x86_64-debian/build/include --env LLVM_TOOLS_DIR=/home/worker/2.0.1/lldb-x86_64-debian/build/./bin --arch x86_64 --build-dir /home/worker/2.0.1/lldb-x86_64-debian/build/lldb-test-build.noindex --lldb-module-cache-dir /home/worker/2.0.1/lldb-x86_64-debian/build/lldb-test-build.noindex/module-cache-lldb/lldb-api --clang-module-cache-dir /home/worker/2.0.1/lldb-x86_64-debian/build/lldb-test-build.noindex/module-cache-clang/lldb-api --executable /home/worker/2.0.1/lldb-x86_64-debian/build/./bin/lldb --compiler /home/worker/2.0.1/lldb-x86_64-debian/build/./bin/clang --dsymutil /home/worker/2.0.1/lldb-x86_64-debian/build/./bin/dsymutil --make /usr/bin/gmake --llvm-tools-dir /home/worker/2.0.1/lldb-x86_64-debian/build/./bin --lldb-obj-root /home/worker/2.0.1/lldb-x86_64-debian/build/tools/lldb --lldb-libs-dir /home/worker/2.0.1/lldb-x86_64-debian/build/./lib -t /home/worker/2.0.1/lldb-x86_64-debian/llvm-project/lldb/test/API/functionalities/step-avoids-no-debug -p TestStepNoDebug.py
--
Exit Code: -6

Command Output (stdout):
--
lldb version 21.0.0git (https://github.com/llvm/llvm-project.git revision 04e39ce3fddaaec41d9c7babcca55133d7e49969)
  clang revision 04e39ce3fddaaec41d9c7babcca55133d7e49969
  llvm revision 04e39ce3fddaaec41d9c7babcca55133d7e49969

--
Command Output (stderr):
--
Change dir to: /home/worker/2.0.1/lldb-x86_64-debian/llvm-project/lldb/test/API/functionalities/step-avoids-no-debug
UNSUPPORTED: LLDB (/home/worker/2.0.1/lldb-x86_64-debian/build/bin/clang-x86_64) :: test_step_in_with_python_dsym (TestStepNoDebug.StepAvoidsNoDebugTestCase.test_step_in_with_python_dsym) (test case does not fall in any category of interest for this run) 
runCmd: settings clear -all

output: 

runCmd: settings set symbols.enable-external-lookup false

output: 

runCmd: settings set target.inherit-tcc true

output: 

runCmd: settings set target.disable-aslr false

output: 

runCmd: settings set target.detach-on-error false

output: 

runCmd: settings set target.auto-apply-fixits false

@llvm-ci
Copy link
Collaborator

llvm-ci commented Mar 19, 2025

LLVM Buildbot has detected a new failure on builder lldb-aarch64-ubuntu running on linaro-lldb-aarch64-ubuntu while building lldb at step 6 "test".

Full details are available at: https://lab.llvm.org/buildbot/#/builders/59/builds/14520

Here is the relevant piece of the build log for the reference
Step 6 (test) failure: build (failure)
...
PASS: lldb-api :: commands/command/delete/TestCommandDelete.py (18 of 2110)
PASS: lldb-api :: commands/command/invalid-args/TestInvalidArgsCommand.py (19 of 2110)
PASS: lldb-api :: commands/command/regex/TestRegexCommand.py (20 of 2110)
PASS: lldb-api :: commands/command/script/add/TestAddParsedCommand.py (21 of 2110)
PASS: lldb-api :: commands/command/nested_alias/TestNestedAlias.py (22 of 2110)
PASS: lldb-api :: commands/command/script/import/TestImport.py (23 of 2110)
PASS: lldb-api :: commands/command/script/import/rdar-12586188/TestRdar12586188.py (24 of 2110)
PASS: lldb-api :: commands/command/script_alias/TestCommandScriptAlias.py (25 of 2110)
PASS: lldb-api :: commands/command/source/TestCommandSource.py (26 of 2110)
UNRESOLVED: lldb-api :: commands/command/backticks/TestBackticksInAlias.py (27 of 2110)
******************** TEST 'lldb-api :: commands/command/backticks/TestBackticksInAlias.py' FAILED ********************
Script:
--
/usr/bin/python3.10 /home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/llvm-project/lldb/test/API/dotest.py -u CXXFLAGS -u CFLAGS --env LLVM_LIBS_DIR=/home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/./lib --env LLVM_INCLUDE_DIR=/home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/include --env LLVM_TOOLS_DIR=/home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/./bin --arch aarch64 --build-dir /home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/lldb-test-build.noindex --lldb-module-cache-dir /home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/lldb-test-build.noindex/module-cache-lldb/lldb-api --clang-module-cache-dir /home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/lldb-test-build.noindex/module-cache-clang/lldb-api --executable /home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/./bin/lldb --compiler /home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/./bin/clang --dsymutil /home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/./bin/dsymutil --make /usr/bin/gmake --llvm-tools-dir /home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/./bin --lldb-obj-root /home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/tools/lldb --lldb-libs-dir /home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/./lib /home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/llvm-project/lldb/test/API/commands/command/backticks -p TestBackticksInAlias.py
--
Exit Code: -6

Command Output (stdout):
--
lldb version 21.0.0git (https://github.com/llvm/llvm-project.git revision 04e39ce3fddaaec41d9c7babcca55133d7e49969)
  clang revision 04e39ce3fddaaec41d9c7babcca55133d7e49969
  llvm revision 04e39ce3fddaaec41d9c7babcca55133d7e49969

--
Command Output (stderr):
--
PASS: LLDB (/home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/bin/clang-aarch64) :: test_backticks_in_alias (TestBackticksInAlias.TestBackticksInAlias)
PASS: LLDB (/home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/bin/clang-aarch64) :: test_backticks_in_parsed_cmd_argument (TestBackticksInAlias.TestBackticksInAlias)
PLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/ and include the crash backtrace.
PASS: LLDB (/home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/bin/clang-aarch64) :: test_backticks_in_parsed_cmd_option (TestBackticksInAlias.TestBackticksInAlias)
 #0 0x0000ffffabf6b740 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) Signals.cpp:0:0
 #1 0x0000ffffabf6976c llvm::sys::RunSignalHandlers() Signals.cpp:0:0
 #2 0x0000ffffabf6be4c SignalHandler(int, siginfo_t*, void*) Signals.cpp:0:0
 #3 0x0000ffffb2f137dc (linux-vdso.so.1+0x7dc)
 #4 0x0000ffffb2c9f1f0 __pthread_kill_implementation ./nptl/./nptl/pthread_kill.c:44:76
 #5 0x0000ffffb2c5a67c gsignal ./signal/../sysdeps/posix/raise.c:27:6
 #6 0x0000ffffb2c47130 abort ./stdlib/./stdlib/abort.c:81:7
 #7 0x0000ffffab596c50 lldb::SBAttachInfo::SBAttachInfo() (/home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/local/lib/python3.10/dist-packages/lldb/_lldb.cpython-310-aarch64-linux-gnu.so+0x54b6c50)
 #8 0x0000ffffab9a91fc lldb_private::Process::SetExitStatus(int, llvm::StringRef) Process.cpp:0:0
 #9 0x0000ffffabd62950 lldb_private::process_gdb_remote::ProcessGDBRemote::MonitorDebugserverProcess(std::weak_ptr<lldb_private::process_gdb_remote::ProcessGDBRemote>, unsigned long, int, int) ProcessGDBRemote.cpp:0:0
#10 0x0000ffffabd73bfc std::_Function_handler<void (unsigned long, int, int), std::_Bind<void (* (std::weak_ptr<lldb_private::process_gdb_remote::ProcessGDBRemote>, std::_Placeholder<1>, std::_Placeholder<2>, std::_Placeholder<3>))(std::weak_ptr<lldb_private::process_gdb_remote::ProcessGDBRemote>, unsigned long, int, int)> >::_M_invoke(std::_Any_data const&, unsigned long&&, int&&, int&&) ProcessGDBRemote.cpp:0:0
#11 0x0000ffffab8973c0 std::_Function_handler<void* (), lldb_private::Host::StartMonitoringChildProcess(std::function<void (unsigned long, int, int)> const&, unsigned long)::$_0>::_M_invoke(std::_Any_data const&) Host.cpp:0:0
#12 0x0000ffffab899c98 lldb_private::HostNativeThreadBase::ThreadCreateTrampoline(void*) HostNativeThreadBase.cpp:0:0
#13 0x0000ffffb2c9d5b8 start_thread ./nptl/./nptl/pthread_create.c:442:8
#14 0x0000ffffb2d05edc ./misc/../sysdeps/unix/sysv/linux/aarch64/clone.S:82:0

--

********************

@llvm-ci
Copy link
Collaborator

llvm-ci commented Mar 19, 2025

LLVM Buildbot has detected a new failure on builder lldb-arm-ubuntu running on linaro-lldb-arm-ubuntu while building lldb at step 6 "test".

Full details are available at: https://lab.llvm.org/buildbot/#/builders/18/builds/13132

Here is the relevant piece of the build log for the reference
Step 6 (test) failure: build (failure)
...
UNSUPPORTED: lldb-api :: functionalities/data-formatter/data-formatter-stl/libcxx/unique_ptr/TestDataFormatterLibcxxUniquePtr.py (390 of 2925)
UNSUPPORTED: lldb-api :: functionalities/data-formatter/data-formatter-stl/libcxx/unordered_map/TestDataFormatterLibccUnorderedMap.py (391 of 2925)
UNSUPPORTED: lldb-api :: functionalities/data-formatter/data-formatter-stl/libcxx/valarray/TestDataFormatterLibcxxValarray.py (392 of 2925)
UNSUPPORTED: lldb-api :: functionalities/data-formatter/data-formatter-stl/libcxx/variant/TestDataFormatterLibcxxVariant.py (393 of 2925)
UNSUPPORTED: lldb-api :: functionalities/data-formatter/data-formatter-stl/libcxx/vbool/TestDataFormatterLibcxxVBool.py (394 of 2925)
UNSUPPORTED: lldb-api :: functionalities/data-formatter/data-formatter-stl/libcxx/vector/TestDataFormatterLibcxxVector.py (395 of 2925)
PASS: lldb-api :: functionalities/data-formatter/data-formatter-stl/libstdcpp/smart_ptr/TestDataFormatterStdSmartPtr.py (396 of 2925)
PASS: lldb-api :: functionalities/data-formatter/data-formatter-stl/libstdcpp/iterator/TestDataFormatterStdIterator.py (397 of 2925)
PASS: lldb-api :: functionalities/data-formatter/data-formatter-stl/libstdcpp/map/TestDataFormatterStdMap.py (398 of 2925)
UNRESOLVED: lldb-api :: functionalities/data-formatter/data-formatter-stl/libcxx-simulators/string/TestDataFormatterLibcxxStringSimulator.py (399 of 2925)
******************** TEST 'lldb-api :: functionalities/data-formatter/data-formatter-stl/libcxx-simulators/string/TestDataFormatterLibcxxStringSimulator.py' FAILED ********************
Script:
--
/usr/bin/python3.10 /home/tcwg-buildbot/worker/lldb-arm-ubuntu/llvm-project/lldb/test/API/dotest.py -u CXXFLAGS -u CFLAGS --env LLVM_LIBS_DIR=/home/tcwg-buildbot/worker/lldb-arm-ubuntu/build/./lib --env LLVM_INCLUDE_DIR=/home/tcwg-buildbot/worker/lldb-arm-ubuntu/build/include --env LLVM_TOOLS_DIR=/home/tcwg-buildbot/worker/lldb-arm-ubuntu/build/./bin --arch armv8l --build-dir /home/tcwg-buildbot/worker/lldb-arm-ubuntu/build/lldb-test-build.noindex --lldb-module-cache-dir /home/tcwg-buildbot/worker/lldb-arm-ubuntu/build/lldb-test-build.noindex/module-cache-lldb/lldb-api --clang-module-cache-dir /home/tcwg-buildbot/worker/lldb-arm-ubuntu/build/lldb-test-build.noindex/module-cache-clang/lldb-api --executable /home/tcwg-buildbot/worker/lldb-arm-ubuntu/build/./bin/lldb --compiler /home/tcwg-buildbot/worker/lldb-arm-ubuntu/build/./bin/clang --dsymutil /home/tcwg-buildbot/worker/lldb-arm-ubuntu/build/./bin/dsymutil --make /usr/bin/gmake --llvm-tools-dir /home/tcwg-buildbot/worker/lldb-arm-ubuntu/build/./bin --lldb-obj-root /home/tcwg-buildbot/worker/lldb-arm-ubuntu/build/tools/lldb --lldb-libs-dir /home/tcwg-buildbot/worker/lldb-arm-ubuntu/build/./lib /home/tcwg-buildbot/worker/lldb-arm-ubuntu/llvm-project/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx-simulators/string -p TestDataFormatterLibcxxStringSimulator.py
--
Exit Code: -6

Command Output (stdout):
--
lldb version 21.0.0git (https://github.com/llvm/llvm-project.git revision 04e39ce3fddaaec41d9c7babcca55133d7e49969)
  clang revision 04e39ce3fddaaec41d9c7babcca55133d7e49969
  llvm revision 04e39ce3fddaaec41d9c7babcca55133d7e49969

--
Command Output (stderr):
--
PASS: LLDB (/home/tcwg-buildbot/worker/lldb-arm-ubuntu/build/bin/clang-arm) :: test_r0_c0 (TestDataFormatterLibcxxStringSimulator.LibcxxStringDataFormatterSimulatorTestCase)
PASS: LLDB (/home/tcwg-buildbot/worker/lldb-arm-ubuntu/build/bin/clang-arm) :: test_r0_c0_ALTERNATE_LAYOUT (TestDataFormatterLibcxxStringSimulator.LibcxxStringDataFormatterSimulatorTestCase)
PASS: LLDB (/home/tcwg-buildbot/worker/lldb-arm-ubuntu/build/bin/clang-arm) :: test_r0_c1 (TestDataFormatterLibcxxStringSimulator.LibcxxStringDataFormatterSimulatorTestCase)
PASS: LLDB (/home/tcwg-buildbot/worker/lldb-arm-ubuntu/build/bin/clang-arm) :: test_r0_c1_ALTERNATE_LAYOUT (TestDataFormatterLibcxxStringSimulator.LibcxxStringDataFormatterSimulatorTestCase)
PASS: LLDB (/home/tcwg-buildbot/worker/lldb-arm-ubuntu/build/bin/clang-arm) :: test_r0_c2 (TestDataFormatterLibcxxStringSimulator.LibcxxStringDataFormatterSimulatorTestCase)
PASS: LLDB (/home/tcwg-buildbot/worker/lldb-arm-ubuntu/build/bin/clang-arm) :: test_r0_c2_ALTERNATE_LAYOUT (TestDataFormatterLibcxxStringSimulator.LibcxxStringDataFormatterSimulatorTestCase)
PASS: LLDB (/home/tcwg-buildbot/worker/lldb-arm-ubuntu/build/bin/clang-arm) :: test_r1_c0 (TestDataFormatterLibcxxStringSimulator.LibcxxStringDataFormatterSimulatorTestCase)
PASS: LLDB (/home/tcwg-buildbot/worker/lldb-arm-ubuntu/build/bin/clang-arm) :: test_r1_c0_ALTERNATE_LAYOUT (TestDataFormatterLibcxxStringSimulator.LibcxxStringDataFormatterSimulatorTestCase)
PASS: LLDB (/home/tcwg-buildbot/worker/lldb-arm-ubuntu/build/bin/clang-arm) :: test_r1_c1 (TestDataFormatterLibcxxStringSimulator.LibcxxStringDataFormatterSimulatorTestCase)
PASS: LLDB (/home/tcwg-buildbot/worker/lldb-arm-ubuntu/build/bin/clang-arm) :: test_r1_c1_ALTERNATE_LAYOUT (TestDataFormatterLibcxxStringSimulator.LibcxxStringDataFormatterSimulatorTestCase)
PLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/ and include the crash backtrace.
PASS: LLDB (/home/tcwg-buildbot/worker/lldb-arm-ubuntu/build/bin/clang-arm) :: test_r1_c2 (TestDataFormatterLibcxxStringSimulator.LibcxxStringDataFormatterSimulatorTestCase)
#0 0xf128f2c0 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) Signals.cpp:0:0
#1 0xf128ccf8 llvm::sys::RunSignalHandlers() Signals.cpp:0:0
#2 0xf128fb44 SignalHandler(int, siginfo_t*, void*) Signals.cpp:0:0
#3 0xf7acd6f0 __default_rt_sa_restorer ./signal/../sysdeps/unix/sysv/linux/arm/sigrestorer.S:80:0
#4 0xf7abdb06 ./csu/../sysdeps/unix/sysv/linux/arm/libc-do-syscall.S:47:0
#5 0xf7afd292 __pthread_kill_implementation ./nptl/pthread_kill.c:44:76
#6 0xf7acc840 gsignal ./signal/../sysdeps/posix/raise.c:27:6

--

********************

labath added a commit that referenced this pull request Mar 19, 2025
…a target (#127834)"

This reverts commit 04e39ce due to test
breakage.
oontvoo added a commit to oontvoo/llvm-project that referenced this pull request Mar 19, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants