This revision was automatically updated to reflect the committed changes.
Closed by commit rG1bf6f55911ca: [lldb-vscode] Adding support for displaying 
backtraces. (authored by ashgti, committed by dgoldman).

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D156465/new/

https://reviews.llvm.org/D156465

Files:
  lldb/tools/lldb-vscode/JSONUtils.cpp
  lldb/tools/lldb-vscode/lldb-vscode.cpp

Index: lldb/tools/lldb-vscode/lldb-vscode.cpp
===================================================================
--- lldb/tools/lldb-vscode/lldb-vscode.cpp
+++ lldb/tools/lldb-vscode/lldb-vscode.cpp
@@ -2687,13 +2687,72 @@
     const auto startFrame = GetUnsigned(arguments, "startFrame", 0);
     const auto levels = GetUnsigned(arguments, "levels", 0);
     const auto endFrame = (levels == 0) ? INT64_MAX : (startFrame + levels);
+    auto totalFrames = thread.GetNumFrames();
+
+    // This will always return an invalid thread when
+    // libBacktraceRecording.dylib is not loaded or if there is no extended
+    // backtrace.
+    lldb::SBThread queue_backtrace_thread =
+        thread.GetExtendedBacktraceThread("libdispatch");
+    if (queue_backtrace_thread.IsValid()) {
+      // One extra frame as a label to mark the enqueued thread.
+      totalFrames += queue_backtrace_thread.GetNumFrames() + 1;
+    }
+
+    // This will always return an invalid thread when there is no exception in
+    // the current thread.
+    lldb::SBThread exception_backtrace_thread =
+        thread.GetCurrentExceptionBacktrace();
+    if (exception_backtrace_thread.IsValid()) {
+      // One extra frame as a label to mark the exception thread.
+      totalFrames += exception_backtrace_thread.GetNumFrames() + 1;
+    }
+
     for (uint32_t i = startFrame; i < endFrame; ++i) {
-      auto frame = thread.GetFrameAtIndex(i);
+      lldb::SBFrame frame;
+      std::string prefix;
+      if (i < thread.GetNumFrames()) {
+        frame = thread.GetFrameAtIndex(i);
+      } else if (queue_backtrace_thread.IsValid() &&
+                 i < (thread.GetNumFrames() +
+                      queue_backtrace_thread.GetNumFrames() + 1)) {
+        if (i == thread.GetNumFrames()) {
+          const uint32_t thread_idx =
+              queue_backtrace_thread.GetExtendedBacktraceOriginatingIndexID();
+          const char *queue_name = queue_backtrace_thread.GetQueueName();
+          auto name = llvm::formatv("Enqueued from {0} (Thread {1})",
+                                    queue_name, thread_idx);
+          stackFrames.emplace_back(
+              llvm::json::Object{{"id", thread.GetThreadID() + 1},
+                                 {"name", name},
+                                 {"presentationHint", "label"}});
+          continue;
+        }
+        frame = queue_backtrace_thread.GetFrameAtIndex(
+            i - thread.GetNumFrames() - 1);
+      } else if (exception_backtrace_thread.IsValid()) {
+        if (i == thread.GetNumFrames() +
+                     (queue_backtrace_thread.IsValid()
+                          ? queue_backtrace_thread.GetNumFrames() + 1
+                          : 0)) {
+          stackFrames.emplace_back(
+              llvm::json::Object{{"id", thread.GetThreadID() + 2},
+                                 {"name", "Original Exception Backtrace"},
+                                 {"presentationHint", "label"}});
+          continue;
+        }
+
+        frame = exception_backtrace_thread.GetFrameAtIndex(
+            i - thread.GetNumFrames() -
+            (queue_backtrace_thread.IsValid()
+                 ? queue_backtrace_thread.GetNumFrames() + 1
+                 : 0));
+      }
       if (!frame.IsValid())
         break;
       stackFrames.emplace_back(CreateStackFrame(frame));
     }
-    const auto totalFrames = thread.GetNumFrames();
+
     body.try_emplace("totalFrames", totalFrames);
   }
   body.try_emplace("stackFrames", std::move(stackFrames));
Index: lldb/tools/lldb-vscode/JSONUtils.cpp
===================================================================
--- lldb/tools/lldb-vscode/JSONUtils.cpp
+++ lldb/tools/lldb-vscode/JSONUtils.cpp
@@ -815,17 +815,30 @@
 llvm::json::Value CreateThread(lldb::SBThread &thread) {
   llvm::json::Object object;
   object.try_emplace("id", (int64_t)thread.GetThreadID());
-  char thread_str[64];
-  snprintf(thread_str, sizeof(thread_str), "Thread #%u", thread.GetIndexID());
-  const char *name = thread.GetName();
-  if (name) {
-    std::string thread_with_name(thread_str);
-    thread_with_name += ' ';
-    thread_with_name += name;
-    EmplaceSafeString(object, "name", thread_with_name);
+  const char *thread_name = thread.GetName();
+  const char *queue_name = thread.GetQueueName();
+
+  std::string thread_str;
+  if (thread_name) {
+    thread_str = std::string(thread_name);
+  } else if (queue_name) {
+    auto kind = thread.GetQueue().GetKind();
+    std::string queue_kind_label = "";
+    if (kind == lldb::eQueueKindSerial) {
+      queue_kind_label = " (serial)";
+    } else if (kind == lldb::eQueueKindConcurrent) {
+      queue_kind_label = " (concurrent)";
+    }
+
+    thread_str = llvm::formatv("Thread {0} Queue: {1}{2}", thread.GetIndexID(),
+                               queue_name, queue_kind_label)
+                     .str();
   } else {
-    EmplaceSafeString(object, "name", std::string(thread_str));
+    thread_str = llvm::formatv("Thread {0}", thread.GetIndexID()).str();
   }
+
+  EmplaceSafeString(object, "name", thread_str);
+
   return llvm::json::Value(std::move(object));
 }
 
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to