[Lldb-commits] [PATCH] D145297: [lldb] Add an example of interactive scripted process debugging

2023-04-20 Thread Med Ismail Bennani via Phabricator via lldb-commits
mib marked 23 inline comments as done.
mib added inline comments.



Comment at: 
lldb/test/API/functionalities/interactive_scripted_process/TestInteractiveScriptedProcess.py:102-103
+self.assertState(lldb.SBProcess.GetStateFromEvent(event), 
lldb.eStateRunning)
+event = lldbutil.fetch_next_event(self, mux_process_listener, 
mux_process.GetBroadcaster())
+self.assertState(lldb.SBProcess.GetStateFromEvent(event), 
lldb.eStateStopped)
+

bulbazord wrote:
> Did you mean to get info from the `mux_process_listener` twice? Was one of 
> these supposed to be for the real process?
We're only listening to the `mux_process` events so this is how its supposed to 
be.



Comment at: 
lldb/test/API/functionalities/interactive_scripted_process/interactive_scripted_process.py:9
+
+import os,json,struct,signal
+import time

bulbazord wrote:
> nit: import these all on different lines
why :p ?


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

https://reviews.llvm.org/D145297

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


[Lldb-commits] [PATCH] D145297: [lldb] Add an example of interactive scripted process debugging

2023-04-20 Thread Med Ismail Bennani via Phabricator via lldb-commits
mib updated this revision to Diff 515505.
mib marked 2 inline comments as done.
mib added a comment.

Address @bulbazord comments:

- f-string everything
- remove logs
- add type annotations


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

https://reviews.llvm.org/D145297

Files:
  lldb/test/API/functionalities/interactive_scripted_process/Makefile
  
lldb/test/API/functionalities/interactive_scripted_process/TestInteractiveScriptedProcess.py
  
lldb/test/API/functionalities/interactive_scripted_process/interactive_scripted_process.py
  lldb/test/API/functionalities/interactive_scripted_process/main.cpp

Index: lldb/test/API/functionalities/interactive_scripted_process/main.cpp
===
--- /dev/null
+++ lldb/test/API/functionalities/interactive_scripted_process/main.cpp
@@ -0,0 +1,35 @@
+#include 
+#include 
+#include 
+#include 
+#include 
+
+void spawn_thread(int index) {
+  std::string name = "I'm thread " + std::to_string(index) + " !";
+  bool done = false;
+  std::string state = "Started execution!";
+  while (true) {
+if (done) // also break here
+  break;
+  }
+
+  state = "Stopped execution!";
+}
+
+int main() {
+  constexpr size_t num_threads = 10;
+  std::vector threads;
+
+  for (size_t i = 0; i < num_threads; i++) {
+threads.push_back(std::thread(spawn_thread, i));
+  }
+
+  std::cout << "Spawned " << threads.size() << " threads!" << std::endl; // Break here
+
+  for (auto &t : threads) {
+if (t.joinable())
+  t.join();
+  }
+
+  return 0;
+}
Index: lldb/test/API/functionalities/interactive_scripted_process/interactive_scripted_process.py
===
--- /dev/null
+++ lldb/test/API/functionalities/interactive_scripted_process/interactive_scripted_process.py
@@ -0,0 +1,417 @@
+# Usage:
+# ./bin/lldb $LLVM/lldb/test/API/functionalities/interactive_scripted_process/main \
+#   -o "br set -p 'Break here'" \
+#   -o "command script import $LLVM/lldb/test/API/functionalities/interactive_scripted_process/interactive_scripted_process.py" \
+#   -o "create_mux" \
+#   -o "create_sub" \
+#   -o "br set -p 'also break here'" -o 'continue'
+
+import os,json,struct,signal
+
+from threading import Thread
+from typing import Any, Dict
+
+import lldb
+from lldb.plugins.scripted_process import ScriptedProcess
+from lldb.plugins.scripted_process import ScriptedThread
+
+class PassthruScriptedProcess(ScriptedProcess):
+driving_target = None
+driving_process = None
+
+def __init__(self, exe_ctx: lldb.SBExecutionContext, args :
+ lldb.SBStructuredData, launched_driving_process: bool =True):
+super().__init__(exe_ctx, args)
+
+self.driving_target = None
+self.driving_process = None
+
+self.driving_target_idx = args.GetValueForKey("driving_target_idx")
+if (self.driving_target_idx and self.driving_target_idx.IsValid()):
+if self.driving_target_idx.GetType() == lldb.eStructuredDataTypeInteger:
+idx = self.driving_target_idx.GetIntegerValue(42)
+if self.driving_target_idx.GetType() == lldb.eStructuredDataTypeString:
+idx = int(self.driving_target_idx.GetStringValue(100))
+self.driving_target = self.target.GetDebugger().GetTargetAtIndex(idx)
+
+if launched_driving_process:
+self.driving_process = self.driving_target.GetProcess()
+for driving_thread in self.driving_process:
+structured_data = lldb.SBStructuredData()
+structured_data.SetFromJSON(json.dumps({
+"driving_target_idx" : idx,
+"thread_idx" : driving_thread.GetIndexID()
+}))
+
+self.threads[driving_thread.GetThreadID()] = PassthruScriptedThread(self, structured_data)
+
+for module in self.driving_target.modules:
+path = module.file.fullpath
+load_addr = module.GetObjectFileHeaderAddress().GetLoadAddress(self.driving_target)
+self.loaded_images.append({"path": path, "load_addr": load_addr})
+
+def get_memory_region_containing_address(self, addr: int) -> lldb.SBMemoryRegionInfo:
+mem_region = lldb.SBMemoryRegionInfo()
+error = self.driving_process.GetMemoryRegionInfo(addr, mem_region)
+if error.Fail():
+return None
+return mem_region
+
+def read_memory_at_address(self, addr: int, size: int, error: lldb.SBError) -> lldb.SBData:
+data = lldb.SBData()
+bytes_read = self.driving_process.ReadMemory(addr, size, error)
+
+if error.Fail():
+return data
+
+data.SetDataWithOwnership(error, bytes_read,
+  self.driving_target.GetByteOrder(),
+  self.driving_target.GetAddressByteSize())
+

