[Lldb-commits] [PATCH] D93874: [process] fix exec support on Linux

2020-12-28 Thread walter erquinigo via Phabricator via lldb-commits
wallace updated this revision to Diff 313904.
wallace added a comment.

improve test


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D93874

Files:
  lldb/include/lldb/Target/Process.h
  lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
  lldb/source/Target/Process.cpp
  lldb/test/API/functionalities/exec/TestExec.py
  lldb/test/API/functionalities/exec/main.cpp

Index: lldb/test/API/functionalities/exec/main.cpp
===
--- lldb/test/API/functionalities/exec/main.cpp
+++ lldb/test/API/functionalities/exec/main.cpp
@@ -1,13 +1,24 @@
 #define _POSIX_C_SOURCE 200809L
 
+#include 
 #include 
 #include 
 #include 
 #include 
 #include 
+#include 
 #include 
 
+volatile int wait_for_attach = 1;
+
 int main(int argc, char const **argv) {
+  if (getenv("LLDB_TEST_SHOULD_ATTACH") != nullptr) {
+lldb_enable_attach();
+
+while (wait_for_attach)
+  std::this_thread::sleep_for(std::chrono::milliseconds(10));
+  }
+
   char *buf = strdup(argv[0]); // Set breakpoint 1 here
   std::string directory_name(::dirname(buf));
 
Index: lldb/test/API/functionalities/exec/TestExec.py
===
--- lldb/test/API/functionalities/exec/TestExec.py
+++ lldb/test/API/functionalities/exec/TestExec.py
@@ -24,7 +24,8 @@
 @skipIfAsan # rdar://problem/43756823
 @skipIfWindows
 def test_hitting_exec (self):
-self.do_test(False)
+self.do_test(False, False)
+self.do_test(False, True)
 
 @expectedFailureAll(archs=['i386'],
 oslist=no_match(["freebsd"]),
@@ -34,9 +35,10 @@
 @skipIfAsan # rdar://problem/43756823
 @skipIfWindows
 def test_skipping_exec (self):
-self.do_test(True)
+self.do_test(True, False)
+self.do_test(True, True)
 
-def do_test(self, skip_exec):
+def do_test(self, skip_exec, should_attach):
 self.build()
 exe = self.getBuildArtifact("a.out")
 secondprog = self.getBuildArtifact("secondprog")
@@ -52,10 +54,26 @@
 'Set breakpoint 2 here', lldb.SBFileSpec("secondprog.cpp", False))
 self.assertTrue(breakpoint2, VALID_BREAKPOINT)
 
-# Launch the process
-process = target.LaunchSimple(
-None, None, self.get_process_working_directory())
-self.assertTrue(process, PROCESS_IS_VALID)
+if not should_attach:
+# Launch the process
+process = target.LaunchSimple(
+None, None, self.get_process_working_directory())
+self.assertTrue(process, PROCESS_IS_VALID)
+else:
+# Spawn the process and attach to it
+popen = subprocess.Popen(exe, env={"LLDB_TEST_SHOULD_ATTACH": "1"})
+if self.TraceOn():
+print("Will attach to PID " + str(popen.pid))
+
+error = lldb.SBError()
+attach_info = lldb.SBAttachInfo(popen.pid)
+process = target.Attach(attach_info, error)
+self.assertTrue(error.Success() and process)
+
+process.GetSelectedThread().GetSelectedFrame().EvaluateExpression(
+"wait_for_attach = 0")
+
+self.assertTrue(process.Continue())
 
 if self.TraceOn():
 self.runCmd("settings show target.process.stop-on-exec", check=False)
Index: lldb/source/Target/Process.cpp
===
--- lldb/source/Target/Process.cpp
+++ lldb/source/Target/Process.cpp
@@ -1248,6 +1248,12 @@
   return false;
 }
 
