siger-young updated this revision to Diff 395076.
siger-young added a comment.

Remove "return" to prevent memory leakage.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D115926

Files:
  lldb/bindings/interface/SBBreakpoint.i
  lldb/bindings/lua/lua-typemaps.swig
  lldb/bindings/lua/lua-wrapper.swig
  lldb/include/lldb/API/SBBreakpoint.h
  lldb/include/lldb/API/SBBreakpointOptionCommon.h
  lldb/include/lldb/API/SBDefines.h
  lldb/source/API/SBBreakpoint.cpp
  lldb/source/API/SBBreakpointName.cpp
  lldb/source/API/SBBreakpointOptionCommon.cpp
  lldb/source/API/SBBreakpointOptionCommon.h
  lldb/test/API/lua_api/TestBreakpointAPI.lua

Index: lldb/test/API/lua_api/TestBreakpointAPI.lua
===================================================================
--- lldb/test/API/lua_api/TestBreakpointAPI.lua
+++ lldb/test/API/lua_api/TestBreakpointAPI.lua
@@ -49,4 +49,20 @@
     assertEquals(var_argc_value, 3)
 end
 
+function _T:TestBreakpointRealCallback()
+    local target = self:create_target()
+    local breakpoint = target:BreakpointCreateByLocation('main.c', 31)
+    assertTrue(breakpoint:IsValid() and breakpoint:GetNumLocations() == 1)
+    local flag = false
+    local i = 1
+    breakpoint:SetScriptCallback(function(frame)
+        flag = true
+        assertEquals(frame:FindVariable('i'):GetValueAsSigned(), i)
+        i = i + 1
+        return false
+    end)
+    target:LaunchSimple(nil, nil, nil)
+    assertTrue(flag)
+end
+
 os.exit(_T:run())
Index: lldb/source/API/SBBreakpointOptionCommon.h
===================================================================
--- lldb/source/API/SBBreakpointOptionCommon.h
+++ /dev/null
@@ -1,36 +0,0 @@
-//===-- SBBreakpointOptionCommon.h ------------------------------------------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLDB_SOURCE_API_SBBREAKPOINTOPTIONCOMMON_H
-#define LLDB_SOURCE_API_SBBREAKPOINTOPTIONCOMMON_H
-
-#include "lldb/API/SBDefines.h"
-#include "lldb/Utility/Baton.h"
-
-namespace lldb
-{
-struct CallbackData {
-  SBBreakpointHitCallback callback;
-  void *callback_baton;
-};
-
-class SBBreakpointCallbackBaton : public lldb_private::TypedBaton<CallbackData> {
-public:
-  SBBreakpointCallbackBaton(SBBreakpointHitCallback callback,
-                            void *baton);
-
-  ~SBBreakpointCallbackBaton() override;
-
-  static bool PrivateBreakpointHitCallback(void *baton,
-                                           lldb_private::StoppointCallbackContext *ctx,
-                                           lldb::user_id_t break_id,
-                                           lldb::user_id_t break_loc_id);
-};
-
-} // namespace lldb
-#endif // LLDB_SOURCE_API_SBBREAKPOINTOPTIONCOMMON_H
Index: lldb/source/API/SBBreakpointOptionCommon.cpp
===================================================================
--- lldb/source/API/SBBreakpointOptionCommon.cpp
+++ lldb/source/API/SBBreakpointOptionCommon.cpp
@@ -6,8 +6,9 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "lldb/API/SBBreakpointName.h"
+#include "lldb/API/SBBreakpointOptionCommon.h"
 #include "lldb/API/SBBreakpointLocation.h"
+#include "lldb/API/SBBreakpointName.h"
 #include "lldb/API/SBDebugger.h"
 #include "lldb/API/SBEvent.h"
 #include "lldb/API/SBProcess.h"
@@ -31,13 +32,15 @@
 
 #include "lldb/lldb-enumerations.h"
 
-#include "SBBreakpointOptionCommon.h"
-
 #include "llvm/ADT/STLExtras.h"
 
 using namespace lldb;
 using namespace lldb_private;
 
+SBBreakpointCallbackBaton::SBBreakpointCallbackBaton(
+    std::unique_ptr<CallbackData> Data)
+    : TypedBaton(std::move(Data)) {}
+
 SBBreakpointCallbackBaton::SBBreakpointCallbackBaton(SBBreakpointHitCallback 
                                                          callback,
                                                      void *baton)
@@ -52,26 +55,18 @@
                                                   lldb::user_id_t break_loc_id)
 {
   ExecutionContext exe_ctx(ctx->exe_ctx_ref);
+  SBFrame sb_frame(exe_ctx.GetFrameSP());
   BreakpointSP bp_sp(
       exe_ctx.GetTargetRef().GetBreakpointList().FindBreakpointByID(break_id));
   if (baton && bp_sp) {
     CallbackData *data = (CallbackData *)baton;
     lldb_private::Breakpoint *bp = bp_sp.get();
-    if (bp && data->callback) {
-      Process *process = exe_ctx.GetProcessPtr();
-      if (process) {
-        SBProcess sb_process(process->shared_from_this());
-        SBThread sb_thread;
-        SBBreakpointLocation sb_location;
-        assert(bp_sp);
-        sb_location.SetLocation(bp_sp->FindLocationByID(break_loc_id));
-        Thread *thread = exe_ctx.GetThreadPtr();
-        if (thread)
-          sb_thread.SetThread(thread->shared_from_this());
 
-        return data->callback(data->callback_baton, sb_process, sb_thread,
-                              sb_location);
-      }
+    if (bp && data->callback) {
+      SBBreakpointLocation sb_bp_loc;
+      assert(bp_sp);
+      sb_bp_loc.SetLocation(bp_sp->FindLocationByID(break_loc_id));
+      return data->callback(data->callback_baton, sb_frame, sb_bp_loc);
     }
   }
   return true; // Return true if we should stop at this breakpoint
Index: lldb/source/API/SBBreakpointName.cpp
===================================================================
--- lldb/source/API/SBBreakpointName.cpp
+++ lldb/source/API/SBBreakpointName.cpp
@@ -8,6 +8,7 @@
 
 #include "lldb/API/SBBreakpointName.h"
 #include "SBReproducerPrivate.h"
+#include "lldb/API/SBBreakpointOptionCommon.h"
 #include "lldb/API/SBDebugger.h"
 #include "lldb/API/SBError.h"
 #include "lldb/API/SBStream.h"
@@ -25,8 +26,6 @@
 #include "lldb/Target/ThreadSpec.h"
 #include "lldb/Utility/Stream.h"
 
-#include "SBBreakpointOptionCommon.h"
-
 using namespace lldb;
 using namespace lldb_private;
 
Index: lldb/source/API/SBBreakpoint.cpp
===================================================================
--- lldb/source/API/SBBreakpoint.cpp
+++ lldb/source/API/SBBreakpoint.cpp
@@ -9,6 +9,7 @@
 #include "lldb/API/SBBreakpoint.h"
 #include "SBReproducerPrivate.h"
 #include "lldb/API/SBBreakpointLocation.h"
+#include "lldb/API/SBBreakpointOptionCommon.h"
 #include "lldb/API/SBDebugger.h"
 #include "lldb/API/SBEvent.h"
 #include "lldb/API/SBProcess.h"
@@ -36,8 +37,6 @@
 #include "lldb/Target/ThreadSpec.h"
 #include "lldb/Utility/Stream.h"
 
-#include "SBBreakpointOptionCommon.h"
-
 #include "lldb/lldb-enumerations.h"
 
 #include "llvm/ADT/STLExtras.h"
@@ -616,6 +615,21 @@
   }
 }
 
