mib updated this revision to Diff 500317.
mib retitled this revision from "[lldb] Fix watchpoint command function 
stopping behavior" to "[lldb] Fix {break,watch}point command function stopping 
behavior".
mib edited the summary of this revision.
mib added a comment.

Address @jingham & @delcypher feedbacks.


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

https://reviews.llvm.org/D144688

Files:
  lldb/source/Commands/CommandObjectWatchpointCommand.cpp
  lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp
  
lldb/test/API/commands/watchpoints/watchpoint_commands/command/TestWatchpointCommandPython.py
  lldb/test/API/commands/watchpoints/watchpoint_commands/command/main.cpp
  
lldb/test/API/commands/watchpoints/watchpoint_commands/command/watchpoint_command.py

Index: lldb/test/API/commands/watchpoints/watchpoint_commands/command/watchpoint_command.py
===================================================================
--- lldb/test/API/commands/watchpoints/watchpoint_commands/command/watchpoint_command.py
+++ lldb/test/API/commands/watchpoints/watchpoint_commands/command/watchpoint_command.py
@@ -9,7 +9,12 @@
         print ("I stopped the first time")
         frame.EvaluateExpression("cookie = 888")
         num_hits += 1
-        frame.thread.process.Continue()
+        return True
+    if num_hits == 1:
+        print ("I stopped the second time, but with no return")
+        frame.EvaluateExpression("cookie = 666")
+        num_hits += 1
     else:
         print ("I stopped the %d time" % (num_hits))
         frame.EvaluateExpression("cookie = 999")
+        return False # This cause the process to continue.
Index: lldb/test/API/commands/watchpoints/watchpoint_commands/command/main.cpp
===================================================================
--- lldb/test/API/commands/watchpoints/watchpoint_commands/command/main.cpp
+++ lldb/test/API/commands/watchpoints/watchpoint_commands/command/main.cpp
@@ -16,5 +16,5 @@
         modify(global);
 
     printf("global=%d\n", global);
-    printf("cookie=%d\n", cookie);
+    printf("cookie=%d\n", cookie); // Set another breakpoint here.
 }