+void Process::ProcessDidExec() {
+  m_thread_list_real.Clear();
+  m_thread_list.Clear();
+  m_thread_plans.Clear();
+}
+
 void Process::UpdateThreadListIfNeeded() {
   const uint32_t stop_id = GetStopID();
   if (m_thread_list.GetSize(false) == 0 ||
Index: lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
===
--- lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
+++ lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
@@ -2611,8 +2611,7 @@
 Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
 LLDB_LOGF(log, "ProcessGDBRemote::SetLastStopPacket () - detected exec");
 
-m_thread_list_real.Clear();
-m_thread_list.Clear();
+ProcessDidExec();
 BuildDynamicRegisterInfo(true);
 m_gdb_comm.ResetDiscoverableSettings(did_exec);
   }
Index: lldb/include/lldb/Target/Process.h
===
--- lldb/include/lldb/Target/Process.h
+++ lldb/include/lldb/Target/Process.h
@@ -2075,6 +2075,10 @@
 
   void UpdateThreadListIfNeeded();
 
+  /// Method to be invoked to signal that the underlying process has exec'ed
+  /// and some clean up should be done to prepare for the new process state.
+  void ProcessDidExec();
+

[Lldb-commits] [PATCH] D93874: [process] fix exec support on Linux

2020-12-28 Thread walter erquinigo via Phabricator via lldb-commits
wallace created this revision.
wallace added reviewers: clayborg, jingham.
wallace requested review of this revision.
Herald added a project: LLDB.
Herald added a subscriber: lldb-commits.

On Linux, unlike Darwin, after a process performs exec, the thread id doesn't 
change. This causes any living thread plans to fail because the original thread 
is now invalid. This crash only happens if thread plans are still executing 
when the original thread dies.

I've been testing this on my Linux machine and it happens mostly when I attach 
to a process that then execs. If LLDB launches that process, this problem 
almost never happens. As with most race conditions, it's hard to predict and 
reproduce. In any case, I added a test with an attach scenario that works 
correctly on my machine.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D93874

Files:
  lldb/include/lldb/Target/Process.h
  lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
  lldb/source/Target/Process.cpp
  lldb/test/API/functionalities/exec/TestExec.py
  lldb/test/API/functionalities/exec/main.cpp

Index: lldb/test/API/functionalities/exec/main.cpp
===
--- lldb/test/API/functionalities/exec/main.cpp
+++ lldb/test/API/functionalities/exec/main.cpp
@@ -1,5 +1,6 @@
 #define _POSIX_C_SOURCE 200809L
 
+#include 
 #include 
 #include 
 #include 
@@ -8,6 +9,9 @@
 #include 
 
 int main(int argc, char const **argv) {
+  if (getenv("LLDB_TEST_SHOULD_ATTACH") != nullptr)
+raise(SIGSTOP);
+
   char *buf = strdup(argv[0]); // Set breakpoint 1 here
   std::string directory_name(::dirname(buf));
 
Index: lldb/test/API/functionalities/exec/TestExec.py
===
--- lldb/test/API/functionalities/exec/TestExec.py
+++ lldb/test/API/functionalities/exec/TestExec.py
@@ -24,7 +24,8 @@
 @skipIfAsan # rdar://problem/43756823
 @skipIfWindows
 def test_hitting_exec (self):
-self.do_test(False)
+self.do_test(False, False)
+self.do_test(False, True)
 
 @expectedFailureAll(archs=['i386'],
 oslist=no_match(["freebsd"]),
@@ -34,9 +35,10 @@
 @skipIfAsan # rdar://problem/43756823
 @skipIfWindows
 def test_skipping_exec (self):
-self.do_test(True)
+self.do_test(True, False)
+self.do_test(True, True)
 
-def do_test(self, skip_exec):
+def do_test(self, skip_exec, should_attach):
 self.build()
 exe = self.getBuildArtifact("a.out")
 secondprog = self.getBuildArtifact("secondprog")
@@ -52,10 +54,31 @@
 'Set breakpoint 2 here', lldb.SBFileSpec("secondprog.cpp", False))
 self.assertTrue(breakpoint2, VALID_BREAKPOINT)
 
-# Launch the process
-process = target.LaunchSimple(
-None, None, self.get_process_working_directory())
-self.assertTrue(process, PROCESS_IS_VALID)
+if not should_attach:
+# Launch the process
+process = target.LaunchSimple(
+None, None, self.get_process_working_directory())
+self.assertTrue(process, PROCESS_IS_VALID)
+else:
+# Spawn the process and attach to it
+popen = subprocess.Popen(exe, env={"LLDB_TEST_SHOULD_ATTACH": "1"})
+if self.TraceOn():
+print("Will attach to PID" + str(popen.pid))
+
+error = lldb.SBError()
+attach_info = lldb.SBAttachInfo(popen.pid)
+process = target.Attach(attach_info, error)
+self.assertTrue(error.Success() and process)
+
+# In some systems lldb will stop for a second time at the SIGSTOP attach
+# point. That might be need to be fixed in a different patch.
+# To avoid making guesses, we continue until we hit breakpoint1.
+while True:
+error = process.Continue()
+self.assertTrue(error.Success())
+threads = lldbutil.get_threads_stopped_at_breakpoint(process, breakpoint1)
+if len(threads) > 0:
+break
 
 if self.TraceOn():
 self.runCmd("settings show target.process.stop-on-exec", check=False)
Index: lldb/source/Target/Process.cpp
===
--- lldb/source/Target/Process.cpp
+++ lldb/source/Target/Process.cpp
@@ -1248,6 +1248,12 @@
   return false;
 }
 
+void Process::ProcessDidExec() {
+  m_thread_list_real.Clear();
+  m_thread_list.Clear();
+  m_thread_plans.Clear();
+}
+
 void Process::UpdateThreadListIfNeeded() {
   const uint32_t stop_id = GetStopID();
   if (m_thread_list.GetSize(false) == 0 ||
Index: lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
===
--- lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
+++ 

[Lldb-commits] [lldb] 76a718e - [lldb] Deduplicate some lldb-server tests

2020-12-28 Thread Pavel Labath via lldb-commits

Author: Pavel Labath
Date: 2020-12-28T20:16:08+01:00
New Revision: 76a718ee939ed84d95b005f36cfbd103a702522f

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

LOG: [lldb] Deduplicate some lldb-server tests

Merge llgs and debugserver flavours

Added: 


Modified: 
lldb/test/API/tools/lldb-server/TestGdbRemoteAttach.py
lldb/test/API/tools/lldb-server/TestGdbRemoteCompletion.py
lldb/test/API/tools/lldb-server/TestGdbRemoteExpeditedRegisters.py
lldb/test/API/tools/lldb-server/TestGdbRemoteHostInfo.py
lldb/test/API/tools/lldb-server/TestGdbRemote_qThreadStopInfo.py
lldb/test/API/tools/lldb-server/commandline/TestGdbRemoteConnection.py

lldb/test/API/tools/lldb-server/signal-filtering/TestGdbRemote_QPassSignals.py

Removed: 




diff  --git a/lldb/test/API/tools/lldb-server/TestGdbRemoteAttach.py 
b/lldb/test/API/tools/lldb-server/TestGdbRemoteAttach.py
index 9ffa7e26fab7..dd427b66ca89 100644
--- a/lldb/test/API/tools/lldb-server/TestGdbRemoteAttach.py
+++ b/lldb/test/API/tools/lldb-server/TestGdbRemoteAttach.py
@@ -1,17 +1,17 @@
-
-
 import gdbremote_testcase
 import lldbgdbserverutils
 from lldbsuite.test.decorators import *
 from lldbsuite.test.lldbtest import *
 from lldbsuite.test import lldbutil
 
-
 class TestGdbRemoteAttach(gdbremote_testcase.GdbRemoteTestCaseBase):
 
 mydir = TestBase.compute_mydir(__file__)
 
-def attach_with_vAttach(self):
+def test_attach_with_vAttach(self):
+self.build()
+self.set_inferior_startup_attach_manually()
+
 # Start the inferior, start the debug monitor, nothing is attached yet.
 procs = self.prep_debug_monitor_and_inferior(
 inferior_args=["sleep:60"])
@@ -49,15 +49,3 @@ def attach_with_vAttach(self):
 self.assertIsNotNone(pid_text)
 reported_pid = int(pid_text, base=16)
 self.assertEqual(reported_pid, inferior.pid)
-
-@debugserver_test
-def test_attach_with_vAttach_debugserver(self):
-self.build()
-self.set_inferior_startup_attach_manually()
-self.attach_with_vAttach()
-
-@llgs_test
-def test_attach_with_vAttach_llgs(self):
-self.build()
-self.set_inferior_startup_attach_manually()
-self.attach_with_vAttach()

diff  --git a/lldb/test/API/tools/lldb-server/TestGdbRemoteCompletion.py 
b/lldb/test/API/tools/lldb-server/TestGdbRemoteCompletion.py
index e9eaab322821..22af21d132da 100644
--- a/lldb/test/API/tools/lldb-server/TestGdbRemoteCompletion.py
+++ b/lldb/test/API/tools/lldb-server/TestGdbRemoteCompletion.py
@@ -34,7 +34,7 @@ def init_lldb_server(self):
 def generate_hex_path(self, target):
 return str(os.path.join(self.getBuildDir(), target)).encode().hex()
 
-@llgs_test
+@add_test_categories(["llgs"])
 def test_autocomplete_path(self):
 self.build()
 self.init_lldb_server()

diff  --git 
a/lldb/test/API/tools/lldb-server/TestGdbRemoteExpeditedRegisters.py 
b/lldb/test/API/tools/lldb-server/TestGdbRemoteExpeditedRegisters.py
index 103ecfd292cd..fcf115647801 100644
--- a/lldb/test/API/tools/lldb-server/TestGdbRemoteExpeditedRegisters.py
+++ b/lldb/test/API/tools/lldb-server/TestGdbRemoteExpeditedRegisters.py
@@ -57,45 +57,21 @@ def stop_notification_contains_generic_register(
 self.assertTrue(reg_info["lldb_register_index"] in expedited_registers)
 self.trace("{} reg_info:{}".format(generic_register_name, reg_info))
 
-def stop_notification_contains_aarch64_vg_register(self):
-# Generate a stop reply, parse out expedited registers from stop
-# notification.
-expedited_registers = self.gather_expedited_registers()
-self.assertIsNotNone(expedited_registers)
-self.assertTrue(len(expedited_registers) > 0)
-
-# Gather target register infos.
-reg_infos = self.gather_register_infos()
-
-# Find the vg register.
-reg_info = self.find_register_with_name_and_dwarf_regnum(
-reg_infos, 'vg', '46')
-self.assertIsNotNone(reg_info)
-
-# Ensure the expedited registers contained it.
-self.assertTrue(reg_info["lldb_register_index"] in expedited_registers)
-self.trace("{} reg_info:{}".format('vg', reg_info))
+def test_stop_notification_contains_any_registers(self):
+self.build()
+self.set_inferior_startup_launch()
 
-def stop_notification_contains_any_registers(self):
 # Generate a stop reply, parse out expedited registers from stop
 # notification.
 expedited_registers = self.gather_expedited_registers()
 # Verify we have at least one expedited register.
 self.assertTrue(len(expedited_registers) > 0)
 
-@debugserver_test
-def 

[Lldb-commits] [PATCH] D93481: [lldb/Lua] add support for multiline scripted breakpoints

2020-12-28 Thread Pedro Tammela via Phabricator via lldb-commits
tammela added inline comments.



Comment at: lldb/source/Plugins/ScriptInterpreter/Lua/Lua.h:39
   llvm::Error LoadModule(llvm::StringRef filename);
+  llvm::Error LoadBuffer(llvm::StringRef buffer, bool pop_result = true);
   llvm::Error ChangeIO(FILE *out, FILE *err);

labath wrote:
> tammela wrote:
> > labath wrote:
> > > This default value does not seem particularly useful. In fact, I am not 
> > > sure if this argument should even exist at all. The usage in 
> > > `IOHandlerIsInputComplete` is sufficiently unorthodox that it might be a 
> > > good idea to draw attention to the fact that something funky is happening 
> > > via an explicit pop (and maybe a comment).
> > We can't explicitly pop, as in calling `lua_pop()`, from 
> > `ScriptInterpreterLua.cpp` because the `lua_State` is not exposed. Are you 
> > suggesting to add a method that wraps `lua_pop()` as well?
> Good question. I didn't realize this aspect of the problem. I think the 
> answer to this depends on the direction we want the Lua class to go in. Back 
> when it was first introduced, my idea was for it to be some sort of a c++ 
> wrapper for the lua (C) api. It would offset a nicer interface to interact 
> with lua, but would otherwise be (more-or-less) lldb-agnostic (kind of like 
> our PythonDataObjects). In that world, it would make sense to expose the lua 
> stack and the pop function (among other things).
> 
> However, I don't think that's really how things have worked out. The current 
> Lua interface is much more high-level and much-more debugger-oriented than I 
> originally imagined. Among functions like `RegisterBreakpointCallback` and 
> `ChangeIO`, a function like `Pop` seems misplaced. I'm not sure this is a 
> good position to be in (there's still a need to find a home for the c++ 
> wrapper-like functions, for example to handle exceptions), but if we want to 
> go down that path, then a pop function is not the right answer. However, I 
> think the same applies to the LoadBuffer function, as it cannot be useful 
> (beyond this syntax-check use case) without exposing the lua stack, 
> implicitly or explicitly.  In this world it would be better to make the 
> function even more high-level, and have something like `CheckSyntax(buffer)` 
> (which does pretty much what LoadBuffer does, but it always pops the result). 
> Internally it can be implemented as a call to LoadBuffer, but this function 
> would now be a private implementation detail instead of a part of the 
> interface.
I think it's better to keep it as high level as possible. Exposing the 
`lua_State` spills the stack control to whom ever has access to the Lua 
interpreter, which might be undesirable and cumbersome to keep track of.




Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D93481

___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [PATCH] D93481: [lldb/Lua] add support for multiline scripted breakpoints

2020-12-28 Thread Pedro Tammela via Phabricator via lldb-commits
tammela updated this revision to Diff 313870.
tammela added a comment.

Addressing comments


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D93481

Files:
  lldb/source/Plugins/ScriptInterpreter/Lua/Lua.cpp
  lldb/source/Plugins/ScriptInterpreter/Lua/Lua.h
  lldb/source/Plugins/ScriptInterpreter/Lua/ScriptInterpreterLua.cpp
  lldb/source/Plugins/ScriptInterpreter/Lua/ScriptInterpreterLua.h
  lldb/test/Shell/ScriptInterpreter/Lua/breakpoint_callback.test
  lldb/test/Shell/ScriptInterpreter/Lua/partial_statements.test

Index: lldb/test/Shell/ScriptInterpreter/Lua/partial_statements.test
===
--- /dev/null
+++ lldb/test/Shell/ScriptInterpreter/Lua/partial_statements.test
@@ -0,0 +1,15 @@
+# REQUIRES: lua
+# RUN: %lldb -s %s --script-language lua 2>&1 | FileCheck %s
+script
+do
+local a = 123
+print(a)
+end
+# CHECK: 123
+str = 'hello there!'
+function callme()
+print(str)
+end
+callme()
+# CHECK: hello there!
+# CHECK-NOT: error
Index: lldb/test/Shell/ScriptInterpreter/Lua/breakpoint_callback.test
===
--- lldb/test/Shell/ScriptInterpreter/Lua/breakpoint_callback.test
+++ lldb/test/Shell/ScriptInterpreter/Lua/breakpoint_callback.test
@@ -1,5 +1,13 @@
 # REQUIRES: lua
-# RUN: %lldb -s %s --script-language lua 2>&1 | FileCheck %s
+# RUN: echo "int main() { return 0; }" | %clang_host -x c - -o %t
+# RUN: %lldb -s %s --script-language lua %t 2>&1 | FileCheck %s
 b main
 breakpoint command add -s lua
-# CHECK: error: This script interpreter does not support breakpoint callbacks
+local a = 123
+print(a)
+quit
+run
+# CHECK: 123
+breakpoint command add -s lua
+789_nil
+# CHECK: unexpected symbol near '789'
Index: lldb/source/Plugins/ScriptInterpreter/Lua/ScriptInterpreterLua.h
===
--- lldb/source/Plugins/ScriptInterpreter/Lua/ScriptInterpreterLua.h
+++ lldb/source/Plugins/ScriptInterpreter/Lua/ScriptInterpreterLua.h
@@ -65,6 +65,10 @@
   llvm::Error EnterSession(lldb::user_id_t debugger_id);
   llvm::Error LeaveSession();
 
+  void CollectDataForBreakpointCommandCallback(
+  std::vector _options_vec,
+  CommandReturnObject ) override;
+
   Status SetBreakpointCommandCallback(BreakpointOptions *bp_options,
   const char *command_body_text) override;
 
Index: lldb/source/Plugins/ScriptInterpreter/Lua/ScriptInterpreterLua.cpp
===
--- lldb/source/Plugins/ScriptInterpreter/Lua/ScriptInterpreterLua.cpp
+++ lldb/source/Plugins/ScriptInterpreter/Lua/ScriptInterpreterLua.cpp
@@ -17,23 +17,33 @@
 #include "lldb/Utility/Stream.h"
 #include "lldb/Utility/StringList.h"
 #include "lldb/Utility/Timer.h"
+#include "llvm/ADT/StringRef.h"
 #include "llvm/Support/FormatAdapters.h"
 #include 
+#include 
 
 using namespace lldb;
 using namespace lldb_private;
 
 LLDB_PLUGIN_DEFINE(ScriptInterpreterLua)
 
+enum ActiveIOHandler {
+  eIOHandlerNone,
+  eIOHandlerBreakpoint,
+  eIOHandlerWatchpoint
+};
+
 class IOHandlerLuaInterpreter : public IOHandlerDelegate,
 public IOHandlerEditline {
 public:
   IOHandlerLuaInterpreter(Debugger ,
-  ScriptInterpreterLua _interpreter)
+  ScriptInterpreterLua _interpreter,
+  ActiveIOHandler active_io_handler = eIOHandlerNone)
   : IOHandlerEditline(debugger, IOHandler::Type::LuaInterpreter, "lua",
   ">>> ", "..> ", true, debugger.GetUseColor(), 0,
   *this, nullptr),
-m_script_interpreter(script_interpreter) {
+m_script_interpreter(script_interpreter),
+m_active_io_handler(active_io_handler) {
 llvm::cantFail(m_script_interpreter.GetLua().ChangeIO(
 debugger.GetOutputFile().GetStream(),
 debugger.GetErrorFile().GetStream()));
@@ -44,20 +54,79 @@
 llvm::cantFail(m_script_interpreter.LeaveSession());
   }
 
-  void IOHandlerInputComplete(IOHandler _handler,
-  std::string ) override {
-if (llvm::StringRef(data).rtrim() == "quit") {
-  io_handler.SetIsDone(true);
+  void IOHandlerActivated(IOHandler _handler, bool interactive) override {
+const char *instructions = nullptr;
+switch (m_active_io_handler) {
+case eIOHandlerNone:
+case eIOHandlerWatchpoint:
+  break;
+case eIOHandlerBreakpoint:
+  instructions = "Enter your Lua command(s). Type 'quit' to end.\n"
+ "The commands are compiled as the body of the following "
+ "Lua function\n"
+ "function (frame, bp_loc, ...) end\n";
+  SetPrompt(llvm::StringRef("..> "));
+  break;
+}
+if (instructions == nullptr)
   return;
+if