https://github.com/gmondada created 
https://github.com/llvm/llvm-project/pull/173848

This commit fixes the following problem:

When debugging an APK running on Android, and the Android process stops due to 
a user breakpoint, sometimes a second breakpoint is hit at the same time, and 
the corresponding thread is marked as stopped for reason `jit-debug-register`.

This second breakpoint is used by lldb internally, to track code generated by 
the JIT compiler (JVM).

Instead of displaying the code corresponding to the user breakpoint, the 
debugger displays the disassembled code corresponding to this internal 
breakpoint.

Probably, similar problems appears in other contextes.

Solution:

Internal breakpoints must stay internal, not visible by VS Code or any other 
DAP-based debugger.

Notes:

* This is part on an effort to get lldb working for debugging Swift on Android: 
https://github.com/swiftlang/llvm-project/issues/10831
* Reproducing the problems is not simple because you need an environment 
allowing to run lldb-server in the Android emulator. See 
https://github.com/gmondada/swift-on-android/blob/main/Docs/exploring-apk-debugging.md

>From e0b41065989cb04e64543960a8c597a0212f952b Mon Sep 17 00:00:00 2001
From: Gabriele Mondada <[email protected]>
Date: Sun, 28 Dec 2025 20:46:34 +0100
Subject: [PATCH] [lldb-dap] Do not expose internal breakpoints to DAP clients

This commit fixes the following problem seen on Android:
When the process stops due to a user breakpoint, sometimes a second breakpoint 
is hit at the same time, and the corresponding thread is marked as stopped for 
reason `jit-debug-register`. This second breakpoint is used by lldb internally, 
to track code generated by the JIT compiler (JVM). Instead of displaying the 
code corresponding to the user breakpoint, the debugger displays the 
disassembled code corresponding to this internal breakpoint.
---
 lldb/tools/lldb-dap/LLDBUtils.cpp | 14 +++++++++++++-
 1 file changed, 13 insertions(+), 1 deletion(-)

diff --git a/lldb/tools/lldb-dap/LLDBUtils.cpp 
b/lldb/tools/lldb-dap/LLDBUtils.cpp
index 22e4012b238ac..e4b399b3f341f 100644
--- a/lldb/tools/lldb-dap/LLDBUtils.cpp
+++ b/lldb/tools/lldb-dap/LLDBUtils.cpp
@@ -16,6 +16,7 @@
 #include "lldb/API/SBStringList.h"
 #include "lldb/API/SBStructuredData.h"
 #include "lldb/API/SBThread.h"
+#include "lldb/lldb-defines.h"
 #include "lldb/lldb-enumerations.h"
 #include "llvm/ADT/ArrayRef.h"
 #include "llvm/Support/Error.h"
@@ -129,7 +130,6 @@ bool ThreadHasStopReason(lldb::SBThread &thread) {
   switch (thread.GetStopReason()) {
   case lldb::eStopReasonTrace:
   case lldb::eStopReasonPlanComplete:
-  case lldb::eStopReasonBreakpoint:
   case lldb::eStopReasonWatchpoint:
   case lldb::eStopReasonInstrumentation:
   case lldb::eStopReasonSignal:
@@ -142,6 +142,18 @@ bool ThreadHasStopReason(lldb::SBThread &thread) {
   case lldb::eStopReasonInterrupt:
   case lldb::eStopReasonHistoryBoundary:
     return true;
+  case lldb::eStopReasonBreakpoint: {
+    // Internal breakpoints must not be considered as valid stop reason.
+    uint64_t data_count = thread.GetStopReasonDataCount();
+    if (data_count == 0)
+      return true;
+    for (uint64_t i = 0; i < data_count; i += 2) {
+      lldb::break_id_t bp_id = thread.GetStopReasonDataAtIndex(i);
+      if (!LLDB_BREAK_ID_IS_INTERNAL(bp_id))
+        return true;
+    }
+    return false;
+  }
   case lldb::eStopReasonThreadExiting:
   case lldb::eStopReasonInvalid:
   case lldb::eStopReasonNone:

_______________________________________________
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to