[Lldb-commits] [lldb] c997acb - [lldb] Add support for specifying language when setting watchpoint by expression

Alex Langford via lldb-commits lldb-commits at lists.llvm.org
Wed Apr 26 10:24:39 PDT 2023


Author: Alex Langford
Date: 2023-04-26T10:24:28-07:00
New Revision: c997acb97a9b15468d991116c28bb003afecb07c

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

LOG: [lldb] Add support for specifying language when setting watchpoint by expression

This is useful in contexts where you have multiple languages in play:
You may be stopped in a frame for language A, but want to set a watchpoint
with an expression using language B. The current way to do this is to
use the setting `target.language` while setting the watchpoint and
unset it after the watchpoint is set, but that's kind of clunky and
somewhat error-prone. This should add a better way to do this.

rdar://108202559

Differential Revision: https://reviews.llvm.org/D149111

Added: 
    lldb/test/Shell/Watchpoint/ExpressionLanguage.test
    lldb/test/Shell/Watchpoint/Inputs/languages.cpp

Modified: 
    lldb/include/lldb/Interpreter/OptionGroupWatchpoint.h
    lldb/source/Commands/CommandObjectWatchpoint.cpp
    lldb/source/Interpreter/OptionGroupWatchpoint.cpp

Removed: 
    


################################################################################
diff  --git a/lldb/include/lldb/Interpreter/OptionGroupWatchpoint.h b/lldb/include/lldb/Interpreter/OptionGroupWatchpoint.h
index 33818043cf63f..201ab1d134f25 100644
--- a/lldb/include/lldb/Interpreter/OptionGroupWatchpoint.h
+++ b/lldb/include/lldb/Interpreter/OptionGroupWatchpoint.h
@@ -43,6 +43,7 @@ class OptionGroupWatchpoint : public OptionGroup {
   WatchType watch_type;
   uint32_t watch_size;
   bool watch_type_specified;
+  lldb::LanguageType language_type;
 
 private:
   OptionGroupWatchpoint(const OptionGroupWatchpoint &) = delete;

diff  --git a/lldb/source/Commands/CommandObjectWatchpoint.cpp b/lldb/source/Commands/CommandObjectWatchpoint.cpp
index 8b8c196e4505b..14180f9b56d36 100644
--- a/lldb/source/Commands/CommandObjectWatchpoint.cpp
+++ b/lldb/source/Commands/CommandObjectWatchpoint.cpp
@@ -835,8 +835,7 @@ corresponding to the byte size of the data type.");
     m_arguments.push_back(arg);
 
     // Absorb the '-w' and '-s' options into our option group.
-    m_option_group.Append(&m_option_watchpoint, LLDB_OPT_SET_ALL,
-                          LLDB_OPT_SET_1);
+    m_option_group.Append(&m_option_watchpoint, LLDB_OPT_SET_1, LLDB_OPT_SET_1);
     m_option_group.Finalize();
   }
 