Index: lldb/test/API/commands/watchpoints/watchpoint_commands/command/TestWatchpointCommandPython.py
===================================================================
--- lldb/test/API/commands/watchpoints/watchpoint_commands/command/TestWatchpointCommandPython.py
+++ lldb/test/API/commands/watchpoints/watchpoint_commands/command/TestWatchpointCommandPython.py
@@ -1,4 +1,4 @@
-"""
+"""
 Test 'watchpoint command'.
 """
 
@@ -22,6 +22,8 @@
         # Find the line number to break inside main().
         self.line = line_number(
             self.source, '// Set break point at this line.')
+        self.second_line = line_number(
+            self.source, '// Set another breakpoint here.')
         # And the watchpoint variable declaration line number.
         self.decl = line_number(self.source,
                                 '// Watchpoint variable declaration.')
@@ -143,6 +145,32 @@
         self.expect("thread backtrace", STOPPED_DUE_TO_WATCHPOINT,
                     substrs=['stop reason = watchpoint'])
 
+        # We should have hit the watchpoint once, set cookie to 888, since the
+        # user callback returned True.
+        self.expect("frame variable --show-globals cookie",
+                    substrs=['(int32_t)', 'cookie = 888'])
+
+        self.runCmd("process continue")
+
+        # We should be stopped again due to the watchpoint (write type).
+        # The stop reason of the thread should be watchpoint.
+        self.expect("thread backtrace", STOPPED_DUE_TO_WATCHPOINT,
+                    substrs=['stop reason = watchpoint'])
+
+        # We should have hit the watchpoint a second time, set cookie to 666,
+        # even if the user callback didn't return anything and then continue.
+        self.expect("frame variable --show-globals cookie",
+                    substrs=['(int32_t)', 'cookie = 666'])
+
+        # Add a breakpoint to set a watchpoint when stopped on the breakpoint.
+        lldbutil.run_break_set_by_file_and_line(
+            self, None, self.second_line, num_expected_locations=1)
+
+        self.runCmd("process continue")
+
+        self.expect("thread backtrace", STOPPED_DUE_TO_BREAKPOINT,
+                    substrs=['stop reason = breakpoint'])
+
         # We should have hit the watchpoint once, set cookie to 888, then continued to the
         # second hit and set it to 999
         self.expect("frame variable --show-globals cookie",
Index: lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp
===================================================================
--- lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp
+++ lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp
@@ -1292,40 +1292,52 @@
   StringList auto_generated_function;
   auto_generated_function.AppendString(signature);
   auto_generated_function.AppendString(
-      "     global_dict = globals()"); // Grab the global dictionary
+      "    global_dict = globals()"); // Grab the global dictionary
   auto_generated_function.AppendString(
-      "     new_keys = internal_dict.keys()"); // Make a list of keys in the
-                                               // session dict
+      "    new_keys = internal_dict.keys()"); // Make a list of keys in the
+                                              // session dict
   auto_generated_function.AppendString(
-      "     old_keys = global_dict.keys()"); // Save list of keys in global dict
+      "    old_keys = global_dict.keys()"); // Save list of keys in global dict
   auto_generated_function.AppendString(
-      "     global_dict.update (internal_dict)"); // Add the session dictionary
-                                                  // to the
-  // global dictionary.
+      "    global_dict.update (internal_dict)"); // Add the session dictionary
+                                                 // to the global dictionary.
+  auto_generated_function.AppendString(
+      "    __return_val = None"); // Initialize user callback return value.
 
   // Wrap everything up inside the function, increasing the indentation.
 
-  auto_generated_function.AppendString("     if True:");
+  auto_generated_function.AppendString("    def __user_callback():");
+  auto_generated_function.AppendString("      nonlocal __return_val");
   for (int i = 0; i < num_lines; ++i) {
     sstr.Clear();
-    sstr.Printf("       %s", input.GetStringAtIndex(i));
+    llvm::StringRef line = input.GetStringAtIndex(i);
+    if (line.startswith("return ")) {
+      llvm::StringRef return_val =
+          line.substr(llvm::StringRef("return ").size());
+      sstr.Printf("      __return_val = %s", return_val.data());
+    } else {
+      sstr.Printf("      %s", line.data());
+    }
     auto_generated_function.AppendString(sstr.GetData());
   }
   auto_generated_function.AppendString(
-      "     for key in new_keys:"); // Iterate over all the keys from session
-                                    // dict
+      "    __user_callback()"); //  Call user callback
   auto_generated_function.AppendString(
-      "         internal_dict[key] = global_dict[key]"); // Update session dict
-                                                         // values
+      "    for key in new_keys:"); // Iterate over all the keys from session
+                                   // dict
   auto_generated_function.AppendString(
-      "         if key not in old_keys:"); // If key was not originally in
-                                           // global dict
+      "        internal_dict[key] = global_dict[key]"); // Update session dict
+                                                        // values
   auto_generated_function.AppendString(
-      "             del global_dict[key]"); //  ...then remove key/value from
-                                            //  global dict
+      "        if key not in old_keys:"); // If key was not originally in
+                                          // global dict
+  auto_generated_function.AppendString(
+      "            del global_dict[key]"); //  ...then remove key/value from
+                                           //  global dict
+  auto_generated_function.AppendString(
+      "    return __return_val"); //  Return the user callback return value.
 
   // Verify that the results are valid Python.
-
   error = ExportFunctionDefinitionToInterpreter(auto_generated_function);
 
   return error;
Index: lldb/source/Commands/CommandObjectWatchpointCommand.cpp
===================================================================
--- lldb/source/Commands/CommandObjectWatchpointCommand.cpp
+++ lldb/source/Commands/CommandObjectWatchpointCommand.cpp
@@ -422,7 +422,8 @@
           // automatize what the user would do manually: make their watchpoint
           // command be a function call
           else if (!m_options.m_function_name.empty()) {
-            std::string oneliner(m_options.m_function_name);
+            std::string oneliner("return ");
+            oneliner += m_options.m_function_name;
             oneliner += "(frame, wp, internal_dict)";
             script_interp->SetWatchpointCommandCallback(
                 wp_options, oneliner.c_str());
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
  • [Lldb-commits] [PATCH]... Med Ismail Bennani via Phabricator via lldb-commits

Reply via email to