+void SBBreakpoint::SetScriptCallback(const SBBreakpointCallbackBatonSP &baton_sp) {
+  LLDB_RECORD_METHOD(void, SBBreakpoint, SetScriptCallback,
+                     (const SBBreakpointCallbackBatonSP &), baton_sp);
+
+  BreakpointSP bkpt_sp = GetSP();
+
+  if (bkpt_sp) {
+    std::lock_guard<std::recursive_mutex> guard(
+        bkpt_sp->GetTarget().GetAPIMutex());
+    bkpt_sp->SetCallback(
+        SBBreakpointCallbackBaton ::PrivateBreakpointHitCallback, baton_sp,
+        false);
+  }
+}
+
 void SBBreakpoint::SetScriptCallbackFunction(
   const char *callback_function_name) {
 LLDB_RECORD_METHOD(void, SBBreakpoint, SetScriptCallbackFunction,
@@ -1045,6 +1059,8 @@
                        (lldb::SBAddress &));
   LLDB_REGISTER_METHOD(lldb::SBStructuredData, SBBreakpoint,
                        SerializeToStructuredData, ());
+  LLDB_REGISTER_METHOD(void, SBBreakpoint, SetScriptCallback,
+                       (const SBBreakpointCallbackBatonSP &));
   LLDB_REGISTER_METHOD(void, SBBreakpoint, SetScriptCallbackFunction,
                        (const char *));
   LLDB_REGISTER_METHOD(lldb::SBError, SBBreakpoint, SetScriptCallbackFunction,
Index: lldb/include/lldb/API/SBDefines.h
===================================================================
--- lldb/include/lldb/API/SBDefines.h
+++ lldb/include/lldb/API/SBDefines.h
@@ -94,9 +94,8 @@
 class LLDB_API SBWatchpoint;
 class LLDB_API SBUnixSignals;
 
-typedef bool (*SBBreakpointHitCallback)(void *baton, SBProcess &process,
-                                        SBThread &thread,
-                                        lldb::SBBreakpointLocation &location);
+typedef bool (*SBBreakpointHitCallback)(void *baton, SBFrame &sb_frame,
+                                        SBBreakpointLocation &sb_bp_loc);
 }
 
 #endif // LLDB_API_SBDEFINES_H
Index: lldb/include/lldb/API/SBBreakpointOptionCommon.h
===================================================================
--- /dev/null
+++ lldb/include/lldb/API/SBBreakpointOptionCommon.h
@@ -0,0 +1,40 @@
+//===-- SBBreakpointOptionCommon.h ------------------------------------------*-
+// C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_API_SBBREAKPOINTOPTIONCOMMON_H
+#define LLDB_API_SBBREAKPOINTOPTIONCOMMON_H
+
+#include "lldb/API/SBDefines.h"
+#include "lldb/Utility/Baton.h"
+
+namespace lldb {
+struct CallbackData {
+  SBBreakpointHitCallback callback;
+  void *callback_baton;
+
+  virtual ~CallbackData() = default;
+};
+
+class SBBreakpointCallbackBaton
+    : public lldb_private::TypedBaton<CallbackData> {
+public:
+  explicit SBBreakpointCallbackBaton(std::unique_ptr<CallbackData> Data);
+  SBBreakpointCallbackBaton(SBBreakpointHitCallback callback, void *baton);
+
+  ~SBBreakpointCallbackBaton() override;
+
+  static bool PrivateBreakpointHitCallback(
+      void *baton, lldb_private::StoppointCallbackContext *ctx,
+      lldb::user_id_t break_id, lldb::user_id_t break_loc_id);
+};
+
+typedef std::shared_ptr<SBBreakpointCallbackBaton> SBBreakpointCallbackBatonSP;
+
+} // namespace lldb
+#endif // LLDB_API_SBBREAKPOINTOPTIONCOMMON_H
Index: lldb/include/lldb/API/SBBreakpoint.h
===================================================================
--- lldb/include/lldb/API/SBBreakpoint.h
+++ lldb/include/lldb/API/SBBreakpoint.h
@@ -9,6 +9,7 @@
 #ifndef LLDB_API_SBBREAKPOINT_H
 #define LLDB_API_SBBREAKPOINT_H
 
+#include "lldb/API/SBBreakpointOptionCommon.h"
 #include "lldb/API/SBDefines.h"
 
 class SBBreakpointListImpl;
@@ -94,6 +95,8 @@
 
   void SetCallback(SBBreakpointHitCallback callback, void *baton);
 
+  void SetScriptCallback(const SBBreakpointCallbackBatonSP &baton_sp);
+
   void SetScriptCallbackFunction(const char *callback_function_name);
 
   SBError SetScriptCallbackFunction(const char *callback_function_name,
Index: lldb/bindings/lua/lua-wrapper.swig
===================================================================
--- lldb/bindings/lua/lua-wrapper.swig
+++ lldb/bindings/lua/lua-wrapper.swig
@@ -98,4 +98,52 @@
    return luaL_error(L, "You cannot close a file handle used by lldb.");
 }
 
+// These are external callback wrappers.
+
+bool SBBreakpointHitCallbackLua(
+   void *baton,
+   SBFrame &sb_frame,
+   SBBreakpointLocation &sb_bp_loc
+);
+
+struct CallbackDataLua : public CallbackData {
+public:
+   CallbackDataLua(lua_State *l) : L(l) {
+      callback = SBBreakpointHitCallbackLua;
+      callback_baton = (void *) this;
+   }
+   lua_State *L;
+};
+
+
+bool SBBreakpointHitCallbackLua(
+   void *baton,
+   SBFrame &sb_frame,
+   SBBreakpointLocation &sb_bp_loc
+)
+{
+   auto data = (CallbackDataLua *) baton;
+
+   lua_State *L = data->L;
+   lua_pushlightuserdata(L, data);
+   lua_gettable(L, LUA_REGISTRYINDEX);
+   int nargs = 2;
+
+   // Push the Lua wrappers
+   PushSBClass(L, &sb_frame);
+   PushSBClass(L, &sb_bp_loc);
+
+   // Call into the Lua callback passing 'sb_frame' and 'sb_wp'.
+   if (lua_pcall(L, nargs, 1, 0) != LUA_OK) {
+      luaL_error(L, "%s", lua_tostring(L, -1));
+      return true;
+   }
+
+   // Boolean return from the callback
+   bool stop = lua_toboolean(L, -1);
+   lua_pop(L, 1);
+
+   return stop;
+}
+
 %}
