//===----------------------------------------------------------------------===// // // 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 // //===----------------------------------------------------------------------===// #include "lldb/Target/SyntheticFrameProvider.h" #include "lldb/Core/PluginManager.h" #include "lldb/Target/Thread.h" #include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/Status.h" using namespace lldb; using namespace lldb_private; SyntheticFrameProvider::SyntheticFrameProvider(StackFrameListSP input_frames) : m_input_frames(std::move(input_frames)) {} SyntheticFrameProvider::~SyntheticFrameProvider() = default; void SyntheticFrameProviderDescriptor::Dump(Stream *s) const { if (!s) return; s->Printf(" Name: %s\n", GetName().str().c_str()); // Show thread filter information. if (thread_specs.empty()) { s->PutCString(" Thread Filter: (applies to all threads)\n"); } else { s->Printf(" Thread Filter: %zu specification(s)\n", thread_specs.size()); for (size_t i = 0; i < thread_specs.size(); ++i) { const ThreadSpec &spec = thread_specs[i]; s->Printf(" [%zu] ", i); spec.GetDescription(s, lldb::eDescriptionLevelVerbose); s->PutChar('\n'); } } } llvm::Expected SyntheticFrameProvider::CreateInstance( StackFrameListSP input_frames, const SyntheticFrameProviderDescriptor &descriptor) { if (!input_frames) return llvm::createStringError( "cannot create synthetic frame provider: invalid input frames"); // Iterate through all registered ScriptedFrameProvider plugins. ScriptedFrameProviderCreateInstance create_callback = nullptr; for (uint32_t idx = 0; (create_callback = PluginManager::GetScriptedFrameProviderCreateCallbackAtIndex( idx)) != nullptr; ++idx) { auto provider_or_err = create_callback(input_frames, descriptor); if (!provider_or_err) { LLDB_LOG_ERROR(GetLog(LLDBLog::Target), provider_or_err.takeError(), "Failed to create synthetic frame provider: {0}"); continue; } if (auto frame_provider_up = std::move(*provider_or_err)) return std::move(frame_provider_up); } return llvm::createStringError( "cannot create synthetic frame provider: no suitable plugin found"); } llvm::Expected SyntheticFrameProvider::CreateInstance( StackFrameListSP input_frames, llvm::StringRef plugin_name, const std::vector &thread_specs) { if (!input_frames) return llvm::createStringError( "cannot create synthetic frame provider: invalid input frames"); // Look up the specific C++ plugin by name. SyntheticFrameProviderCreateInstance create_callback = PluginManager::GetSyntheticFrameProviderCreateCallbackForPluginName( plugin_name); if (!create_callback) return llvm::createStringError( "cannot create synthetic frame provider: C++ plugin '%s' not found", plugin_name.str().c_str()); auto provider_or_err = create_callback(input_frames, thread_specs); if (!provider_or_err) return provider_or_err.takeError(); if (auto frame_provider_sp = std::move(*provider_or_err)) return std::move(frame_provider_sp); return llvm::createStringError( "cannot create synthetic frame provider: C++ plugin '%s' returned null", plugin_name.str().c_str()); }