[Lldb-commits] [PATCH] D145297: [lldb] Add an example of interactive scripted process debugging

2023-04-20 Thread Med Ismail Bennani via Phabricator via lldb-commits
mib added a comment.

ping @jingham @JDevlieghere


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

https://reviews.llvm.org/D145297

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


[Lldb-commits] [PATCH] D145297: [lldb] Add an example of interactive scripted process debugging

2023-04-20 Thread Med Ismail Bennani via Phabricator via lldb-commits
mib updated this revision to Diff 515523.
mib added a comment.

Fix typo in one of the type annotation


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

https://reviews.llvm.org/D145297

Files:
  lldb/test/API/functionalities/interactive_scripted_process/Makefile
  
lldb/test/API/functionalities/interactive_scripted_process/TestInteractiveScriptedProcess.py
  
lldb/test/API/functionalities/interactive_scripted_process/interactive_scripted_process.py
  lldb/test/API/functionalities/interactive_scripted_process/main.cpp

Index: lldb/test/API/functionalities/interactive_scripted_process/main.cpp
===
--- /dev/null
+++ lldb/test/API/functionalities/interactive_scripted_process/main.cpp
@@ -0,0 +1,35 @@
+#include 
+#include 
+#include 
+#include 
+#include 
+
+void spawn_thread(int index) {
+  std::string name = "I'm thread " + std::to_string(index) + " !";
+  bool done = false;
+  std::string state = "Started execution!";
+  while (true) {
+if (done) // also break here
+  break;
+  }
+
+  state = "Stopped execution!";
+}
+
+int main() {
+  constexpr size_t num_threads = 10;
+  std::vector threads;
+
+  for (size_t i = 0; i < num_threads; i++) {
+threads.push_back(std::thread(spawn_thread, i));
+  }
+
+  std::cout << "Spawned " << threads.size() << " threads!" << std::endl; // Break here
+
+  for (auto &t : threads) {
+if (t.joinable())
+  t.join();
+  }
+
+  return 0;
+}
Index: lldb/test/API/functionalities/interactive_scripted_process/interactive_scripted_process.py
===
--- /dev/null
+++ lldb/test/API/functionalities/interactive_scripted_process/interactive_scripted_process.py
@@ -0,0 +1,417 @@
+# Usage:
+# ./bin/lldb $LLVM/lldb/test/API/functionalities/interactive_scripted_process/main \
+#   -o "br set -p 'Break here'" \
+#   -o "command script import $LLVM/lldb/test/API/functionalities/interactive_scripted_process/interactive_scripted_process.py" \
+#   -o "create_mux" \
+#   -o "create_sub" \
+#   -o "br set -p 'also break here'" -o 'continue'
+
+import os,json,struct,signal
+
+from threading import Thread
+from typing import Any, Dict
+
+import lldb
+from lldb.plugins.scripted_process import ScriptedProcess
+from lldb.plugins.scripted_process import ScriptedThread
+
+class PassthruScriptedProcess(ScriptedProcess):
+driving_target = None
+driving_process = None
+
+def __init__(self, exe_ctx: lldb.SBExecutionContext, args :
+ lldb.SBStructuredData, launched_driving_process: bool =True):
+super().__init__(exe_ctx, args)
+
+self.driving_target = None
+self.driving_process = None
+
+self.driving_target_idx = args.GetValueForKey("driving_target_idx")
+if (self.driving_target_idx and self.driving_target_idx.IsValid()):
+if self.driving_target_idx.GetType() == lldb.eStructuredDataTypeInteger:
+idx = self.driving_target_idx.GetIntegerValue(42)
+if self.driving_target_idx.GetType() == lldb.eStructuredDataTypeString:
+idx = int(self.driving_target_idx.GetStringValue(100))
+self.driving_target = self.target.GetDebugger().GetTargetAtIndex(idx)
+
+if launched_driving_process:
+self.driving_process = self.driving_target.GetProcess()
+for driving_thread in self.driving_process:
+structured_data = lldb.SBStructuredData()
+structured_data.SetFromJSON(json.dumps({
+"driving_target_idx" : idx,
+"thread_idx" : driving_thread.GetIndexID()
+}))
+
+self.threads[driving_thread.GetThreadID()] = PassthruScriptedThread(self, structured_data)
+
+for module in self.driving_target.modules:
+path = module.file.fullpath
+load_addr = module.GetObjectFileHeaderAddress().GetLoadAddress(self.driving_target)
+self.loaded_images.append({"path": path, "load_addr": load_addr})
+
+def get_memory_region_containing_address(self, addr: int) -> lldb.SBMemoryRegionInfo:
+mem_region = lldb.SBMemoryRegionInfo()
+error = self.driving_process.GetMemoryRegionInfo(addr, mem_region)
+if error.Fail():
+return None
+return mem_region
+
+def read_memory_at_address(self, addr: int, size: int, error: lldb.SBError) -> lldb.SBData:
+data = lldb.SBData()
+bytes_read = self.driving_process.ReadMemory(addr, size, error)
+
+if error.Fail():
+return data
+
+data.SetDataWithOwnership(error, bytes_read,
+  self.driving_target.GetByteOrder(),
+  self.driving_target.GetAddressByteSize())
+
+return data
+
+def write_memory_at_address(self, addr: int, data: lldb.SBDa

[Lldb-commits] [PATCH] D145297: [lldb] Add an example of interactive scripted process debugging

2023-04-20 Thread Med Ismail Bennani via Phabricator via lldb-commits
mib updated this revision to Diff 515529.
mib added a comment.

More f-string


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

https://reviews.llvm.org/D145297

Files:
  lldb/test/API/functionalities/interactive_scripted_process/Makefile
  
lldb/test/API/functionalities/interactive_scripted_process/TestInteractiveScriptedProcess.py
  
lldb/test/API/functionalities/interactive_scripted_process/interactive_scripted_process.py
  lldb/test/API/functionalities/interactive_scripted_process/main.cpp

Index: lldb/test/API/functionalities/interactive_scripted_process/main.cpp
===
--- /dev/null
+++ lldb/test/API/functionalities/interactive_scripted_process/main.cpp
@@ -0,0 +1,35 @@
+#include 
+#include 
+#include 
+#include 
+#include 
+
+void spawn_thread(int index) {
+  std::string name = "I'm thread " + std::to_string(index) + " !";
+  bool done = false;
+  std::string state = "Started execution!";
+  while (true) {
+if (done) // also break here
+  break;
+  }
+
+  state = "Stopped execution!";
+}
+
+int main() {
+  constexpr size_t num_threads = 10;
+  std::vector threads;
+
+  for (size_t i = 0; i < num_threads; i++) {
+threads.push_back(std::thread(spawn_thread, i));
+  }
+
+  std::cout << "Spawned " << threads.size() << " threads!" << std::endl; // Break here
+
+  for (auto &t : threads) {
+if (t.joinable())
+  t.join();
+  }
+
+  return 0;
+}
Index: lldb/test/API/functionalities/interactive_scripted_process/interactive_scripted_process.py
===
--- /dev/null
+++ lldb/test/API/functionalities/interactive_scripted_process/interactive_scripted_process.py
@@ -0,0 +1,417 @@
+# Usage:
+# ./bin/lldb $LLVM/lldb/test/API/functionalities/interactive_scripted_process/main \
+#   -o "br set -p 'Break here'" \
+#   -o "command script import $LLVM/lldb/test/API/functionalities/interactive_scripted_process/interactive_scripted_process.py" \
+#   -o "create_mux" \
+#   -o "create_sub" \
+#   -o "br set -p 'also break here'" -o 'continue'
+
+import os,json,struct,signal
+
+from threading import Thread
+from typing import Any, Dict
+
+import lldb
+from lldb.plugins.scripted_process import ScriptedProcess
+from lldb.plugins.scripted_process import ScriptedThread
+
+class PassthruScriptedProcess(ScriptedProcess):
+driving_target = None
+driving_process = None
+
+def __init__(self, exe_ctx: lldb.SBExecutionContext, args :
+ lldb.SBStructuredData, launched_driving_process: bool =True):
+super().__init__(exe_ctx, args)
+
+self.driving_target = None
+self.driving_process = None
+
+self.driving_target_idx = args.GetValueForKey("driving_target_idx")
+if (self.driving_target_idx and self.driving_target_idx.IsValid()):
+if self.driving_target_idx.GetType() == lldb.eStructuredDataTypeInteger:
+idx = self.driving_target_idx.GetIntegerValue(42)
+if self.driving_target_idx.GetType() == lldb.eStructuredDataTypeString:
+idx = int(self.driving_target_idx.GetStringValue(100))
+self.driving_target = self.target.GetDebugger().GetTargetAtIndex(idx)
+
+if launched_driving_process:
+self.driving_process = self.driving_target.GetProcess()
+for driving_thread in self.driving_process:
+structured_data = lldb.SBStructuredData()
+structured_data.SetFromJSON(json.dumps({
+"driving_target_idx" : idx,
+"thread_idx" : driving_thread.GetIndexID()
+}))
+
+self.threads[driving_thread.GetThreadID()] = PassthruScriptedThread(self, structured_data)
+
+for module in self.driving_target.modules:
+path = module.file.fullpath
+load_addr = module.GetObjectFileHeaderAddress().GetLoadAddress(self.driving_target)
+self.loaded_images.append({"path": path, "load_addr": load_addr})
+
+def get_memory_region_containing_address(self, addr: int) -> lldb.SBMemoryRegionInfo:
+mem_region = lldb.SBMemoryRegionInfo()
+error = self.driving_process.GetMemoryRegionInfo(addr, mem_region)
+if error.Fail():
+return None
+return mem_region
+
+def read_memory_at_address(self, addr: int, size: int, error: lldb.SBError) -> lldb.SBData:
+data = lldb.SBData()
+bytes_read = self.driving_process.ReadMemory(addr, size, error)
+
+if error.Fail():
+return data
+
+data.SetDataWithOwnership(error, bytes_read,
+  self.driving_target.GetByteOrder(),
+  self.driving_target.GetAddressByteSize())
+
+return data
+
+def write_memory_at_address(self, addr: int, data: lldb.SBData, error: lldb.SBError) 

[Lldb-commits] [PATCH] D145297: [lldb] Add an example of interactive scripted process debugging

2023-04-21 Thread Alex Langford via Phabricator via lldb-commits
bulbazord added a comment.

Looks good to me. Might want to let @jingham or @JDevlieghere give it a 
look-over though.




Comment at: 
lldb/test/API/functionalities/interactive_scripted_process/interactive_scripted_process.py:9
+
+import os,json,struct,signal
+import time

mib wrote:
> bulbazord wrote:
> > nit: import these all on different lines
> why :p ?
I don't actually think it matters a ton, which is why it was a nit, but I think 
there's something to be said for consistency with the rest of lldb.


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

https://reviews.llvm.org/D145297

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


[Lldb-commits] [PATCH] D145297: [lldb] Add an example of interactive scripted process debugging

2023-04-21 Thread Jonas Devlieghere via Phabricator via lldb-commits
JDevlieghere added inline comments.



Comment at: 
lldb/test/API/functionalities/interactive_scripted_process/interactive_scripted_process.py:9
+
+import os,json,struct,signal
+import time

bulbazord wrote:
> mib wrote:
> > bulbazord wrote:
> > > nit: import these all on different lines
> > why :p ?
> I don't actually think it matters a ton, which is why it was a nit, but I 
> think there's something to be said for consistency with the rest of lldb.
Given the discussion in 
https://discourse.llvm.org/t/rfc-document-and-standardize-python-code-style, 
let's format new tests with `black`. It doesn't look like the tool has a 
preference between those two so I would vote for consistency. 


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

https://reviews.llvm.org/D145297

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


[Lldb-commits] [PATCH] D145297: [lldb] Add an example of interactive scripted process debugging

2023-04-21 Thread Med Ismail Bennani via Phabricator via lldb-commits
mib updated this revision to Diff 515899.
mib marked 2 inline comments as done.
mib added a comment.

Re-format python code with `black`


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

https://reviews.llvm.org/D145297

Files:
  lldb/test/API/functionalities/interactive_scripted_process/Makefile
  
lldb/test/API/functionalities/interactive_scripted_process/TestInteractiveScriptedProcess.py
  
lldb/test/API/functionalities/interactive_scripted_process/interactive_scripted_process.py
  lldb/test/API/functionalities/interactive_scripted_process/main.cpp

Index: lldb/test/API/functionalities/interactive_scripted_process/main.cpp
===
--- /dev/null
+++ lldb/test/API/functionalities/interactive_scripted_process/main.cpp
@@ -0,0 +1,35 @@
+#include 
+#include 
+#include 
+#include 
+#include 
+
+void spawn_thread(int index) {
+  std::string name = "I'm thread " + std::to_string(index) + " !";
+  bool done = false;
+  std::string state = "Started execution!";
+  while (true) {
+if (done) // also break here
+  break;
+  }
+
+  state = "Stopped execution!";
+}
+
+int main() {
+  constexpr size_t num_threads = 10;
+  std::vector threads;
+
+  for (size_t i = 0; i < num_threads; i++) {
+threads.push_back(std::thread(spawn_thread, i));
+  }
+
+  std::cout << "Spawned " << threads.size() << " threads!" << std::endl; // Break here
+
+  for (auto &t : threads) {
+if (t.joinable())
+  t.join();
+  }
+
+  return 0;
+}
Index: lldb/test/API/functionalities/interactive_scripted_process/interactive_scripted_process.py
===
--- /dev/null
+++ lldb/test/API/functionalities/interactive_scripted_process/interactive_scripted_process.py
@@ -0,0 +1,494 @@
+# Usage:
+# ./bin/lldb $LLVM/lldb/test/API/functionalities/interactive_scripted_process/main \
+#   -o "br set -p 'Break here'" \
+#   -o "command script import $LLVM/lldb/test/API/functionalities/interactive_scripted_process/interactive_scripted_process.py" \
+#   -o "create_mux" \
+#   -o "create_sub" \
+#   -o "br set -p 'also break here'" -o 'continue'
+
+import os, json, struct, signal
+
+from threading import Thread
+from typing import Any, Dict
+
+import lldb
+from lldb.plugins.scripted_process import ScriptedProcess
+from lldb.plugins.scripted_process import ScriptedThread
+
+
+class PassthruScriptedProcess(ScriptedProcess):
+driving_target = None
+driving_process = None
+
+def __init__(
+self,
+exe_ctx: lldb.SBExecutionContext,
+args: lldb.SBStructuredData,
+launched_driving_process: bool = True,
+):
+super().__init__(exe_ctx, args)
+
+self.driving_target = None
+self.driving_process = None
+
+self.driving_target_idx = args.GetValueForKey("driving_target_idx")
+if self.driving_target_idx and self.driving_target_idx.IsValid():
+if self.driving_target_idx.GetType() == lldb.eStructuredDataTypeInteger:
+idx = self.driving_target_idx.GetIntegerValue(42)
+if self.driving_target_idx.GetType() == lldb.eStructuredDataTypeString:
+idx = int(self.driving_target_idx.GetStringValue(100))
+self.driving_target = self.target.GetDebugger().GetTargetAtIndex(idx)
+
+if launched_driving_process:
+self.driving_process = self.driving_target.GetProcess()
+for driving_thread in self.driving_process:
+structured_data = lldb.SBStructuredData()
+structured_data.SetFromJSON(
+json.dumps(
+{
+"driving_target_idx": idx,
+"thread_idx": driving_thread.GetIndexID(),
+}
+)
+)
+
+self.threads[driving_thread.GetThreadID()] = PassthruScriptedThread(
+self, structured_data
+)
+
+for module in self.driving_target.modules:
+path = module.file.fullpath
+load_addr = module.GetObjectFileHeaderAddress().GetLoadAddress(
+self.driving_target
+)
+self.loaded_images.append({"path": path, "load_addr": load_addr})
+
+def get_memory_region_containing_address(
+self, addr: int
+) -> lldb.SBMemoryRegionInfo:
+mem_region = lldb.SBMemoryRegionInfo()
+error = self.driving_process.GetMemoryRegionInfo(addr, mem_region)
+if error.Fail():
+return None
+return mem_region
+
+def read_memory_at_address(
+self, addr: int, size: int, error: lldb.SBError
+) -> lldb.SBData:
+data = lldb.SBData()
+bytes_read = self.driving_process.ReadMemory(addr, size, error)
+
+if error.Fail():
+

[Lldb-commits] [PATCH] D145297: [lldb] Add an example of interactive scripted process debugging

2023-04-25 Thread Med Ismail Bennani via Phabricator via lldb-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rG6cf668016efd: [lldb] Add an example of interactive scripted 
process debugging (authored by mib).

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D145297

Files:
  lldb/test/API/functionalities/interactive_scripted_process/Makefile
  
lldb/test/API/functionalities/interactive_scripted_process/TestInteractiveScriptedProcess.py
  
lldb/test/API/functionalities/interactive_scripted_process/interactive_scripted_process.py
  lldb/test/API/functionalities/interactive_scripted_process/main.cpp

Index: lldb/test/API/functionalities/interactive_scripted_process/main.cpp
===
--- /dev/null
+++ lldb/test/API/functionalities/interactive_scripted_process/main.cpp
@@ -0,0 +1,35 @@
+#include 
+#include 
+#include 
+#include 
+#include 
+
+void spawn_thread(int index) {
+  std::string name = "I'm thread " + std::to_string(index) + " !";
+  bool done = false;
+  std::string state = "Started execution!";
+  while (true) {
+if (done) // also break here
+  break;
+  }
+
+  state = "Stopped execution!";
+}
+
+int main() {
+  constexpr size_t num_threads = 10;
+  std::vector threads;
+
+  for (size_t i = 0; i < num_threads; i++) {
+threads.push_back(std::thread(spawn_thread, i));
+  }
+
+  std::cout << "Spawned " << threads.size() << " threads!" << std::endl; // Break here
+
+  for (auto &t : threads) {
+if (t.joinable())
+  t.join();
+  }
+
+  return 0;
+}
Index: lldb/test/API/functionalities/interactive_scripted_process/interactive_scripted_process.py
===
--- /dev/null
+++ lldb/test/API/functionalities/interactive_scripted_process/interactive_scripted_process.py
@@ -0,0 +1,494 @@
+# Usage:
+# ./bin/lldb $LLVM/lldb/test/API/functionalities/interactive_scripted_process/main \
+#   -o "br set -p 'Break here'" \
+#   -o "command script import $LLVM/lldb/test/API/functionalities/interactive_scripted_process/interactive_scripted_process.py" \
+#   -o "create_mux" \
+#   -o "create_sub" \
+#   -o "br set -p 'also break here'" -o 'continue'
+
+import os, json, struct, signal
+
+from threading import Thread
+from typing import Any, Dict
+
+import lldb
+from lldb.plugins.scripted_process import ScriptedProcess
+from lldb.plugins.scripted_process import ScriptedThread
+
+
+class PassthruScriptedProcess(ScriptedProcess):
+driving_target = None
+driving_process = None
+
+def __init__(
+self,
+exe_ctx: lldb.SBExecutionContext,
+args: lldb.SBStructuredData,
+launched_driving_process: bool = True,
+):
+super().__init__(exe_ctx, args)
+
+self.driving_target = None
+self.driving_process = None
+
+self.driving_target_idx = args.GetValueForKey("driving_target_idx")
+if self.driving_target_idx and self.driving_target_idx.IsValid():
+if self.driving_target_idx.GetType() == lldb.eStructuredDataTypeInteger:
+idx = self.driving_target_idx.GetIntegerValue(42)
+if self.driving_target_idx.GetType() == lldb.eStructuredDataTypeString:
+idx = int(self.driving_target_idx.GetStringValue(100))
+self.driving_target = self.target.GetDebugger().GetTargetAtIndex(idx)
+
+if launched_driving_process:
+self.driving_process = self.driving_target.GetProcess()
+for driving_thread in self.driving_process:
+structured_data = lldb.SBStructuredData()
+structured_data.SetFromJSON(
+json.dumps(
+{
+"driving_target_idx": idx,
+"thread_idx": driving_thread.GetIndexID(),
+}
+)
+)
+
+self.threads[driving_thread.GetThreadID()] = PassthruScriptedThread(
+self, structured_data
+)
+
+for module in self.driving_target.modules:
+path = module.file.fullpath
+load_addr = module.GetObjectFileHeaderAddress().GetLoadAddress(
+self.driving_target
+)
+self.loaded_images.append({"path": path, "load_addr": load_addr})
+
+def get_memory_region_containing_address(
+self, addr: int
+) -> lldb.SBMemoryRegionInfo:
+mem_region = lldb.SBMemoryRegionInfo()
+error = self.driving_process.GetMemoryRegionInfo(addr, mem_region)
+if error.Fail():
+return None
+return mem_region
+
+def read_memory_at_address(
+self, addr: int, size: int, error: lldb.SBError
+) -> lldb.SBData:
+data = lldb.SBData()
+b

[Lldb-commits] [PATCH] D145297: [lldb] Add an example of interactive scripted process debugging

2023-04-14 Thread Med Ismail Bennani via Phabricator via lldb-commits
mib updated this revision to Diff 513817.
mib retitled this revision from "[lldb] Add an example of interactive scripted 
process debugging (NFC)" to "[lldb] Add an example of interactive scripted 
process debugging".
mib edited the summary of this revision.
mib added a comment.

Many changes:

- Fixed many bugs
- Added test case

-


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

https://reviews.llvm.org/D145297

Files:
  lldb/test/API/functionalities/interactive_scripted_process/Makefile
  
lldb/test/API/functionalities/interactive_scripted_process/TestInteractiveScriptedProcess.py
  
lldb/test/API/functionalities/interactive_scripted_process/interactive_scripted_process.py
  lldb/test/API/functionalities/interactive_scripted_process/main.cpp

Index: lldb/test/API/functionalities/interactive_scripted_process/main.cpp
===
--- /dev/null
+++ lldb/test/API/functionalities/interactive_scripted_process/main.cpp
@@ -0,0 +1,35 @@
+#include 
+#include 
+#include 
+#include 
+#include 
+
+void spawn_thread(int index) {
+  std::string name = "I'm thread " + std::to_string(index) + " !";
+  bool done = false;
+  std::string state = "Started execution!";
+  while (true) {
+if (done) // also break here
+  break;
+  }
+
+  state = "Stopped execution!";
+}
+
+int main() {
+  size_t num_threads = 10;
+  std::vector threads;
+
+  for (size_t i = 0; i < num_threads; i++) {
+threads.push_back(std::thread(spawn_thread, i));
+  }
+
+  std::cout << "Spawned " << threads.size() << " threads!"; // Break here
+
+  for (auto &t : threads) {
+if (t.joinable())
+  t.join();
+  }
+
+  return 0;
+}
Index: lldb/test/API/functionalities/interactive_scripted_process/interactive_scripted_process.py
===
--- /dev/null
+++ lldb/test/API/functionalities/interactive_scripted_process/interactive_scripted_process.py
@@ -0,0 +1,427 @@
+# Usage:
+# ./bin/lldb $LLVM/lldb/test/API/functionalities/interactive_scripted_process/main \
+#   -o "br set -p 'Break here'" \
+#   -o "command script import $LLVM/lldb/test/API/functionalities/interactive_scripted_process/interactive_scripted_process.py" \
+#   -o "create_mux" \
+#   -o "create_sub" \
+#   -o "br set -p 'also break here'" -o 'continue'
+
+import os,json,struct,signal
+import time
+
+from threading import Thread
+from typing import Any, Dict
+
+import lldb
+from lldb.plugins.scripted_process import ScriptedProcess
+from lldb.plugins.scripted_process import ScriptedThread
+
+class PassthruScriptedProcess(ScriptedProcess):
+driving_target = None
+driving_process = None
+
+def __init__(self, exe_ctx: lldb.SBExecutionContext, args :
+ lldb.SBStructuredData, launched_driving_process=True):
+super().__init__(exe_ctx, args)
+
+self.driving_target = None
+self.driving_process = None
+
+self.driving_target_idx = args.GetValueForKey("driving_target_idx")
+if (self.driving_target_idx and self.driving_target_idx.IsValid()):
+if self.driving_target_idx.GetType() == lldb.eStructuredDataTypeInteger:
+idx = self.driving_target_idx.GetIntegerValue(42)
+if self.driving_target_idx.GetType() == lldb.eStructuredDataTypeString:
+idx = int(self.driving_target_idx.GetStringValue(100))
+self.driving_target = self.target.GetDebugger().GetTargetAtIndex(idx)
+
+if launched_driving_process:
+self.driving_process = self.driving_target.GetProcess()
+for driving_thread in self.driving_process:
+structured_data = lldb.SBStructuredData()
+structured_data.SetFromJSON(json.dumps({
+"driving_target_idx" : idx,
+"thread_idx" : driving_thread.GetIndexID()
+}))
+
+self.threads[driving_thread.GetThreadID()] = PassthruScriptedThread(self, structured_data)
+
+for module in self.driving_target.modules:
+path = module.file.fullpath
+load_addr = module.GetObjectFileHeaderAddress().GetLoadAddress(self.driving_target)
+self.loaded_images.append({"path": path, "load_addr": load_addr})
+
+def get_memory_region_containing_address(self, addr: int) -> lldb.SBMemoryRegionInfo:
+mem_region = lldb.SBMemoryRegionInfo()
+error = self.driving_process.GetMemoryRegionInfo(addr, mem_region)
+if error.Fail():
+return None
+return mem_region
+
+def read_memory_at_address(self, addr: int, size: int, error: lldb.SBError) -> lldb.SBData:
+data = lldb.SBData()
+bytes_read = self.driving_process.ReadMemory(addr, size, error)
+
+if error.Fail():
+return data
+
+data.SetDataWithOwnership(error, bytes_read,
+  

[Lldb-commits] [PATCH] D145297: [lldb] Add an example of interactive scripted process debugging

2023-04-14 Thread Med Ismail Bennani via Phabricator via lldb-commits
mib updated this revision to Diff 513818.

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

https://reviews.llvm.org/D145297

Files:
  lldb/test/API/functionalities/interactive_scripted_process/Makefile
  
lldb/test/API/functionalities/interactive_scripted_process/TestInteractiveScriptedProcess.py
  
lldb/test/API/functionalities/interactive_scripted_process/interactive_scripted_process.py
  lldb/test/API/functionalities/interactive_scripted_process/main.cpp

Index: lldb/test/API/functionalities/interactive_scripted_process/main.cpp
===
--- /dev/null
+++ lldb/test/API/functionalities/interactive_scripted_process/main.cpp
@@ -0,0 +1,35 @@
+#include 
+#include 
+#include 
+#include 
+#include 
+
+void spawn_thread(int index) {
+  std::string name = "I'm thread " + std::to_string(index) + " !";
+  bool done = false;
+  std::string state = "Started execution!";
+  while (true) {
+if (done) // also break here
+  break;
+  }
+
+  state = "Stopped execution!";
+}
+
+int main() {
+  size_t num_threads = 10;
+  std::vector threads;
+
+  for (size_t i = 0; i < num_threads; i++) {
+threads.push_back(std::thread(spawn_thread, i));
+  }
+
+  std::cout << "Spawned " << threads.size() << " threads!"; // Break here
+
+  for (auto &t : threads) {
+if (t.joinable())
+  t.join();
+  }
+
+  return 0;
+}
Index: lldb/test/API/functionalities/interactive_scripted_process/interactive_scripted_process.py
===
--- /dev/null
+++ lldb/test/API/functionalities/interactive_scripted_process/interactive_scripted_process.py
@@ -0,0 +1,426 @@
+# Usage:
+# ./bin/lldb $LLVM/lldb/test/API/functionalities/interactive_scripted_process/main \
+#   -o "br set -p 'Break here'" \
+#   -o "command script import $LLVM/lldb/test/API/functionalities/interactive_scripted_process/interactive_scripted_process.py" \
+#   -o "create_mux" \
+#   -o "create_sub" \
+#   -o "br set -p 'also break here'" -o 'continue'
+
+import os,json,struct,signal
+import time
+
+from threading import Thread
+from typing import Any, Dict
+
+import lldb
+from lldb.plugins.scripted_process import ScriptedProcess
+from lldb.plugins.scripted_process import ScriptedThread
+
+class PassthruScriptedProcess(ScriptedProcess):
+driving_target = None
+driving_process = None
+
+def __init__(self, exe_ctx: lldb.SBExecutionContext, args :
+ lldb.SBStructuredData, launched_driving_process=True):
+super().__init__(exe_ctx, args)
+
+self.driving_target = None
+self.driving_process = None
+
+self.driving_target_idx = args.GetValueForKey("driving_target_idx")
+if (self.driving_target_idx and self.driving_target_idx.IsValid()):
+if self.driving_target_idx.GetType() == lldb.eStructuredDataTypeInteger:
+idx = self.driving_target_idx.GetIntegerValue(42)
+if self.driving_target_idx.GetType() == lldb.eStructuredDataTypeString:
+idx = int(self.driving_target_idx.GetStringValue(100))
+self.driving_target = self.target.GetDebugger().GetTargetAtIndex(idx)
+
+if launched_driving_process:
+self.driving_process = self.driving_target.GetProcess()
+for driving_thread in self.driving_process:
+structured_data = lldb.SBStructuredData()
+structured_data.SetFromJSON(json.dumps({
+"driving_target_idx" : idx,
+"thread_idx" : driving_thread.GetIndexID()
+}))
+
+self.threads[driving_thread.GetThreadID()] = PassthruScriptedThread(self, structured_data)
+
+for module in self.driving_target.modules:
+path = module.file.fullpath
+load_addr = module.GetObjectFileHeaderAddress().GetLoadAddress(self.driving_target)
+self.loaded_images.append({"path": path, "load_addr": load_addr})
+
+def get_memory_region_containing_address(self, addr: int) -> lldb.SBMemoryRegionInfo:
+mem_region = lldb.SBMemoryRegionInfo()
+error = self.driving_process.GetMemoryRegionInfo(addr, mem_region)
+if error.Fail():
+return None
+return mem_region
+
+def read_memory_at_address(self, addr: int, size: int, error: lldb.SBError) -> lldb.SBData:
+data = lldb.SBData()
+bytes_read = self.driving_process.ReadMemory(addr, size, error)
+
+if error.Fail():
+return data
+
+data.SetDataWithOwnership(error, bytes_read,
+  self.driving_target.GetByteOrder(),
+  self.driving_target.GetAddressByteSize())
+
+return data
+
+def write_memory_at_address(self, addr, data, error):
+return self.driving_process.WriteMemory(addr,
+ 

[Lldb-commits] [PATCH] D145297: [lldb] Add an example of interactive scripted process debugging

2023-04-17 Thread Alex Langford via Phabricator via lldb-commits
bulbazord added a comment.

A few high-level comments:

- You're doing a lot of type-annotations in python which is good, but you're 
not being very consistent about it. It would be tremendously helpful if you 
could add type annotations everywhere.
- I would recommend using f-strings over `%` and `.format` for string 
interpolation. They are available as of python 3.6 and the minimum version to 
use `lit` is 3.6 (if LLVM's CMakeLists.txt is to be believed).






Comment at: 
lldb/test/API/functionalities/interactive_scripted_process/TestInteractiveScriptedProcess.py:2
+"""
+Test the functionality of scripted processes
+"""

nit



Comment at: 
lldb/test/API/functionalities/interactive_scripted_process/TestInteractiveScriptedProcess.py:8
+from lldbsuite.test.lldbtest import *
+import os
+

nit: import json



Comment at: 
lldb/test/API/functionalities/interactive_scripted_process/TestInteractiveScriptedProcess.py:54
+
+mux_class = self.script_module + "." + "MultiplexerScriptedProcess"
+script_dict = {'driving_target_idx' : real_target_id}





Comment at: 
lldb/test/API/functionalities/interactive_scripted_process/TestInteractiveScriptedProcess.py:60-61
+
+self.runCmd("log enable lldb state -f /tmp/state.log")
+# self.runCmd("log enable lldb event -f /tmp/event.log")
+self.dbg.SetAsync(True)

Remove these log lines, I don't think they're needed for the test.



Comment at: 
lldb/test/API/functionalities/interactive_scripted_process/TestInteractiveScriptedProcess.py:89
+self.assertEqual(len(real_process.threads), len(mux_process.threads), 
"Same number of threads")
+for id in range(0, len(real_process.threads)):
+real_pc = real_process.threads[id].frame[0].pc

Defaults to 0 if you don't specify a start.



Comment at: 
lldb/test/API/functionalities/interactive_scripted_process/TestInteractiveScriptedProcess.py:102-103
+self.assertState(lldb.SBProcess.GetStateFromEvent(event), 
lldb.eStateRunning)
+event = lldbutil.fetch_next_event(self, mux_process_listener, 
mux_process.GetBroadcaster())
+self.assertState(lldb.SBProcess.GetStateFromEvent(event), 
lldb.eStateStopped)
+

Did you mean to get info from the `mux_process_listener` twice? Was one of 
these supposed to be for the real process?



Comment at: 
lldb/test/API/functionalities/interactive_scripted_process/interactive_scripted_process.py:9
+
+import os,json,struct,signal
+import time

nit: import these all on different lines



Comment at: 
lldb/test/API/functionalities/interactive_scripted_process/interactive_scripted_process.py:74-89
+def write_memory_at_address(self, addr, data, error):
+return self.driving_process.WriteMemory(addr,
+bytearray(data.uint8.all()),
+error)
+
+def get_loaded_images(self):
+return self.loaded_images

Some functions have their parameter types and return types annotated but others 
don't. Can you add all the annotations to be consistent?



Comment at: 
lldb/test/API/functionalities/interactive_scripted_process/interactive_scripted_process.py:89
+def get_scripted_thread_plugin(self):
+return PassthruScriptedThread.__module__ + "." + 
PassthruScriptedThread.__name__
+





Comment at: 
lldb/test/API/functionalities/interactive_scripted_process/interactive_scripted_process.py:132
+def get_scripted_thread_plugin(self):
+return MultiplexedScriptedThread.__module__ + "." + 
MultiplexedScriptedThread.__name__
+





Comment at: 
lldb/test/API/functionalities/interactive_scripted_process/interactive_scripted_process.py:165
+def get_name(self) -> str:
+return PassthruScriptedThread.__name__ + ".thread-" + str(self.idx)
+





Comment at: 
lldb/test/API/functionalities/interactive_scripted_process/interactive_scripted_process.py:168
+def get_stop_reason(self) -> Dict[str, Any]:
+stop_reason = { "type": lldb.eStopReasonInvalid, "data": {  }}
+





Comment at: 
lldb/test/API/functionalities/interactive_scripted_process/interactive_scripted_process.py:204
+
+return struct.pack("{}Q".format(len(self.register_ctx)), 
*self.register_ctx.values())
+





Comment at: 
lldb/test/API/functionalities/interactive_scripted_process/interactive_scripted_process.py:209
+parity = "Odd" if self.scripted_process.parity % 2 else "Even"
+return parity + MultiplexedScriptedThread.__name__ + ".thread-" + 
str(self.idx)
+




=

[Lldb-commits] [PATCH] D145297: [lldb] Add an example of interactive scripted process debugging (NFC)

2023-03-03 Thread Med Ismail Bennani via Phabricator via lldb-commits
mib created this revision.
mib added reviewers: labath, JDevlieghere, jingham.
mib added a project: LLDB.
Herald added a project: All.
mib requested review of this revision.
Herald added a subscriber: lldb-commits.

This patch is a proof of concept that shows how a scripted process could
be used with real process to perform interactive debugging.

In this example, we run a process that spawns 10 threads. Then, we
create a intermediary scripted process who's job will be to wrap the
real process while intercepting it's process events and dispatching them
back either to the real process or to other child scripted processes.

In this example, we have 2 child scripted processes, with even and odd
thread indices. The goal is to be able to do thread filtering and
explore the various interactive debugging approaches, by letting a child
process running when stopping the other process and inspecting it.
Another approach would be to have the child processes execution in-sync
to force running every child process when one of them starts running.

Signed-off-by: Med Ismail Bennani 


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D145297

Files:
  lldb/test/API/functionalities/interactive_scripted_process/Makefile
  
lldb/test/API/functionalities/interactive_scripted_process/interactive_scripted_process.py
  lldb/test/API/functionalities/interactive_scripted_process/main.cpp

Index: lldb/test/API/functionalities/interactive_scripted_process/main.cpp
===
--- /dev/null
+++ lldb/test/API/functionalities/interactive_scripted_process/main.cpp
@@ -0,0 +1,35 @@
+#include 
+#include 
+#include 
+#include 
+#include 
+
+void spawn_thread(int index) {
+  std::string name = "I'm thread " + std::to_string(index) + " !";
+  bool done = false;
+  std::string state = "Started execution!";
+  while (true) {
+if (done) // also break here
+  break;
+  }
+
+  state = "Stopped execution!";
+}
+
+int main() {
+  size_t num_threads = 10;
+  std::vector threads;
+
+  for (size_t i = 0; i < num_threads; i++) {
+threads.push_back(std::thread(spawn_thread, i));
+  }
+
+  std::cout << "Spawned " << threads.size() << " threads!"; // Break here
+
+  for (auto &t : threads) {
+if (t.joinable())
+  t.join();
+  }
+
+  return 0;
+}
Index: lldb/test/API/functionalities/interactive_scripted_process/interactive_scripted_process.py
===
--- /dev/null
+++ lldb/test/API/functionalities/interactive_scripted_process/interactive_scripted_process.py
@@ -0,0 +1,349 @@
+# Usage:
+# ./bin/lldb $LLVM/lldb/test/API/functionalities/interactive_scripted_process/main \
+#   -o "br set -p 'Break here'" -o "run" \
+#   -o "command script import
+#   $LLVM/lldb/test/API/functionalities/interactive_scripted_process/interactive_scripted_process.py" \
+#   -o "br set -p 'also break here'" -o 'continue'
+
+import os,json,struct,signal
+
+from threading import Thread
+from typing import Any, Dict
+
+import lldb
+from lldb.plugins.scripted_process import ScriptedProcess
+from lldb.plugins.scripted_process import ScriptedThread
+
+class PassthruScriptedProcess(ScriptedProcess):
+driving_target = None
+driving_process = None
+
+def __init__(self, exe_ctx: lldb.SBExecutionContext, args : lldb.SBStructuredData):
+super().__init__(exe_ctx, args)
+
+self.driving_target = None
+self.driving_process = None
+
+self.driving_target_idx = args.GetValueForKey("driving_target_idx")
+if (self.driving_target_idx and self.driving_target_idx.IsValid()):
+if self.driving_target_idx.GetType() == lldb.eStructuredDataTypeInteger:
+idx = self.driving_target_idx.GetIntegerValue(42)
+if self.driving_target_idx.GetType() == lldb.eStructuredDataTypeString:
+idx = int(self.driving_target_idx.GetStringValue(100))
+self.driving_target = self.target.GetDebugger().GetTargetAtIndex(idx)
+self.driving_process = self.driving_target.GetProcess()
+for driving_thread in self.driving_process:
+structured_data = lldb.SBStructuredData()
+structured_data.SetFromJSON(json.dumps({
+"driving_target_idx" : idx,
+"thread_idx" : driving_thread.GetIndexID()
+}))
+
+self.threads[driving_thread.GetThreadID()] = PassthruScriptedThread(self, structured_data)
+
+for module in self.driving_target.modules:
+path = module.file.fullpath
+load_addr = module.GetObjectFileHeaderAddress().GetLoadAddress(self.driving_target)
+self.loaded_images.append({"path": path, "load_addr": load_addr})
+
+def get_memory_region_containing_address(self, addr: int) -> lldb.SBMemoryRegionInfo:
+mem_region = lldb.SBMemoryRegionInfo()
+error = self.driving_process.GetMemoryR

[Lldb-commits] [PATCH] D145297: [lldb] Add an example of interactive scripted process debugging (NFC)

2023-03-03 Thread Med Ismail Bennani via Phabricator via lldb-commits
mib added a comment.

This depends on D145294 , D145295 
 & D145296  
so make sure you take a look at those diffs :)


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D145297

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


[Lldb-commits] [PATCH] D145297: [lldb] Add an example of interactive scripted process debugging (NFC)

2023-03-13 Thread Med Ismail Bennani via Phabricator via lldb-commits
mib added a comment.

ping @JDevlieghere @jingham @labath


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D145297

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