Index: lldb/bindings/lua/lua-typemaps.swig
===================================================================
--- lldb/bindings/lua/lua-typemaps.swig
+++ lldb/bindings/lua/lua-typemaps.swig
@@ -314,3 +314,29 @@
 }
 
 //===----------------------------------------------------------------------===//
+
+// Typemap for closure callback in external scripting environment
+
+%typemap(arginit) const SBBreakpointCallbackBatonSP &baton_sp {
+   // We could `SBBreakpointCallbackBatonSP baton_sp;` inside "%typemap(in)"
+   // but SWIG puts "%typemap(in)" part and the real call in 2 *different* scopes
+   // so the smart pointer destructs earlier than it is used by the call.
+   $1 = new SBBreakpointCallbackBatonSP();
+}
+
+%typemap(in) const SBBreakpointCallbackBatonSP &baton_sp {
+   if (lua_isfunction(L, $input)) {
+      auto data_up = std::make_unique<CallbackDataLua>(L);
+      lua_pushlightuserdata(L, data_up.get());
+      lua_pushvalue(L, $input);
+      lua_settable(L, LUA_REGISTRYINDEX);
+      *$1 = std::make_shared<SBBreakpointCallbackBaton>(std::move(data_up));
+   }
+   else {
+      luaL_error(L, "Expect a Lua function.");
+   }
+}
+
+%typemap(freearg) const SBBreakpointCallbackBatonSP &baton_sp {
+   free($1);
+}
Index: lldb/bindings/interface/SBBreakpoint.i
===================================================================
--- lldb/bindings/interface/SBBreakpoint.i
+++ lldb/bindings/interface/SBBreakpoint.i
@@ -177,6 +177,11 @@
     const char *
     GetQueueName () const;
 
+    %feature("docstring", "
+    Set a specific closure to be called when the breakpoint is hit.") SetScriptCallback;
+    void
+    SetScriptCallback (const SBBreakpointCallbackBatonSP &baton_sp);
+
     %feature("docstring", "
     Set the name of the script function to be called when the breakpoint is hit.") SetScriptCallbackFunction;
     void
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to