[Lldb-commits] [PATCH] D153735: [lldb][TargetGetModuleCallback] Implement Python interface

2023-07-11 Thread Kazuki Sakamoto via Phabricator via lldb-commits
splhack updated this revision to Diff 539238.
splhack added a comment.

- Rename 'get module callback' to 'locate module callback'
- SBPlatform will do
  - capture callback(SBPlatformLocateModuleCallback) and baton(void *)
  - convert ModuleSpec/FileSpec from/to SBModuleSpec/SBFileSpec for calling the 
callback


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D153735

Files:
  lldb/bindings/python/python-typemaps.swig
  lldb/bindings/python/python-wrapper.swig
  lldb/include/lldb/API/SBDefines.h
  lldb/include/lldb/API/SBPlatform.h
  lldb/source/API/SBPlatform.cpp
  lldb/test/API/python_api/sbplatform/TestLocateModuleCallback.py

Index: lldb/test/API/python_api/sbplatform/TestLocateModuleCallback.py
===
--- /dev/null
+++ lldb/test/API/python_api/sbplatform/TestLocateModuleCallback.py
@@ -0,0 +1,338 @@
+"""
+Test platform locate module callback functionality
+"""
+
+import ctypes
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from pathlib import Path
+
+import lldb
+
+UNITTESTS_TARGET_INPUTS_PATH = "../../../../unittests/Target/Inputs"
+MODULE_PLATFORM_PATH = "/system/lib64/AndroidModule.so"
+MODULE_TRIPLE = "aarch64-none-linux"
+MODULE_RESOLVED_TRIPLE = "aarch64--linux-android"
+MODULE_UUID = "80008338-82A0-51E5-5922-C905D23890DA-BDDEFECC"
+MODULE_FUNCTION = "boom"
+MODULE_HIDDEN_FUNCTION = "boom_hidden"
+MODULE_FILE = "AndroidModule.so"
+MODULE_NON_EXISTENT_FILE = "non-existent-file"
+SYMBOL_FILE = "AndroidModule.unstripped.so"
+BREAKPAD_SYMBOL_FILE = "AndroidModule.so.sym"
+SYMBOL_STRIPPED = "stripped"
+SYMBOL_UNSTRIPPED = "unstripped"
+
+
+class LocateModuleCallbackTestCase(TestBase):
+def setUp(self):
+TestBase.setUp(self)
+self.platform = self.dbg.GetSelectedPlatform()
+self.target = self.dbg.CreateTarget("")
+self.assertTrue(self.target)
+
+self.input_dir = (
+Path(self.getSourceDir()) / UNITTESTS_TARGET_INPUTS_PATH
+).resolve()
+self.assertTrue(self.input_dir.is_dir())
+
+def check_module_spec(self, module_spec: lldb.SBModuleSpec):
+self.assertEqual(
+MODULE_UUID.replace("-", ""),
+ctypes.string_at(
+int(module_spec.GetUUIDBytes()),
+module_spec.GetUUIDLength(),
+)
+.hex()
+.upper(),
+)
+
+self.assertEqual(MODULE_TRIPLE, module_spec.GetTriple())
+
+self.assertEqual(MODULE_PLATFORM_PATH, module_spec.GetFileSpec().fullpath)
+
+def check_module(self, module: lldb.SBModule, symbol_file: str, symbol_kind: str):
+self.assertTrue(module.IsValid())
+
+self.assertEqual(
+MODULE_UUID,
+module.GetUUIDString(),
+)
+
+self.assertEqual(MODULE_RESOLVED_TRIPLE, module.GetTriple())
+
+self.assertEqual(MODULE_PLATFORM_PATH, module.GetPlatformFileSpec().fullpath)
+
+self.assertEqual(
+str(self.input_dir / MODULE_FILE),
+module.GetFileSpec().fullpath,
+)
+
+self.assertEqual(
+str(self.input_dir / symbol_file),
+module.GetSymbolFileSpec().fullpath,
+)
+
+sc_list = module.FindFunctions(MODULE_FUNCTION, lldb.eSymbolTypeCode)
+self.assertEqual(1, sc_list.GetSize())
+sc_list = module.FindFunctions(MODULE_HIDDEN_FUNCTION, lldb.eSymbolTypeCode)
+self.assertEqual(0 if symbol_kind == SYMBOL_STRIPPED else 1, sc_list.GetSize())
+
+def test_set_non_callable(self):
+# The callback should be callable.
+non_callable = "a"
+
+with self.assertRaises(TypeError, msg="Need a callable object or None!"):
+self.platform.SetLocateModuleCallback(non_callable)
+
+def test_set_wrong_args(self):
+# The callback should accept 3 argument.
+def test_args2(a, b):
+pass
+
+with self.assertRaises(TypeError, msg="Expected 3 argument callable object"):
+self.platform.SetLocateModuleCallback(test_args2)
+
+def test_default(self):
+# The default behavior is to locate the module with LLDB implementation
+# and AddModule should fail.
+module = self.target.AddModule(
+MODULE_PLATFORM_PATH,
+MODULE_TRIPLE,
+MODULE_UUID,
+)
+
+self.assertFalse(module)
+
+def test_set_none(self):
+# SetLocateModuleCallback should succeed to clear the callback with None.
+# and AddModule should fail.
+self.assertTrue(self.platform.SetLocateModuleCallback(None).Success())
+
+module = self.target.AddModule(
+MODULE_PLATFORM_PATH,
+MODULE_TRIPLE,
+MODULE_UUID,
+)
+
+self.assertFalse(module)
+
+def test_return_error(self):
+# The callback fails, AddModule should 

[Lldb-commits] [PATCH] D153735: [lldb][TargetGetModuleCallback] Implement Python interface

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

LGTM with @clayborg comments.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D153735

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


[Lldb-commits] [PATCH] D153735: [lldb][TargetGetModuleCallback] Implement Python interface

2023-07-10 Thread Kazuki Sakamoto via Phabricator via lldb-commits
splhack added inline comments.



Comment at: lldb/include/lldb/API/SBDefines.h:129
 
+typedef SBError (*SBTargetGetModuleCallback)(SBDebugger debugger,
+ SBModuleSpec _spec,

clayborg wrote:
> If we are putting this into SBPlatform, this should probably be named 
> "SBPlatformGetModuleCallback". 
> 
> The name might be a bit more clear if it was 
> "SBPlatformLocateModuleCallback"? Open to suggestions or fine to lave this as 
> "SBPlatformGetModuleCallback" if everyone likes that.
As commented on D153734, I'll rename it to `SBPlatformLocateModuleCallback`.

```
typedef SBError (*SBPlatformLocateModuleCallback)(
SBDebugger debugger,
SBModuleSpec _spec,
SBFileSpec _file_spec,
SBFileSpec _file_spec);
```



Comment at: lldb/include/lldb/API/SBPlatform.h:181
+  /// nullptr or None is set.
+  SBError SetTargetGetModuleCallback(lldb::SBTargetGetModuleCallback callback,
+ void *callback_baton);

clayborg wrote:
> remove "Target" from the function name? Or rename to 
> "SetLocateModuleCallback(...)" if we end up renaming the callback type to 
> SBPlatformLocateModuleCallback
I'll rename it to `SetLocateModuleCallback`.
```
SBError SetLocateModuleCallback(lldb::SBPlatformLocateModuleCallback callback,
   void *callback_baton);
```



Comment at: lldb/source/API/SBPlatform.cpp:668
+// Platform. 'callback_baton' is the actual callback Python callable 
object.
+platform_sp->SetTargetGetModuleCallback(callback_baton);
+return SBError();

clayborg wrote:
> You are not passing the "callback" into Platform::SetTargetGetModuleCallback??
> 
> Are we missing changes to the file "lldb/include/lldb/Target/Platform.h"? 
will update it to support C callback function as well as Python.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D153735

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


[Lldb-commits] [PATCH] D153735: [lldb][TargetGetModuleCallback] Implement Python interface

2023-07-10 Thread Greg Clayton via Phabricator via lldb-commits
clayborg added inline comments.



Comment at: lldb/include/lldb/API/SBDefines.h:129
 
+typedef SBError (*SBTargetGetModuleCallback)(SBDebugger debugger,
+ SBModuleSpec _spec,

If we are putting this into SBPlatform, this should probably be named 
"SBPlatformGetModuleCallback". 

The name might be a bit more clear if it was "SBPlatformLocateModuleCallback"? 
Open to suggestions or fine to lave this as "SBPlatformGetModuleCallback" if 
everyone likes that.



Comment at: lldb/include/lldb/API/SBPlatform.h:181
+  /// nullptr or None is set.
+  SBError SetTargetGetModuleCallback(lldb::SBTargetGetModuleCallback callback,
+ void *callback_baton);

remove "Target" from the function name? Or rename to 
"SetLocateModuleCallback(...)" if we end up renaming the callback type to 
SBPlatformLocateModuleCallback



Comment at: lldb/source/API/SBPlatform.cpp:668
+// Platform. 'callback_baton' is the actual callback Python callable 
object.
+platform_sp->SetTargetGetModuleCallback(callback_baton);
+return SBError();

You are not passing the "callback" into Platform::SetTargetGetModuleCallback??

Are we missing changes to the file "lldb/include/lldb/Target/Platform.h"? 


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D153735

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


[Lldb-commits] [PATCH] D153735: [lldb][TargetGetModuleCallback] Implement Python interface

2023-07-10 Thread Kazuki Sakamoto via Phabricator via lldb-commits
splhack updated this revision to Diff 538835.
splhack added a comment.

rebase


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D153735

Files:
  lldb/bindings/python/python-typemaps.swig
  lldb/bindings/python/python-wrapper.swig
  lldb/include/lldb/API/SBDefines.h
  lldb/include/lldb/API/SBPlatform.h
  lldb/source/API/SBPlatform.cpp
  lldb/source/Plugins/ScriptInterpreter/Python/SWIGPythonBridge.h
  lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp
  lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h
  lldb/test/API/python_api/target/TestGetModuleCallback.py
  lldb/unittests/ScriptInterpreter/Python/PythonTestSuite.cpp

Index: lldb/unittests/ScriptInterpreter/Python/PythonTestSuite.cpp
===
--- lldb/unittests/ScriptInterpreter/Python/PythonTestSuite.cpp
+++ lldb/unittests/ScriptInterpreter/Python/PythonTestSuite.cpp
@@ -321,3 +321,11 @@
 lldb_private::python::SWIGBridge::ToSWIGWrapper(lldb::DataExtractorSP) {
   return python::PythonObject();
 }
+
+Status
+lldb_private::python::SWIGBridge::LLDBSWIGPythonCallTargetGetModuleCallback(
+void *callback_baton, lldb::DebuggerSP debugger_sp,
+const ModuleSpec _spec, FileSpec _file_spec,
+FileSpec _file_spec) {
+  return Status();
+}
Index: lldb/test/API/python_api/target/TestGetModuleCallback.py
===
--- /dev/null
+++ lldb/test/API/python_api/target/TestGetModuleCallback.py
@@ -0,0 +1,303 @@
+"""
+Test Target get module callback functionality
+"""
+
+import ctypes
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from pathlib import Path
+
+import lldb
+
+UNITTESTS_TARGET_INPUTS_PATH = "../../../../unittests/Target/Inputs"
+MODULE_PLATFORM_PATH = "/system/lib64/AndroidModule.so"
+MODULE_TRIPLE = "aarch64-none-linux"
+MODULE_RESOLVED_TRIPLE = "aarch64--linux-android"
+MODULE_UUID = "80008338-82A0-51E5-5922-C905D23890DA-BDDEFECC"
+MODULE_FUNCTION = "boom"
+MODULE_HIDDEN_FUNCTION = "boom_hidden"
+MODULE_FILE = "AndroidModule.so"
+MODULE_NON_EXISTENT_FILE = "non-existent-file"
+SYMBOL_FILE = "AndroidModule.unstripped.so"
+BREAKPAD_SYMBOL_FILE = "AndroidModule.so.sym"
+SYMBOL_STRIPPED = "stripped"
+SYMBOL_UNSTRIPPED = "unstripped"
+
+
+class GetModuleCallbackTestCase(TestBase):
+def setUp(self):
+TestBase.setUp(self)
+self.platform = self.dbg.GetSelectedPlatform()
+self.target = self.dbg.CreateTarget("")
+self.assertTrue(self.target)
+
+self.input_dir = (
+Path(self.getSourceDir()) / UNITTESTS_TARGET_INPUTS_PATH
+).resolve()
+self.assertTrue(self.input_dir.is_dir())
+
+def check_module_spec(self, module_spec: lldb.SBModuleSpec):
+self.assertEqual(
+MODULE_UUID.replace("-", ""),
+ctypes.string_at(
+int(module_spec.GetUUIDBytes()),
+module_spec.GetUUIDLength(),
+)
+.hex()
+.upper(),
+)
+
+self.assertEqual(MODULE_TRIPLE, module_spec.GetTriple())
+
+self.assertEqual(MODULE_PLATFORM_PATH, module_spec.GetFileSpec().fullpath)
+
+def check_module(self, module: lldb.SBModule, symbol_file: str, symbol_kind: str):
+self.assertTrue(module.IsValid())
+
+self.assertEqual(
+MODULE_UUID,
+module.GetUUIDString(),
+)
+
+self.assertEqual(MODULE_RESOLVED_TRIPLE, module.GetTriple())
+
+self.assertEqual(MODULE_PLATFORM_PATH, module.GetPlatformFileSpec().fullpath)
+
+self.assertEqual(
+str(self.input_dir / MODULE_FILE),
+module.GetFileSpec().fullpath,
+)
+
+self.assertEqual(
+str(self.input_dir / symbol_file),
+module.GetSymbolFileSpec().fullpath,
+)
+
+sc_list = module.FindFunctions(MODULE_FUNCTION, lldb.eSymbolTypeCode)
+self.assertEqual(1, sc_list.GetSize())
+sc_list = module.FindFunctions(MODULE_HIDDEN_FUNCTION, lldb.eSymbolTypeCode)
+self.assertEqual(0 if symbol_kind == SYMBOL_STRIPPED else 1, sc_list.GetSize())
+
+def test_set_non_callable(self):
+# The callback should be callable.
+non_callable = "a"
+
+with self.assertRaises(TypeError, msg="Need a callable object or None!"):
+self.platform.SetTargetGetModuleCallback(non_callable)
+
+def test_set_wrong_args(self):
+# The callback should accept 4 argument.
+def test_args3(a, b, c):
+pass
+
+with self.assertRaises(TypeError, msg="Expected 4 argument callable object"):
+self.platform.SetTargetGetModuleCallback(test_args3)
+
+def test_set_none(self):
+# SetTargetGetModuleCallback should succeed to clear the callback with None.
+

[Lldb-commits] [PATCH] D153735: [lldb][TargetGetModuleCallback] Implement Python interface

2023-07-10 Thread Kazuki Sakamoto via Phabricator via lldb-commits
splhack updated this revision to Diff 538713.
splhack added a comment.

rebase


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D153735

Files:
  lldb/bindings/python/python-typemaps.swig
  lldb/bindings/python/python-wrapper.swig
  lldb/include/lldb/API/SBDefines.h
  lldb/include/lldb/API/SBPlatform.h
  lldb/source/API/SBPlatform.cpp
  lldb/source/Plugins/ScriptInterpreter/Python/SWIGPythonBridge.h
  lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp
  lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h
  lldb/test/API/python_api/target/TestGetModuleCallback.py
  lldb/unittests/ScriptInterpreter/Python/PythonTestSuite.cpp

Index: lldb/unittests/ScriptInterpreter/Python/PythonTestSuite.cpp
===
--- lldb/unittests/ScriptInterpreter/Python/PythonTestSuite.cpp
+++ lldb/unittests/ScriptInterpreter/Python/PythonTestSuite.cpp
@@ -321,3 +321,11 @@
 lldb_private::python::SWIGBridge::ToSWIGWrapper(lldb::DataExtractorSP) {
   return python::PythonObject();
 }
+
+Status
+lldb_private::python::SWIGBridge::LLDBSWIGPythonCallTargetGetModuleCallback(
+void *callback_baton, lldb::DebuggerSP debugger_sp,
+const ModuleSpec _spec, FileSpec _file_spec,
+FileSpec _file_spec) {
+  return Status();
+}
Index: lldb/test/API/python_api/target/TestGetModuleCallback.py
===
--- /dev/null
+++ lldb/test/API/python_api/target/TestGetModuleCallback.py
@@ -0,0 +1,303 @@
+"""
+Test Target get module callback functionality
+"""
+
+import ctypes
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from pathlib import Path
+
+import lldb
+
+UNITTESTS_TARGET_INPUTS_PATH = "../../../../unittests/Target/Inputs"
+MODULE_PLATFORM_PATH = "/system/lib64/AndroidModule.so"
+MODULE_TRIPLE = "aarch64-none-linux"
+MODULE_RESOLVED_TRIPLE = "aarch64--linux-android"
+MODULE_UUID = "80008338-82A0-51E5-5922-C905D23890DA-BDDEFECC"
+MODULE_FUNCTION = "boom"
+MODULE_HIDDEN_FUNCTION = "boom_hidden"
+MODULE_FILE = "AndroidModule.so"
+MODULE_NON_EXISTENT_FILE = "non-existent-file"
+SYMBOL_FILE = "AndroidModule.unstripped.so"
+BREAKPAD_SYMBOL_FILE = "AndroidModule.so.sym"
+SYMBOL_STRIPPED = "stripped"
+SYMBOL_UNSTRIPPED = "unstripped"
+
+
+class GetModuleCallbackTestCase(TestBase):
+def setUp(self):
+TestBase.setUp(self)
+self.platform = self.dbg.GetSelectedPlatform()
+self.target = self.dbg.CreateTarget("")
+self.assertTrue(self.target)
+
+self.input_dir = (
+Path(self.getSourceDir()) / UNITTESTS_TARGET_INPUTS_PATH
+).resolve()
+self.assertTrue(self.input_dir.is_dir())
+
+def check_module_spec(self, module_spec: lldb.SBModuleSpec):
+self.assertEqual(
+MODULE_UUID.replace("-", ""),
+ctypes.string_at(
+int(module_spec.GetUUIDBytes()),
+module_spec.GetUUIDLength(),
+)
+.hex()
+.upper(),
+)
+
+self.assertEqual(MODULE_TRIPLE, module_spec.GetTriple())
+
+self.assertEqual(MODULE_PLATFORM_PATH, module_spec.GetFileSpec().fullpath)
+
+def check_module(self, module: lldb.SBModule, symbol_file: str, symbol_kind: str):
+self.assertTrue(module.IsValid())
+
+self.assertEqual(
+MODULE_UUID,
+module.GetUUIDString(),
+)
+
+self.assertEqual(MODULE_RESOLVED_TRIPLE, module.GetTriple())
+
+self.assertEqual(MODULE_PLATFORM_PATH, module.GetPlatformFileSpec().fullpath)
+
+self.assertEqual(
+str(self.input_dir / MODULE_FILE),
+module.GetFileSpec().fullpath,
+)
+
+self.assertEqual(
+str(self.input_dir / symbol_file),
+module.GetSymbolFileSpec().fullpath,
+)
+
+sc_list = module.FindFunctions(MODULE_FUNCTION, lldb.eSymbolTypeCode)
+self.assertEqual(1, sc_list.GetSize())
+sc_list = module.FindFunctions(MODULE_HIDDEN_FUNCTION, lldb.eSymbolTypeCode)
+self.assertEqual(0 if symbol_kind == SYMBOL_STRIPPED else 1, sc_list.GetSize())
+
+def test_set_non_callable(self):
+# The callback should be callable.
+non_callable = "a"
+
+with self.assertRaises(TypeError, msg="Need a callable object or None!"):
+self.platform.SetTargetGetModuleCallback(non_callable)
+
+def test_set_wrong_args(self):
+# The callback should accept 4 argument.
+def test_args3(a, b, c):
+pass
+
+with self.assertRaises(TypeError, msg="Expected 4 argument callable object"):
+self.platform.SetTargetGetModuleCallback(test_args3)
+
+def test_set_none(self):
+# SetTargetGetModuleCallback should succeed to clear the callback with None.
+

[Lldb-commits] [PATCH] D153735: [lldb][TargetGetModuleCallback] Implement Python interface

2023-06-26 Thread Kazuki Sakamoto via Phabricator via lldb-commits
splhack updated this revision to Diff 534804.
splhack added a comment.

Move SetTargetGetModuleCallback from SBDebugger to SBPlatform.
https://discourse.llvm.org/t/rfc-python-callback-for-target-get-module/71580/4?u=splhack


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D153735

Files:
  lldb/bindings/python/python-typemaps.swig
  lldb/bindings/python/python-wrapper.swig
  lldb/include/lldb/API/SBDefines.h
  lldb/include/lldb/API/SBPlatform.h
  lldb/source/API/SBPlatform.cpp
  lldb/source/Plugins/ScriptInterpreter/Python/SWIGPythonBridge.h
  lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp
  lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h
  lldb/test/API/python_api/target/TestGetModuleCallback.py
  lldb/unittests/ScriptInterpreter/Python/PythonTestSuite.cpp

Index: lldb/unittests/ScriptInterpreter/Python/PythonTestSuite.cpp
===
--- lldb/unittests/ScriptInterpreter/Python/PythonTestSuite.cpp
+++ lldb/unittests/ScriptInterpreter/Python/PythonTestSuite.cpp
@@ -321,3 +321,11 @@
 lldb_private::python::SWIGBridge::ToSWIGWrapper(lldb::DataExtractorSP) {
   return python::PythonObject();
 }
+
+Status
+lldb_private::python::SWIGBridge::LLDBSWIGPythonCallTargetGetModuleCallback(
+void *callback_baton, lldb::DebuggerSP debugger_sp,
+const ModuleSpec _spec, FileSpec _file_spec,
+FileSpec _file_spec) {
+  return Status();
+}
Index: lldb/test/API/python_api/target/TestGetModuleCallback.py
===
--- /dev/null
+++ lldb/test/API/python_api/target/TestGetModuleCallback.py
@@ -0,0 +1,303 @@
+"""
+Test Target get module callback functionality
+"""
+
+import ctypes
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from pathlib import Path
+
+import lldb
+
+UNITTESTS_TARGET_INPUTS_PATH = "../../../../unittests/Target/Inputs"
+MODULE_PLATFORM_PATH = "/system/lib64/AndroidModule.so"
+MODULE_TRIPLE = "aarch64-none-linux"
+MODULE_RESOLVED_TRIPLE = "aarch64--linux-android"
+MODULE_UUID = "80008338-82A0-51E5-5922-C905D23890DA-BDDEFECC"
+MODULE_FUNCTION = "boom"
+MODULE_HIDDEN_FUNCTION = "boom_hidden"
+MODULE_FILE = "AndroidModule.so"
+MODULE_NON_EXISTENT_FILE = "non-existent-file"
+SYMBOL_FILE = "AndroidModule.unstripped.so"
+BREAKPAD_SYMBOL_FILE = "AndroidModule.so.sym"
+SYMBOL_STRIPPED = "stripped"
+SYMBOL_UNSTRIPPED = "unstripped"
+
+
+class GetModuleCallbackTestCase(TestBase):
+def setUp(self):
+TestBase.setUp(self)
+self.platform = self.dbg.GetSelectedPlatform()
+self.target = self.dbg.CreateTarget("")
+self.assertTrue(self.target)
+
+self.input_dir = (
+Path(self.getSourceDir()) / UNITTESTS_TARGET_INPUTS_PATH
+).resolve()
+self.assertTrue(self.input_dir.is_dir())
+
+def check_module_spec(self, module_spec: lldb.SBModuleSpec):
+self.assertEqual(
+MODULE_UUID.replace("-", ""),
+ctypes.string_at(
+int(module_spec.GetUUIDBytes()),
+module_spec.GetUUIDLength(),
+)
+.hex()
+.upper(),
+)
+
+self.assertEqual(MODULE_TRIPLE, module_spec.GetTriple())
+
+self.assertEqual(MODULE_PLATFORM_PATH, module_spec.GetFileSpec().fullpath)
+
+def check_module(self, module: lldb.SBModule, symbol_file: str, symbol_kind: str):
+self.assertTrue(module.IsValid())
+
+self.assertEqual(
+MODULE_UUID,
+module.GetUUIDString(),
+)
+
+self.assertEqual(MODULE_RESOLVED_TRIPLE, module.GetTriple())
+
+self.assertEqual(MODULE_PLATFORM_PATH, module.GetPlatformFileSpec().fullpath)
+
+self.assertEqual(
+str(self.input_dir / MODULE_FILE),
+module.GetFileSpec().fullpath,
+)
+
+self.assertEqual(
+str(self.input_dir / symbol_file),
+module.GetSymbolFileSpec().fullpath,
+)
+
+sc_list = module.FindFunctions(MODULE_FUNCTION, lldb.eSymbolTypeCode)
+self.assertEqual(1, sc_list.GetSize())
+sc_list = module.FindFunctions(MODULE_HIDDEN_FUNCTION, lldb.eSymbolTypeCode)
+self.assertEqual(0 if symbol_kind == SYMBOL_STRIPPED else 1, sc_list.GetSize())
+
+def test_set_non_callable(self):
+# The callback should be callable.
+non_callable = "a"
+
+with self.assertRaises(TypeError, msg="Need a callable object or None!"):
+self.platform.SetTargetGetModuleCallback(non_callable)
+
+def test_set_wrong_args(self):
+# The callback should accept 4 argument.
+def test_args3(a, b, c):
+pass
+
+with self.assertRaises(TypeError, msg="Expected 4 argument callable object"):
+self.platform.SetTargetGetModuleCallback(test_args3)
+
+def 

[Lldb-commits] [PATCH] D153735: [lldb][TargetGetModuleCallback] Implement Python interface

2023-06-25 Thread Kazuki Sakamoto via Phabricator via lldb-commits
splhack created this revision.
Herald added a project: All.
splhack requested review of this revision.
Herald added a project: LLDB.
Herald added a subscriber: lldb-commits.

RFC https://discourse.llvm.org/t/rfc-python-callback-for-target-get-module/71580

Use SWIG for the target get module callback the same as other Python callbacks.
TestGetModuleCallback.py verifies the functionalities.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D153735

Files:
  lldb/bindings/python/python-typemaps.swig
  lldb/bindings/python/python-wrapper.swig
  lldb/include/lldb/API/SBDebugger.h
  lldb/include/lldb/API/SBDefines.h
  lldb/source/API/SBDebugger.cpp
  lldb/source/Plugins/ScriptInterpreter/Python/SWIGPythonBridge.h
  lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp
  lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h
  lldb/test/API/python_api/target/TestGetModuleCallback.py
  lldb/unittests/ScriptInterpreter/Python/PythonTestSuite.cpp

Index: lldb/unittests/ScriptInterpreter/Python/PythonTestSuite.cpp
===
--- lldb/unittests/ScriptInterpreter/Python/PythonTestSuite.cpp
+++ lldb/unittests/ScriptInterpreter/Python/PythonTestSuite.cpp
@@ -321,3 +321,11 @@
 lldb_private::python::SWIGBridge::ToSWIGWrapper(lldb::DataExtractorSP) {
   return python::PythonObject();
 }
+
+Status
+lldb_private::python::SWIGBridge::LLDBSWIGPythonCallTargetGetModuleCallback(
+void *callback_baton, lldb::DebuggerSP debugger_sp,
+const ModuleSpec _spec, FileSpec _file_spec,
+FileSpec _file_spec) {
+  return Status();
+}
Index: lldb/test/API/python_api/target/TestGetModuleCallback.py
===
--- /dev/null
+++ lldb/test/API/python_api/target/TestGetModuleCallback.py
@@ -0,0 +1,288 @@
+"""
+Test Target get module callback functionality
+"""
+
+import ctypes
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from pathlib import Path
+
+import lldb
+
+UNITTESTS_TARGET_INPUTS_PATH = "../../../../unittests/Target/Inputs"
+MODULE_PLATFORM_PATH = "/system/lib64/AndroidModule.so"
+MODULE_TRIPLE = "aarch64-none-linux"
+MODULE_RESOLVED_TRIPLE = "aarch64--linux-android"
+MODULE_UUID = "80008338-82A0-51E5-5922-C905D23890DA-BDDEFECC"
+MODULE_FUNCTION = "boom"
+MODULE_HIDDEN_FUNCTION = "boom_hidden"
+MODULE_FILE = "AndroidModule.so"
+MODULE_NON_EXISTENT_FILE = "non-existent-file"
+SYMBOL_FILE = "AndroidModule.unstripped.so"
+BREAKPAD_SYMBOL_FILE = "AndroidModule.so.sym"
+SYMBOL_STRIPPED = "stripped"
+SYMBOL_UNSTRIPPED = "unstripped"
+
+
+class GetModuleCallbackTestCase(TestBase):
+def setUp(self):
+TestBase.setUp(self)
+self.target = self.dbg.CreateTarget("")
+self.assertTrue(self.target)
+
+self.input_dir = (
+Path(self.getSourceDir()) / UNITTESTS_TARGET_INPUTS_PATH
+).resolve()
+self.assertTrue(self.input_dir.is_dir())
+
+def check_module_spec(self, module_spec: lldb.SBModuleSpec):
+self.assertEqual(
+MODULE_UUID.replace("-", ""),
+ctypes.string_at(
+int(module_spec.GetUUIDBytes()),
+module_spec.GetUUIDLength(),
+)
+.hex()
+.upper(),
+)
+
+self.assertEqual(MODULE_TRIPLE, module_spec.GetTriple())
+
+self.assertEqual(MODULE_PLATFORM_PATH, module_spec.GetFileSpec().fullpath)
+
+def check_module(self, module: lldb.SBModule, symbol_file: str, symbol_kind: str):
+self.assertTrue(module.IsValid())
+
+self.assertEqual(
+MODULE_UUID,
+module.GetUUIDString(),
+)
+
+self.assertEqual(MODULE_RESOLVED_TRIPLE, module.GetTriple())
+
+self.assertEqual(MODULE_PLATFORM_PATH, module.GetPlatformFileSpec().fullpath)
+
+self.assertEqual(
+str(self.input_dir / MODULE_FILE),
+module.GetFileSpec().fullpath,
+)
+
+self.assertEqual(
+str(self.input_dir / symbol_file),
+module.GetSymbolFileSpec().fullpath,
+)
+
+sc_list = module.FindFunctions(MODULE_FUNCTION, lldb.eSymbolTypeCode)
+self.assertEqual(1, sc_list.GetSize())
+sc_list = module.FindFunctions(MODULE_HIDDEN_FUNCTION, lldb.eSymbolTypeCode)
+self.assertEqual(0 if symbol_kind == SYMBOL_STRIPPED else 1, sc_list.GetSize())
+
+def test_set_non_callable(self):
+# The callback should be callable.
+non_callable = "a"
+
+with self.assertRaises(TypeError, msg="Need a callable object or None!"):
+self.dbg.SetTargetGetModuleCallback(non_callable)
+
+def test_set_wrong_args(self):
+# The callback should accept 4 argument.
+def test_args3(a, b, c):
+pass
+
+with self.assertRaises(TypeError, msg="Expected 4 argument callable object"):
+