127 lines · cpp
1//===----------------------------------------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include "lldb/Core/PluginManager.h"10#include "lldb/Host/Config.h"11#include "lldb/Symbol/SymbolContext.h"12#include "lldb/Target/ExecutionContext.h"13#include "lldb/Utility/Log.h"14#include "lldb/lldb-enumerations.h"15 16#if LLDB_ENABLE_PYTHON17 18// LLDB Python header must be included first19#include "../lldb-python.h"20 21#include "../SWIGPythonBridge.h"22#include "../ScriptInterpreterPythonImpl.h"23#include "ScriptedBreakpointPythonInterface.h"24 25using namespace lldb;26using namespace lldb_private;27using namespace lldb_private::python;28 29ScriptedBreakpointPythonInterface::ScriptedBreakpointPythonInterface(30 ScriptInterpreterPythonImpl &interpreter)31 : ScriptedBreakpointInterface(), ScriptedPythonInterface(interpreter) {}32 33llvm::Expected<StructuredData::GenericSP>34ScriptedBreakpointPythonInterface::CreatePluginObject(35 llvm::StringRef class_name, lldb::BreakpointSP break_sp,36 const StructuredDataImpl &args_sp) {37 return ScriptedPythonInterface::CreatePluginObject(class_name, nullptr,38 break_sp, args_sp);39}40 41bool ScriptedBreakpointPythonInterface::ResolverCallback(42 SymbolContext sym_ctx) {43 Status error;44 45 StructuredData::ObjectSP obj = Dispatch("__callback__", error, sym_ctx);46 47 if (!ScriptedInterface::CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj,48 error)) {49 Log *log = GetLog(LLDBLog::Script);50 LLDB_LOG(log, "Error calling __callback__ method: {1}", error);51 return true;52 }53 return obj->GetBooleanValue();54}55 56lldb::SearchDepth ScriptedBreakpointPythonInterface::GetDepth() {57 Status error;58 StructuredData::ObjectSP obj = Dispatch("__get_depth__", error);59 60 if (!ScriptedInterface::CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj,61 error)) {62 return lldb::eSearchDepthModule;63 }64 uint64_t value = obj->GetUnsignedIntegerValue();65 if (value <= lldb::kLastSearchDepthKind)66 return (lldb::SearchDepth)value;67 // This is what we were doing on error before, though I'm not sure that's68 // better than returning eSearchDepthInvalid.69 return lldb::eSearchDepthModule;70}71 72std::optional<std::string> ScriptedBreakpointPythonInterface::GetShortHelp() {73 Status error;74 StructuredData::ObjectSP obj = Dispatch("get_short_help", error);75 76 if (!ScriptedInterface::CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj,77 error)) {78 return {};79 }80 81 return obj->GetAsString()->GetValue().str();82}83 84lldb::BreakpointLocationSP ScriptedBreakpointPythonInterface::WasHit(85 lldb::StackFrameSP frame_sp, lldb::BreakpointLocationSP bp_loc_sp) {86 Status py_error;87 lldb::BreakpointLocationSP loc_sp = Dispatch<lldb::BreakpointLocationSP>(88 "was_hit", py_error, frame_sp, bp_loc_sp);89 90 if (py_error.Fail())91 return bp_loc_sp;92 93 return loc_sp;94}95 96std::optional<std::string>97ScriptedBreakpointPythonInterface::GetLocationDescription(98 lldb::BreakpointLocationSP bp_loc_sp, lldb::DescriptionLevel level) {99 Status error;100 StructuredData::ObjectSP obj =101 Dispatch("get_location_description", error, bp_loc_sp, level);102 103 if (!ScriptedInterface::CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj,104 error))105 return {};106 107 return obj->GetAsString()->GetValue().str();108}109 110void ScriptedBreakpointPythonInterface::Initialize() {111 const std::vector<llvm::StringRef> ci_usages = {112 "breakpoint set -P classname [-k key -v value ...]"};113 const std::vector<llvm::StringRef> api_usages = {114 "SBTarget.BreakpointCreateFromScript"};115 PluginManager::RegisterPlugin(116 GetPluginNameStatic(),117 llvm::StringRef("Create a breakpoint that chooses locations based on "118 "user-created callbacks"),119 CreateInstance, eScriptLanguagePython, {ci_usages, api_usages});120}121 122void ScriptedBreakpointPythonInterface::Terminate() {123 PluginManager::UnregisterPlugin(CreateInstance);124}125 126#endif127