jimingham wrote: We don't have SB API's currently for the stop-hooks yet, so we're free to invent them.
But my notion was something like this: class ScriptedHookDefinition { void SetScriptingLanguage(lldb::ScriptLanguage lang); void SetScriptClassName(const char *script_class_name); void SetMethodName(const char *hook_method_name); }; Then for stop hooks that have a lot of "when to stop" as opposed to "what to do when you stop" options: // Stop Hook Filtering and AutoContinue Options class StopHookOptions { SetShlibFilter SetFunctionNameFilter SetAutoContinue etc... }; Then an opaque class that we will use to find the instance of the class that backs this particular hook: class HookInstance { } Then in Target, we'd add: class Target { ... HookInstance SetStopHook(HookDefinition definition, StopHookOptions &options) ... }; Internally, lldb will do what is currently already does, instantiate an instance of script_class_name to handle this hook stash that away somewhere. But we'll add a return that allows us to look up the implementation object, that's the HookInstance class. Then, when we hit a stop for this target, we go through the stop hook instances and dispatches to the method in hook_method_name. This is something we also already know how to do (at least for the Python scripting language), we just hard-coding the name to `__call__`... So that shouldn't be hard. If we had another hook, like ModulesLoaded, then we'd do: class Target { ... HookInstance SetModulesLoadedHook(HookDefinition definition, ModuleLoadedHookOptions &options) ... }; I don't know whether we'll end up needing separate "HookOptions" class, but the stop hooks can filter in a lot of ways that wouldn't make sense for module loaded, so it's likely good to separate those out. Again, internally lldb would do the same thing it currently does for Target Stop Hooks, it would make an instance (held in the Target) of the python class and when modules were loaded, would call that instance's hook_method_name. Then the point of the HookInstance is that we'd add to the HookDefinition: HookDefinition::SetHookInstance(HookInstance instance) If we make a hook using a HookDefinition with a valid instance set, then instead of making a new instance of the `script_class_name` to handle this hook, we'll reuse the instance returned by the call that created the SBHookInstance, in our list of ModulesLoaded handlers, using the hook_method_name from the HookDefinition for this new hook. We also need to handle init methods in the case where we are sharing an instance, because you might for instance want to pass different information to set up the various hooks (e.g. different extra_args). We could do that by requiring that the implementation classes have trivial `__init__` and then specify a hook-specific init that we call by hand. That shouldn't be hard. This scheme seems doable in a language that has runtime dispatch to me. The lldb_private API layers (and their SWIG-ed equivalents) don't need to pass anything but strings: script class name, and method name, and potentially this opaque HookInstance, and lldb will manage the implementation object(s) and dispatching to them - which it already knows how to do because that's how python stop hooks work. That way as we add more kinds of hooks, you can either choose to have each hook managed by an independent instance of your provided class, or have one instance that gets a bunch of hooks routed to it so it can aggregate data among the hooks. That would then allow you to create the composite hook handler that you want. I'm not sure how you would provide a C++ way to do this, but maybe that's not so important. Or maybe someone better at esoteric C++ than me can think of a way to do that? On the command-line side, we already return a hook ID when you do `target stop-hook add`: so you can modify the options or delete them. So we can use that as the HookInstance. So we would extend `target stop-hook add` to take: (lldb) target stop-hook add --instance-type modules-loaded-hook --instance-id 1 --hook-method-name "my_method" and route all that to the HookDefinition. This should also all be trivially wrap able in SB object, and since the interface is just strings, easily SWIG-able as well. You seemed to have a much more complicated picture, and I wasn't sure how batons were getting involved. Maybe I'm missing some subtlety? But this scheme seems pretty straightforward. https://github.com/llvm/llvm-project/pull/142514 _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits