clang 20.0.0 (based on r547379) from build 12806354. Bug: http://b/379133546 Test: N/A Change-Id: I2eb8938af55d809de674be63cb30cf27e801862b Upstream-Commit: ad834e67b1105d15ef907f6255d4c96e8e733f57
308 lines
12 KiB
C++
308 lines
12 KiB
C++
//===-- SystemRuntime.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_TARGET_SYSTEMRUNTIME_H
|
|
#define LLDB_TARGET_SYSTEMRUNTIME_H
|
|
|
|
#include <vector>
|
|
|
|
#include "lldb/Core/ModuleList.h"
|
|
#include "lldb/Core/PluginInterface.h"
|
|
#include "lldb/Target/QueueItem.h"
|
|
#include "lldb/Target/QueueList.h"
|
|
#include "lldb/Target/Runtime.h"
|
|
#include "lldb/Utility/ConstString.h"
|
|
#include "lldb/Utility/StructuredData.h"
|
|
#include "lldb/lldb-private.h"
|
|
#include "lldb/lldb-public.h"
|
|
|
|
namespace lldb_private {
|
|
|
|
/// \class SystemRuntime SystemRuntime.h "lldb/Target/SystemRuntime.h"
|
|
/// A plug-in interface definition class for system runtimes.
|
|
///
|
|
/// The system runtime plugins can collect information from the system
|
|
/// libraries during a Process' lifetime and provide information about how
|
|
/// objects/threads were originated.
|
|
///
|
|
/// For instance, a system runtime plugin use a breakpoint when threads are
|
|
/// created to record the backtrace of where that thread was created. Later,
|
|
/// when backtracing the created thread, it could extend the backtrace to show
|
|
/// where it was originally created from.
|
|
///
|
|
/// The plugin will insert its own breakpoint when Created and start
|
|
/// collecting information. Later when it comes time to augment a Thread, it
|
|
/// can be asked to provide that information.
|
|
///
|
|
|
|
class SystemRuntime : public Runtime, public PluginInterface {
|
|
public:
|
|
/// Find a system runtime plugin for a given process.
|
|
///
|
|
/// Scans the installed SystemRuntime plugins and tries to find an instance
|
|
/// that can be used to track image changes in \a process.
|
|
///
|
|
/// \param[in] process
|
|
/// The process for which to try and locate a system runtime
|
|
/// plugin instance.
|
|
static SystemRuntime *FindPlugin(Process *process);
|
|
|
|
/// Construct with a process.
|
|
SystemRuntime(Process *process);
|
|
|
|
/// Destructor.
|
|
///
|
|
/// The destructor is virtual since this class is designed to be inherited
|
|
/// by the plug-in instance.
|
|
~SystemRuntime() override;
|
|
|
|
/// Called after attaching to a process.
|
|
///
|
|
/// Allow the SystemRuntime plugin to execute some code after attaching to a
|
|
/// process.
|
|
virtual void DidAttach();
|
|
|
|
/// Called after launching a process.
|
|
///
|
|
/// Allow the SystemRuntime plugin to execute some code after launching a
|
|
/// process.
|
|
virtual void DidLaunch();
|
|
|
|
/// Called when modules have been loaded in the process.
|
|
///
|
|
/// Allow the SystemRuntime plugin to enable logging features in the system
|
|
/// runtime libraries.
|
|
void ModulesDidLoad(const ModuleList &module_list) override;
|
|
|
|
/// Called before detaching from a process.
|
|
///
|
|
/// This will give a SystemRuntime plugin a chance to free any resources in
|
|
/// the inferior process before we detach.
|
|
virtual void Detach();
|
|
|
|
/// Return a list of thread origin extended backtraces that may be
|
|
/// available.
|
|
///
|
|
/// A System Runtime may be able to provide a backtrace of when this
|
|
/// thread was originally created. Furthermore, it may be able to provide
|
|
/// that extended backtrace for different styles of creation. On a system
|
|
/// with both pthreads and libdispatch, aka Grand Central Dispatch, queues,
|
|
/// the system runtime may be able to provide the pthread creation of the
|
|
/// thread and it may also be able to provide the backtrace of when this GCD
|
|
/// queue work block was enqueued. The caller may request these different
|
|
/// origins by name.
|
|
///
|
|
/// The names will be provided in the order that they are most likely to be
|
|
/// requested. For instance, a most natural order may be to request the GCD
|
|
/// libdispatch queue origin. If there is none, then request the pthread
|
|
/// origin.
|
|
///
|
|
/// \return
|
|
/// A vector of ConstStrings with names like "pthread" or "libdispatch".
|
|
/// An empty vector may be returned if no thread origin extended
|
|
/// backtrace capabilities are available.
|
|
virtual const std::vector<ConstString> &GetExtendedBacktraceTypes();
|
|
|
|
/// Return a Thread which shows the origin of this thread's creation.
|
|
///
|
|
/// This likely returns a HistoryThread which shows how thread was
|
|
/// originally created (e.g. "pthread" type), or how the work that is
|
|
/// currently executing on it was originally enqueued (e.g. "libdispatch"
|
|
/// type).
|
|
///
|
|
/// There may be a chain of thread-origins; it may be informative to the end
|
|
/// user to query the returned ThreadSP for its origins as well.
|
|
///
|
|
/// \param [in] thread
|
|
/// The thread to examine.
|
|
///
|
|
/// \param [in] type
|
|
/// The type of thread origin being requested. The types supported
|
|
/// are returned from SystemRuntime::GetExtendedBacktraceTypes.
|
|
///
|
|
/// \return
|
|
/// A ThreadSP which will have a StackList of frames. This Thread will
|
|
/// not appear in the Process' list of current threads. Normal thread
|
|
/// operations like stepping will not be available. This is a historical
|
|
/// view thread and may be only useful for showing a backtrace.
|
|
///
|
|
/// An empty ThreadSP will be returned if no thread origin is available.
|
|
virtual lldb::ThreadSP GetExtendedBacktraceThread(lldb::ThreadSP thread,
|
|
ConstString type);
|
|
|
|
/// Get the extended backtrace thread for a QueueItem
|
|
///
|
|
/// A QueueItem represents a function/block that will be executed on
|
|
/// a libdispatch queue in the future, or it represents a function/block
|
|
/// that is currently executing on a thread.
|
|
///
|
|
/// This method will report a thread backtrace of the function that enqueued
|
|
/// it originally, if possible.
|
|
///
|
|
/// \param [in] queue_item_sp
|
|
/// The QueueItem that we are getting an extended backtrace for.
|
|
///
|
|
/// \param [in] type
|
|
/// The type of extended backtrace to fetch. The types supported
|
|
/// are returned from SystemRuntime::GetExtendedBacktraceTypes.
|
|
///
|
|
/// \return
|
|
/// If an extended backtrace is available, it is returned. Else
|
|
/// an empty ThreadSP is returned.
|
|
virtual lldb::ThreadSP
|
|
GetExtendedBacktraceForQueueItem(lldb::QueueItemSP queue_item_sp,
|
|
ConstString type) {
|
|
return lldb::ThreadSP();
|
|
}
|
|
|
|
/// Populate the Process' QueueList with libdispatch / GCD queues that
|
|
/// exist.
|
|
///
|
|
/// When process execution is paused, the SystemRuntime may be called to
|
|
/// fill in the list of Queues that currently exist.
|
|
///
|
|
/// \param [out] queue_list
|
|
/// This QueueList will be cleared, and any queues that currently exist
|
|
/// will be added. An empty QueueList will be returned if no queues
|
|
/// exist or if this Systemruntime does not support libdispatch queues.
|
|
virtual void PopulateQueueList(lldb_private::QueueList &queue_list) {}
|
|
|
|
/// Get the queue name for a thread given a thread's dispatch_qaddr.
|
|
///
|
|
/// On systems using libdispatch queues, a thread may be associated with a
|
|
/// queue. There will be a call to get the thread's dispatch_qaddr. At the
|
|
/// dispatch_qaddr we will find the address of this thread's
|
|
/// dispatch_queue_t structure. Given the address of the dispatch_queue_t
|
|
/// structure for a thread, get the queue name and return it.
|
|
///
|
|
/// \param [in] dispatch_qaddr
|
|
/// The address of the dispatch_qaddr pointer for this thread.
|
|
///
|
|
/// \return
|
|
/// The string of this queue's name. An empty string is returned if the
|
|
/// name could not be found.
|
|
virtual std::string
|
|
GetQueueNameFromThreadQAddress(lldb::addr_t dispatch_qaddr) {
|
|
return "";
|
|
}
|
|
|
|
/// Get the QueueID for the libdispatch queue given the thread's
|
|
/// dispatch_qaddr.
|
|
///
|
|
/// On systems using libdispatch queues, a thread may be associated with a
|
|
/// queue. There will be a call to get the thread's dispatch_qaddr. At the
|
|
/// dispatch_qaddr we will find the address of this thread's
|
|
/// dispatch_queue_t structure. Given the address of the dispatch_queue_t
|
|
/// structure for a thread, get the queue ID and return it.
|
|
///
|
|
/// \param [in] dispatch_qaddr
|
|
/// The address of the dispatch_qaddr pointer for this thread.
|
|
///
|
|
/// \return
|
|
/// The queue ID, or if it could not be retrieved, LLDB_INVALID_QUEUE_ID.
|
|
virtual lldb::queue_id_t
|
|
GetQueueIDFromThreadQAddress(lldb::addr_t dispatch_qaddr) {
|
|
return LLDB_INVALID_QUEUE_ID;
|
|
}
|
|
|
|
/// Get the libdispatch_queue_t address for the queue given the thread's
|
|
/// dispatch_qaddr.
|
|
///
|
|
/// On systems using libdispatch queues, a thread may be associated with a
|
|
/// queue. There will be a call to get the thread's dispatch_qaddr. Given
|
|
/// the thread's dispatch_qaddr, find the libdispatch_queue_t address and
|
|
/// return it.
|
|
///
|
|
/// \param [in] dispatch_qaddr
|
|
/// The address of the dispatch_qaddr pointer for this thread.
|
|
///
|
|
/// \return
|
|
/// The libdispatch_queue_t address, or LLDB_INVALID_ADDRESS if
|
|
/// unavailable/not found.
|
|
virtual lldb::addr_t
|
|
GetLibdispatchQueueAddressFromThreadQAddress(lldb::addr_t dispatch_qaddr) {
|
|
return LLDB_INVALID_ADDRESS;
|
|
}
|
|
|
|
/// Retrieve the Queue kind for the queue at a thread's dispatch_qaddr.
|
|
///
|
|
/// Retrieve the Queue kind - either eQueueKindSerial or
|
|
/// eQueueKindConcurrent, indicating that this queue processes work items
|
|
/// serially or concurrently.
|
|
///
|
|
/// \return
|
|
/// The Queue kind, if it could be read, else eQueueKindUnknown.
|
|
virtual lldb::QueueKind GetQueueKind(lldb::addr_t dispatch_qaddr) {
|
|
return lldb::eQueueKindUnknown;
|
|
}
|
|
|
|
/// Get the pending work items for a libdispatch Queue
|
|
///
|
|
/// If this system/process is using libdispatch and the runtime can do so,
|
|
/// retrieve the list of pending work items for the specified Queue and add
|
|
/// it to the Queue.
|
|
///
|
|
/// \param [in] queue
|
|
/// The queue of interest.
|
|
virtual void PopulatePendingItemsForQueue(lldb_private::Queue *queue) {}
|
|
|
|
/// Complete the fields in a QueueItem
|
|
///
|
|
/// PopulatePendingItemsForQueue() may not fill in all of the QueueItem
|
|
/// details; when the remaining fields are needed, they will be fetched by
|
|
/// call this method.
|
|
///
|
|
/// \param [in] queue_item
|
|
/// The QueueItem that we will be completing.
|
|
///
|
|
/// \param [in] item_ref
|
|
/// The item_ref token that is needed to retrieve the rest of the
|
|
/// information about the QueueItem.
|
|
virtual void CompleteQueueItem(lldb_private::QueueItem *queue_item,
|
|
lldb::addr_t item_ref) {}
|
|
|
|
/// Add key-value pairs to the StructuredData dictionary object with
|
|
/// information debugserver may need when constructing the
|
|
/// jThreadExtendedInfo packet.
|
|
///
|
|
/// \param [out] dict
|
|
/// Dictionary to which key-value pairs should be added; they will
|
|
/// be sent to the remote gdb server stub as arguments in the
|
|
/// jThreadExtendedInfo request.
|
|
virtual void AddThreadExtendedInfoPacketHints(
|
|
lldb_private::StructuredData::ObjectSP dict) {}
|
|
|
|
/// Determine whether it is safe to run an expression on a given thread
|
|
///
|
|
/// If a system must not run functions on a thread in some particular state,
|
|
/// this method gives a way for it to flag that the expression should not be
|
|
/// run.
|
|
///
|
|
/// \param [in] thread_sp
|
|
/// The thread we want to run the expression on.
|
|
///
|
|
/// \return
|
|
/// True will be returned if there are no known problems with running an
|
|
/// expression on this thread. False means that the inferior function
|
|
/// call should not be made on this thread.
|
|
virtual bool SafeToCallFunctionsOnThisThread(lldb::ThreadSP thread_sp) {
|
|
return true;
|
|
}
|
|
|
|
protected:
|
|
std::vector<ConstString> m_types;
|
|
|
|
private:
|
|
SystemRuntime(const SystemRuntime &) = delete;
|
|
const SystemRuntime &operator=(const SystemRuntime &) = delete;
|
|
};
|
|
|
|
} // namespace lldb_private
|
|
|
|
#endif // LLDB_TARGET_SYSTEMRUNTIME_H
|