@@ -990,6 +989,7 @@ class CommandObjectWatchpointSetExpression : public CommandObjectRaw {
       : CommandObjectRaw(
             interpreter, "watchpoint set expression",
             "Set a watchpoint on an address by supplying an expression. "
+            "Use the '-l' option to specify the language of the expression. "
             "Use the '-w' option to specify the type of watchpoint and "
             "the '-s' option to specify the byte size to watch for. "
             "If no '-w' option is specified, it defaults to write. "
@@ -1083,6 +1083,8 @@ class CommandObjectWatchpointSetExpression : public CommandObjectRaw {
     options.SetKeepInMemory(false);
     options.SetTryAllThreads(true);
     options.SetTimeout(std::nullopt);
+    if (m_option_watchpoint.language_type != eLanguageTypeUnknown)
+      options.SetLanguage(m_option_watchpoint.language_type);
 
     ExpressionResults expr_result =
         target->EvaluateExpression(expr, frame, valobj_sp, options);

diff  --git a/lldb/source/Interpreter/OptionGroupWatchpoint.cpp b/lldb/source/Interpreter/OptionGroupWatchpoint.cpp
index 5559e82d47224..c2f78d8c2dd14 100644
--- a/lldb/source/Interpreter/OptionGroupWatchpoint.cpp
+++ b/lldb/source/Interpreter/OptionGroupWatchpoint.cpp
@@ -10,6 +10,7 @@
 
 #include "lldb/Host/OptionParser.h"
 #include "lldb/Interpreter/OptionArgParser.h"
+#include "lldb/Target/Language.h"
 #include "lldb/lldb-enumerations.h"
 
 using namespace lldb;
@@ -62,7 +63,17 @@ static constexpr OptionDefinition g_option_table[] = {
      "Specify the type of watching to perform."},
     {LLDB_OPT_SET_1, false, "size", 's', OptionParser::eRequiredArgument,
      nullptr, OptionEnumValues(g_watch_size), 0, eArgTypeByteSize,
-     "Number of bytes to use to watch a region."}};
+     "Number of bytes to use to watch a region."},
+    {LLDB_OPT_SET_2,
+     false,
+     "language",
+     'l',
+     OptionParser::eRequiredArgument,
+     nullptr,
+     {},
+     0,
+     eArgTypeLanguage,
+     "Language of expression to run"}};
 
 bool OptionGroupWatchpoint::IsWatchSizeSupported(uint32_t watch_size) {
   for (const auto& size : g_watch_size) {
@@ -81,6 +92,18 @@ OptionGroupWatchpoint::SetOptionValue(uint32_t option_idx,
   Status error;
   const int short_option = g_option_table[option_idx].short_option;
   switch (short_option) {
+  case 'l': {
+    language_type = Language::GetLanguageTypeFromString(option_arg);
+    if (language_type == eLanguageTypeUnknown) {
+      StreamString sstr;
+      sstr.Printf("Unknown language type: '%s' for expression. List of "
+                  "supported languages:\n",
+                  option_arg.str().c_str());
+      Language::PrintSupportedLanguagesForExpressions(sstr, " ", "\n");
+      error.SetErrorString(sstr.GetString());
+    }
+    break;
+  }
   case 'w': {
     WatchType tmp_watch_type;
     tmp_watch_type = (WatchType)OptionArgParser::ToOptionEnum(
@@ -108,6 +131,7 @@ void OptionGroupWatchpoint::OptionParsingStarting(
   watch_type_specified = false;
   watch_type = eWatchInvalid;
   watch_size = 0;
+  language_type = eLanguageTypeUnknown;
 }
 
 llvm::ArrayRef<OptionDefinition> OptionGroupWatchpoint::GetDefinitions() {

diff  --git a/lldb/test/Shell/Watchpoint/ExpressionLanguage.test b/lldb/test/Shell/Watchpoint/ExpressionLanguage.test
new file mode 100644
index 0000000000000..be4dca8f64a45
--- /dev/null
+++ b/lldb/test/Shell/Watchpoint/ExpressionLanguage.test
@@ -0,0 +1,19 @@
+# RUN: %clangxx_host %p/Inputs/languages.cpp -g -o %t.out
+# RUN: %lldb -b -o 'settings set interpreter.stop-command-source-on-error false' -s %s %t.out 2>&1 | FileCheck %s
+
+settings  show interpreter.stop-command-source-on-error
+# CHECK: interpreter.stop-command-source-on-error (boolean) = false
+
+b main
+run
+# CHECK: stopped
+# CHECK-NEXT: stop reason = breakpoint
+
+watchpoint set expression -- &g_foo
+# CHECK: Watchpoint created:
+
+watchpoint set expression -l c++ -- &g_bar
+# CHECK: Watchpoint created:
+
+watchpoint set expression -l fake -- &g_baz
+# CHECK: Unknown language type: 'fake' for expression. List of supported languages:

diff  --git a/lldb/test/Shell/Watchpoint/Inputs/languages.cpp b/lldb/test/Shell/Watchpoint/Inputs/languages.cpp
new file mode 100644
index 0000000000000..98b653f3d404a
--- /dev/null
+++ b/lldb/test/Shell/Watchpoint/Inputs/languages.cpp
@@ -0,0 +1,12 @@
+#include <cstdint>
+#include <iostream>
+
+uint64_t g_foo = 5;
+uint64_t g_bar = 6;
+uint64_t g_baz = 7;
+
+int main() {
+  int val = 8;
+  printf("Hello world! %d\n", val);
+  return 0;
+}


        


More information about the lldb-commits mailing list