forked from OSchip/llvm-project
Revert "Add StructuredData plugin type; showcase with new DarwinLog feature"
This reverts commit 1d885845d1451e7b232f53fba2e36be67aadabd8. llvm-svn: 279200
This commit is contained in:
parent
fdc4c6b426
commit
a07e4a8352
|
@ -40,18 +40,7 @@ __pycache__/
|
|||
|
||||
clang-module-cache
|
||||
|
||||
# Skip ctags-style tags files
|
||||
tags
|
||||
|
||||
# We should ignore Xcode-style embedding of llvm/ at lldb root dir.
|
||||
# Do not add trailing '/'s, they skip symlinks.
|
||||
/llvm
|
||||
/DerivedData
|
||||
|
||||
# Ignore test trace directories.
|
||||
20??-??-??-??_??_??/
|
||||
|
||||
# Ignore crashlog support files.
|
||||
crashinfo.lock
|
||||
crashinfo.so
|
||||
|
||||
|
|
|
@ -47,7 +47,6 @@ set( LLDB_USED_LIBS
|
|||
lldbPluginObjectContainerMachOArchive
|
||||
lldbPluginObjectContainerBSDArchive
|
||||
lldbPluginPlatformMacOSX
|
||||
lldbPluginStructuredDataDarwinLog
|
||||
lldbPluginDynamicLoaderMacOSXDYLD
|
||||
lldbPluginUnwindAssemblyInstEmulation
|
||||
lldbPluginUnwindAssemblyX86
|
||||
|
|
|
@ -1,160 +0,0 @@
|
|||
# Change Notes
|
||||
|
||||
## Summary
|
||||
|
||||
This document describes the DarwinLog logging feature.
|
||||
|
||||
## StructuredDataDarwinLog feature
|
||||
|
||||
The DarwinLog feature supports logging os_log*() and NSLog() messages
|
||||
to the command-line lldb console, as well as making those messages
|
||||
available to LLDB clients via the event system. Starting with fall
|
||||
2016 OSes, Apple platforms introduce a new fire-hose, stream-style
|
||||
logging system where the bulk of the log processing happens on the log
|
||||
consumer side. This reduces logging impact on the system when there
|
||||
are no consumers, making it cheaper to include logging at all times.
|
||||
However, it also increases the work needed on the consumer end when
|
||||
log messages are desired.
|
||||
|
||||
The debugserver binary has been modified to support collection of
|
||||
os_log*()/NSLog() messages, selection of which messages appear in the
|
||||
stream, and fine-grained filtering of what gets passed on to the LLDB
|
||||
client. DarwinLog also tracks the activity chain (i.e. os_activity()
|
||||
hierarchy) in effect at the time the log messages were issued. The
|
||||
user is able to configure a number of aspects related to the
|
||||
formatting of the log message header fields.
|
||||
|
||||
The DarwinLog support is written in a way which should support the
|
||||
lldb client side on non-Apple clients talking to an Apple device or
|
||||
macOS system; hence, the plugin support is built into all LLDB
|
||||
clients, not just those built on an Apple platform.
|
||||
|
||||
StructuredDataDarwinLog implements the 'DarwinLog' feature type, and
|
||||
the plugin name for it shows up as 'darwin-log'.
|
||||
|
||||
The user interface to the darwin-log support is via the following:
|
||||
|
||||
* 'plugin structured-data darwin-log enable' command
|
||||
|
||||
This is the main entry point for enabling the command. It can be
|
||||
set before launching a process or while the process is running.
|
||||
If the user wants to squelch seeing info-level or debug-level
|
||||
messages, which is the default behavior, then the enable command
|
||||
must be made prior to launching the process; otherwise, the
|
||||
info-level and debug-level messages will always show up. Also,
|
||||
there is a similar "echo os_log()/NSLog() messages to target
|
||||
process stderr" mechanism which is properly disabled when enabling
|
||||
the DarwinLog support prior to launch. This cannot be squelched
|
||||
if enabling DarwinLog after launch.
|
||||
|
||||
See the help for this command. There are a number of options
|
||||
to shrink or expand the number of messages that are processed
|
||||
on the remote side and sent over to the client, and other
|
||||
options to control the formatting of messages displayed.
|
||||
|
||||
This command is sticky. Once enabled, it will stay enabled for
|
||||
future process launches.
|
||||
|
||||
* 'plugin structured-data darwin-log disable' command
|
||||
|
||||
Executing this command disables os_log() capture in the currently
|
||||
running process and signals LLDB to stop attempting to launch
|
||||
new processes with DarwinLog support enabled.
|
||||
|
||||
* 'settings set \
|
||||
plugin.structured-data.darwin-log.enable-on-startup'
|
||||
|
||||
and
|
||||
|
||||
'settings set \
|
||||
plugin.structured-data.darwin-log.auto-enable-options -- {options}'
|
||||
|
||||
When enable-on-startup is set to true, then LLDB will automatically
|
||||
enable DarwinLog on startup of relevant processes. It will use the
|
||||
content provided in the auto-enable-options settings as the
|
||||
options to pass to the enable command.
|
||||
|
||||
Note the '--' required after auto-enable-command. That is necessary
|
||||
for raw commands like settings set. The '--' will not become part
|
||||
of the options for the enable command.
|
||||
|
||||
### Message flow and related performance considerations
|
||||
|
||||
os_log()-style collection is not free. The more data that must be
|
||||
processed, the slower it will be. There are several knobs available
|
||||
to the developer to limit how much data goes through the pipe, and how
|
||||
much data ultimately goes over the wire to the LLDB client. The
|
||||
user's goal should be to ensure he or she only collects as many log
|
||||
messages are needed, but no more.
|
||||
|
||||
The flow of data looks like the following:
|
||||
|
||||
1. Data comes into debugserver from the low-level OS facility that
|
||||
receives log messages. The data that comes through this pipe can
|
||||
be limited or expanded by the '--debug', '--info' and
|
||||
'--all-processes' options of the 'plugin structured-data darwin-log
|
||||
enable' command. options. Exclude as many categories as possible
|
||||
here (also the default). The knobs here are very coarse - for
|
||||
example, whether to include os_log_info()-level or
|
||||
os_log_debug()-level info, or to include callstacks in the log
|
||||
message event data.
|
||||
|
||||
2. The debugserver process filters the messages that arrive through a
|
||||
message log filter that may be fully customized by the user. It
|
||||
works similar to a rules-based packet filter: a set of rules are
|
||||
matched against the log message, each rule tried in sequential
|
||||
order. The first rule that matches then either accepts or rejects
|
||||
the message. If the log message does not match any rule, then the
|
||||
message gets the no-match (i.e. fall-through) action. The no-match
|
||||
action defaults to accepting but may be set to reject.
|
||||
|
||||
Filters can be added via the enable command's '--filter
|
||||
{filter-spec}' option. Filters are added in order, and multiple
|
||||
--filter entries can be provided to the enable command.
|
||||
|
||||
Filters take the following form:
|
||||
|
||||
{action} {attribute} {op}
|
||||
|
||||
{action} :=
|
||||
accept |
|
||||
reject
|
||||
|
||||
{attribute} :=
|
||||
category | // The log message category
|
||||
subsystem | // The log message subsystem}
|
||||
activity | // The child-most activity in force
|
||||
// at the time the message was logged.
|
||||
activity-chain | // The complete activity chain, specified
|
||||
// as {parent-activity}:{child-activity}:
|
||||
// {grandchild-activity}
|
||||
message | // The fully expanded message contents.
|
||||
// Note this one is expensive because it
|
||||
// requires expanding the message. Avoid
|
||||
// this if possible, or add it further
|
||||
// down the filter chain.
|
||||
|
||||
{op} :=
|
||||
match {exact-match-text} |
|
||||
regex {search-regex} // uses C++ std::regex
|
||||
// ECMAScript variant.
|
||||
|
||||
e.g.
|
||||
--filter "accept subsystem match com.example.mycompany.myproduct"
|
||||
--filter "accept subsystem regex com.example.+"
|
||||
--filter "reject category regex spammy-system-[[:digit:]]+"
|
||||
|
||||
3. Messages that are accepted by the log message filter get sent to
|
||||
the lldb client, where they are mapped to the
|
||||
StructuredDataDarwinLog plugin. By default, command-line lldb will
|
||||
issue a Process-level event containing the log message content, and
|
||||
will request the plugin to print the message if the plugin is
|
||||
enabled to do so.
|
||||
|
||||
### Log message display
|
||||
|
||||
Several settings control aspects of displaying log messages in
|
||||
command-line LLDB. See the enable command's help for a description
|
||||
of these.
|
||||
|
||||
|
|
@ -1,136 +0,0 @@
|
|||
# Change Notes
|
||||
|
||||
## Overview
|
||||
|
||||
This document describes an infrastructural feature called Structured
|
||||
Data plugins. See the DarwinLog.md doc for a description of one
|
||||
such plugin that makes use of this feature.
|
||||
|
||||
## StructuredDataPlugin
|
||||
|
||||
StructuredDataPlugin instances have the following characteristics:
|
||||
|
||||
* Each plugin instance is bound to a single Process instance.
|
||||
|
||||
* Each StructuredData feature has a type name that identifies the
|
||||
feature. For instance, the type name for the DarwinLog feature is
|
||||
"DarwinLog". This feature type name is used in various places.
|
||||
|
||||
* The process monitor reports the list of supported StructuredData
|
||||
features advertised by the process monitor. Process goes through the
|
||||
list of supported feature type names, and asks each known
|
||||
StructuredDataPlugin if it can handle the feature. The first plugin
|
||||
that supports the feature is mapped to that Process instance for
|
||||
that feature. Plugins are only mapped when the process monitor
|
||||
advertises that a feature is supported.
|
||||
|
||||
* The feature may send asynchronous messages in StructuredData format
|
||||
to the Process instance. Process instances route the asynchronous
|
||||
structured data messages to the plugin mapped to that feature type,
|
||||
if one exists.
|
||||
|
||||
* Plugins can request that the Process instance forward on
|
||||
configuration data to the process monitor if the plugin needs/wants
|
||||
to configure the feature. Plugins may call the new Process method
|
||||
|
||||
```C++
|
||||
virtual Error
|
||||
ConfigureStructuredData(const ConstString &type_name,
|
||||
const StructuredData::ObjectSP &config_sp)
|
||||
```
|
||||
|
||||
where type_name is the feature name and config_sp points to the
|
||||
configuration structured data, which may be nullptr.
|
||||
|
||||
* Plugins for features present in a process are notified when modules
|
||||
are loaded into the Process instance via this StructuredDataPlugin
|
||||
method:
|
||||
|
||||
```C++
|
||||
virtual void
|
||||
ModulesDidLoad(Process &process, ModuleList &module_list);
|
||||
```
|
||||
|
||||
* Plugins may optionally broadcast their received structured data as
|
||||
an LLDB process-level event via the following new Process call:
|
||||
|
||||
```C++
|
||||
void
|
||||
BroadcastStructuredData(const StructuredData::ObjectSP &object_sp,
|
||||
const lldb::StructuredDataPluginSP &plugin_sp);
|
||||
```
|
||||
|
||||
IDE clients might use this feature to receive information about the
|
||||
process as it is running to monitor memory usage, CPU usage, and
|
||||
logging.
|
||||
|
||||
Internally, the event type created is an instance of
|
||||
EventDataStructuredData.
|
||||
|
||||
* In the case where a plugin chooses to broadcast a received
|
||||
StructuredData event, the command-line LLDB Debugger instance
|
||||
listens for them. The Debugger instance then gives the plugin an
|
||||
opportunity to display info to either the debugger output or error
|
||||
stream at a time that is safe to write to them. The plugin can
|
||||
choose to display something appropriate regarding the structured
|
||||
data that time.
|
||||
|
||||
* Plugins can provide a ProcessLaunchInfo filter method when the
|
||||
plugin is registered. If such a filter method is provided, then
|
||||
when a process is about to be launched for debugging, the filter
|
||||
callback is invoked, given both the launch info and the target. The
|
||||
plugin may then alter the launch info if needed to better support
|
||||
the feature of the plugin.
|
||||
|
||||
* The plugin is entirely independent of the type of Process-derived
|
||||
class that it is working with. The only requirements from the
|
||||
process monitor are the following feature-agnostic elements:
|
||||
|
||||
* Provide a way to discover features supported by the process
|
||||
monitor for the current process.
|
||||
|
||||
* Specify the list of supported feature type names to Process.
|
||||
The process monitor does this by calling the following new
|
||||
method on Process:
|
||||
|
||||
```C++
|
||||
void
|
||||
MapSupportedStructuredDataPlugins(const StructuredData::Array
|
||||
&supported_type_names)
|
||||
```
|
||||
|
||||
The supported_type_names specifies an array of string entries,
|
||||
where each entry specifies the name of a StructuredData feature.
|
||||
|
||||
* Provide a way to forward on configuration data for a feature type
|
||||
to the process monitor. This is the manner by which LLDB can
|
||||
configure a feature, perhaps based on settings or commands from
|
||||
the user. The following virtual method on Process (described
|
||||
earlier) does the job:
|
||||
|
||||
```C++
|
||||
virtual Error
|
||||
ConfigureStructuredData(const ConstString &type_name,
|
||||
const StructuredData::ObjectSP &config_sp)
|
||||
```
|
||||
|
||||
* Listen for asynchronous structured data packets from the process
|
||||
monitor, and forward them on to Process via this new Process
|
||||
member method:
|
||||
|
||||
```C++
|
||||
bool
|
||||
RouteAsyncStructuredData(const StructuredData::ObjectSP object_sp)
|
||||
```
|
||||
|
||||
* StructuredData producers must send their top-level data as a
|
||||
Dictionary type, with a key called 'type' specifying a string value,
|
||||
where the value is equal to the StructuredData feature/type name
|
||||
previously advertised. Everything else about the content of the
|
||||
dictionary is entirely up to the feature.
|
||||
|
||||
* StructuredDataPlugin commands show up under 'plugin structured-data
|
||||
plugin-name'.
|
||||
|
||||
* StructuredDataPlugin settings show up under
|
||||
'plugin.structured-data.{plugin-name}.
|
|
@ -55,7 +55,6 @@
|
|||
#include "lldb/API/SBSourceManager.h"
|
||||
#include "lldb/API/SBStream.h"
|
||||
#include "lldb/API/SBStringList.h"
|
||||
#include "lldb/API/SBStructuredData.h"
|
||||
#include "lldb/API/SBSymbol.h"
|
||||
#include "lldb/API/SBSymbolContext.h"
|
||||
#include "lldb/API/SBSymbolContextList.h"
|
||||
|
|
|
@ -71,7 +71,6 @@ class LLDB_API SBSection;
|
|||
class LLDB_API SBSourceManager;
|
||||
class LLDB_API SBStream;
|
||||
class LLDB_API SBStringList;
|
||||
class LLDB_API SBStructuredData;
|
||||
class LLDB_API SBSymbol;
|
||||
class LLDB_API SBSymbolContext;
|
||||
class LLDB_API SBSymbolContextList;
|
||||
|
|
|
@ -73,7 +73,6 @@ protected:
|
|||
friend class SBHostOS;
|
||||
friend class SBPlatform;
|
||||
friend class SBProcess;
|
||||
friend class SBStructuredData;
|
||||
friend class SBThread;
|
||||
friend class SBTarget;
|
||||
friend class SBValue;
|
||||
|
|
|
@ -32,8 +32,7 @@ public:
|
|||
eBroadcastBitInterrupt = (1 << 1),
|
||||
eBroadcastBitSTDOUT = (1 << 2),
|
||||
eBroadcastBitSTDERR = (1 << 3),
|
||||
eBroadcastBitProfileData = (1 << 4),
|
||||
eBroadcastBitStructuredData = (1 << 5)
|
||||
eBroadcastBitProfileData = (1 << 4)
|
||||
};
|
||||
|
||||
SBProcess ();
|
||||
|
@ -279,16 +278,10 @@ public:
|
|||
|
||||
static bool
|
||||
GetInterruptedFromEvent (const lldb::SBEvent &event);
|
||||
|
||||
static lldb::SBStructuredData
|
||||
GetStructuredDataFromEvent (const lldb::SBEvent &event);
|
||||
|
||||
|
||||
static bool
|
||||
EventIsProcessEvent (const lldb::SBEvent &event);
|
||||
|
||||
static bool
|
||||
EventIsStructuredDataEvent (const lldb::SBEvent &event);
|
||||
|
||||
lldb::SBBroadcaster
|
||||
GetBroadcaster () const;
|
||||
|
||||
|
|
|
@ -83,7 +83,6 @@ protected:
|
|||
friend class SBProcess;
|
||||
friend class SBSection;
|
||||
friend class SBSourceManager;
|
||||
friend class SBStructuredData;
|
||||
friend class SBSymbol;
|
||||
friend class SBSymbolContext;
|
||||
friend class SBSymbolContextList;
|
||||
|
|
|
@ -1,52 +0,0 @@
|
|||
//===-- SBStructuredData.h --------------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef SBStructuredData_h
|
||||
#define SBStructuredData_h
|
||||
|
||||
#include "lldb/API/SBDefines.h"
|
||||
#include "lldb/API/SBModule.h"
|
||||
|
||||
namespace lldb {
|
||||
|
||||
class SBStructuredData
|
||||
{
|
||||
public:
|
||||
|
||||
SBStructuredData();
|
||||
|
||||
SBStructuredData(const lldb::SBStructuredData &rhs);
|
||||
|
||||
SBStructuredData(const lldb::EventSP &event_sp);
|
||||
|
||||
~SBStructuredData();
|
||||
|
||||
lldb::SBStructuredData &
|
||||
operator =(const lldb::SBStructuredData &rhs);
|
||||
|
||||
bool
|
||||
IsValid() const;
|
||||
|
||||
void
|
||||
Clear();
|
||||
|
||||
lldb::SBError
|
||||
GetAsJSON(lldb::SBStream &stream) const;
|
||||
|
||||
lldb::SBError
|
||||
GetDescription(lldb::SBStream &stream) const;
|
||||
|
||||
private:
|
||||
|
||||
class Impl;
|
||||
std::unique_ptr<Impl> m_impl_up;
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* SBStructuredData_h */
|
|
@ -272,10 +272,11 @@ private:
|
|||
/// //----------------------------------------------------------
|
||||
/// enum
|
||||
/// {
|
||||
/// eBroadcastBitOne = (1 << 0),
|
||||
/// eBroadcastBitTwo = (1 << 1),
|
||||
/// eBroadcastBitThree = (1 << 2),
|
||||
/// ...
|
||||
/// eBroadcastBitStateChanged = (1 << 0),
|
||||
/// eBroadcastBitInterrupt = (1 << 1),
|
||||
/// eBroadcastBitSTDOUT = (1 << 2),
|
||||
/// eBroadcastBitSTDERR = (1 << 3),
|
||||
/// eBroadcastBitProfileData = (1 << 4)
|
||||
/// };
|
||||
/// \endcode
|
||||
//----------------------------------------------------------------------
|
||||
|
|
|
@ -20,7 +20,6 @@
|
|||
// Project includes
|
||||
#include "lldb/lldb-private.h"
|
||||
#include "lldb/Core/ConstString.h"
|
||||
#include "lldb/Core/StructuredData.h"
|
||||
#include "lldb/Host/Predicate.h"
|
||||
#include "lldb/Core/Broadcaster.h"
|
||||
|
||||
|
@ -159,80 +158,6 @@ private:
|
|||
}
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
/// This class handles one or more StructuredData::Dictionary entries
|
||||
/// that are raised for structured data events.
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
class EventDataStructuredData : public EventData
|
||||
{
|
||||
public:
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// Constructors
|
||||
//------------------------------------------------------------------
|
||||
EventDataStructuredData();
|
||||
|
||||
EventDataStructuredData(const lldb::ProcessSP &process_sp,
|
||||
const StructuredData::ObjectSP &object_sp,
|
||||
const lldb::StructuredDataPluginSP &plugin_sp);
|
||||
|
||||
~EventDataStructuredData() override;
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// Member functions
|
||||
//------------------------------------------------------------------
|
||||
const ConstString &
|
||||
GetFlavor() const override;
|
||||
|
||||
void
|
||||
Dump(Stream *s) const override;
|
||||
|
||||
const lldb::ProcessSP&
|
||||
GetProcess() const;
|
||||
|
||||
const StructuredData::ObjectSP&
|
||||
GetObject() const;
|
||||
|
||||
const lldb::StructuredDataPluginSP&
|
||||
GetStructuredDataPlugin() const;
|
||||
|
||||
void
|
||||
SetProcess(const lldb::ProcessSP &process_sp);
|
||||
|
||||
void
|
||||
SetObject(const StructuredData::ObjectSP &object_sp);
|
||||
|
||||
void
|
||||
SetStructuredDataPlugin(const lldb::StructuredDataPluginSP &plugin_sp);
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// Static functions
|
||||
//------------------------------------------------------------------
|
||||
static const EventDataStructuredData*
|
||||
GetEventDataFromEvent(const Event *event_ptr);
|
||||
|
||||
static lldb::ProcessSP
|
||||
GetProcessFromEvent(const Event *event_ptr);
|
||||
|
||||
static StructuredData::ObjectSP
|
||||
GetObjectFromEvent(const Event *event_ptr);
|
||||
|
||||
static lldb::StructuredDataPluginSP
|
||||
GetPluginFromEvent(const Event *event_ptr);
|
||||
|
||||
static const ConstString &
|
||||
GetFlavorString ();
|
||||
|
||||
private:
|
||||
|
||||
lldb::ProcessSP m_process_sp;
|
||||
StructuredData::ObjectSP m_object_sp;
|
||||
lldb::StructuredDataPluginSP m_plugin_sp;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(EventDataStructuredData);
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// lldb::Event
|
||||
//----------------------------------------------------------------------
|
||||
|
|
|
@ -327,65 +327,6 @@ public:
|
|||
GetScriptInterpreterForLanguage(lldb::ScriptLanguage script_lang,
|
||||
CommandInterpreter &interpreter);
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// StructuredDataPlugin
|
||||
//------------------------------------------------------------------
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Register a StructuredDataPlugin class along with optional
|
||||
/// callbacks for debugger initialization and Process launch info
|
||||
/// filtering and manipulation.
|
||||
///
|
||||
/// @param[in] name
|
||||
/// The name of the plugin.
|
||||
///
|
||||
/// @param[in] description
|
||||
/// A description string for the plugin.
|
||||
///
|
||||
/// @param[in] create_callback
|
||||
/// The callback that will be invoked to create an instance of
|
||||
/// the callback. This may not be nullptr.
|
||||
///
|
||||
/// @param[in] debugger_init_callback
|
||||
/// An optional callback that will be made when a Debugger
|
||||
/// instance is initialized.
|
||||
///
|
||||
/// @param[in] filter_callback
|
||||
/// An optional callback that will be invoked before LLDB
|
||||
/// launches a process for debugging. The callback must
|
||||
/// do the following:
|
||||
/// 1. Only do something if the plugin's behavior is enabled.
|
||||
/// 2. Only make changes for processes that are relevant to the
|
||||
/// plugin. The callback gets a pointer to the Target, which
|
||||
/// can be inspected as needed. The ProcessLaunchInfo is
|
||||
/// provided in read-write mode, and may be modified by the
|
||||
/// plugin if, for instance, additional environment variables
|
||||
/// are needed to support the feature when enabled.
|
||||
///
|
||||
/// @return
|
||||
/// Returns true upon success; otherwise, false.
|
||||
//------------------------------------------------------------------
|
||||
static bool
|
||||
RegisterPlugin(const ConstString &name,
|
||||
const char *description,
|
||||
StructuredDataPluginCreateInstance create_callback,
|
||||
DebuggerInitializeCallback debugger_init_callback = nullptr,
|
||||
StructuredDataFilterLaunchInfo filter_callback
|
||||
= nullptr);
|
||||
|
||||
static bool
|
||||
UnregisterPlugin(StructuredDataPluginCreateInstance create_callback);
|
||||
|
||||
static StructuredDataPluginCreateInstance
|
||||
GetStructuredDataPluginCreateCallbackAtIndex(uint32_t idx);
|
||||
|
||||
static StructuredDataPluginCreateInstance
|
||||
GetStructuredDataPluginCreateCallbackForPluginName(const ConstString &name);
|
||||
|
||||
static StructuredDataFilterLaunchInfo
|
||||
GetStructuredDataFilterCallbackAtIndex(uint32_t idx,
|
||||
bool &iteration_complete);
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// SymbolFile
|
||||
//------------------------------------------------------------------
|
||||
|
@ -590,16 +531,6 @@ public:
|
|||
static bool CreateSettingForOperatingSystemPlugin(Debugger &debugger,
|
||||
const lldb::OptionValuePropertiesSP &properties_sp,
|
||||
const ConstString &description, bool is_global_property);
|
||||
|
||||
static lldb::OptionValuePropertiesSP
|
||||
GetSettingForStructuredDataPlugin(Debugger &debugger,
|
||||
const ConstString &setting_name);
|
||||
|
||||
static bool
|
||||
CreateSettingForStructuredDataPlugin(Debugger &debugger,
|
||||
const lldb::OptionValuePropertiesSP &properties_sp,
|
||||
const ConstString &description,
|
||||
bool is_global_property);
|
||||
};
|
||||
|
||||
} // namespace lldb_private
|
||||
|
|
|
@ -451,17 +451,6 @@ public:
|
|||
LongestCommonPrefix (std::string &common_prefix);
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Add or replace an environment variable with the given value.
|
||||
///
|
||||
/// This command adds the environment variable if it is not already
|
||||
/// present using the given value. If the environment variable is
|
||||
/// already in the list, it replaces the first such occurrence
|
||||
/// with the new value.
|
||||
//------------------------------------------------------------------
|
||||
void
|
||||
AddOrReplaceEnvironmentVariable(const char *env_var_name,
|
||||
const char *new_value);
|
||||
|
||||
/// Return whether a given environment variable exists.
|
||||
///
|
||||
/// This command treats Args like a list of environment variables,
|
||||
|
@ -471,18 +460,12 @@ public:
|
|||
/// @param[in] env_var_name
|
||||
/// Specifies the name of the environment variable to check.
|
||||
///
|
||||
/// @param[out] argument_index
|
||||
/// If non-null, then when the environment variable is found,
|
||||
/// the index of the argument position will be returned in
|
||||
/// the size_t pointed to by this argument.
|
||||
///
|
||||
/// @return
|
||||
/// true if the specified env var name exists in the list in
|
||||
/// either of the above-mentioned formats; otherwise, false.
|
||||
//------------------------------------------------------------------
|
||||
bool
|
||||
ContainsEnvironmentVariable(const char *env_var_name,
|
||||
size_t *argument_index = nullptr) const;
|
||||
ContainsEnvironmentVariable(const char *env_var_name) const;
|
||||
|
||||
protected:
|
||||
//------------------------------------------------------------------
|
||||
|
|
|
@ -760,8 +760,7 @@ public:
|
|||
eBroadcastBitInterrupt = (1 << 1),
|
||||
eBroadcastBitSTDOUT = (1 << 2),
|
||||
eBroadcastBitSTDERR = (1 << 3),
|
||||
eBroadcastBitProfileData = (1 << 4),
|
||||
eBroadcastBitStructuredData = (1 << 5),
|
||||
eBroadcastBitProfileData = (1 << 4)
|
||||
};
|
||||
|
||||
enum
|
||||
|
@ -3255,71 +3254,6 @@ public:
|
|||
AdvanceAddressToNextBranchInstruction (Address default_stop_addr,
|
||||
AddressRange range_bounds);
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Configure asynchronous structured data feature.
|
||||
///
|
||||
/// Each Process type that supports using an asynchronous StructuredData
|
||||
/// feature should implement this to enable/disable/configure the feature.
|
||||
/// The default implementation here will always return an error indiciating
|
||||
/// the feature is unsupported.
|
||||
///
|
||||
/// StructuredDataPlugin implementations will call this to configure
|
||||
/// a feature that has been reported as being supported.
|
||||
///
|
||||
/// @param[in] type_name
|
||||
/// The StructuredData type name as previously discovered by
|
||||
/// the Process-derived instance.
|
||||
///
|
||||
/// @param[in] config
|
||||
/// Configuration data for the feature being enabled. This config
|
||||
/// data, which may be null, will be passed along to the feature
|
||||
/// to process. The feature will dictate whether this is a dictionary,
|
||||
/// an array or some other object. If the feature needs to be
|
||||
/// set up properly before it can be enabled, then the config should
|
||||
/// also take an enable/disable flag.
|
||||
///
|
||||
/// @return
|
||||
/// Returns the result of attempting to configure the feature.
|
||||
//------------------------------------------------------------------
|
||||
virtual Error
|
||||
ConfigureStructuredData(const ConstString &type_name,
|
||||
const StructuredData::ObjectSP &config_sp);
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Broadcasts the given structured data object from the given
|
||||
/// plugin.
|
||||
///
|
||||
/// StructuredDataPlugin instances can use this to optionally
|
||||
/// broadcast any of their data if they want to make it available
|
||||
/// for clients. The data will come in on the structured data
|
||||
/// event bit (eBroadcastBitStructuredData).
|
||||
///
|
||||
/// @param[in] object_sp
|
||||
/// The structured data object to broadcast.
|
||||
///
|
||||
/// @param[in] plugin_sp
|
||||
/// The plugin that will be reported in the event's plugin
|
||||
/// parameter.
|
||||
//------------------------------------------------------------------
|
||||
void
|
||||
BroadcastStructuredData(const StructuredData::ObjectSP &object_sp,
|
||||
const lldb::StructuredDataPluginSP &plugin_sp);
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Returns the StructuredDataPlugin associated with a given type
|
||||
/// name, if there is one.
|
||||
///
|
||||
/// There will only be a plugin for a given StructuredDataType if the
|
||||
/// debugged process monitor claims that the feature is supported.
|
||||
/// This is one way to tell whether a feature is available.
|
||||
///
|
||||
/// @return
|
||||
/// The plugin if one is available for the specified feature;
|
||||
/// otherwise, returns an empty shared pointer.
|
||||
//------------------------------------------------------------------
|
||||
lldb::StructuredDataPluginSP
|
||||
GetStructuredDataPlugin(const ConstString &type_name) const;
|
||||
|
||||
protected:
|
||||
void
|
||||
SetState (lldb::EventSP &event_sp);
|
||||
|
@ -3457,57 +3391,6 @@ protected:
|
|||
m_force_next_event_delivery = true;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Loads any plugins associated with asynchronous structured data
|
||||
/// and maps the relevant supported type name to the plugin.
|
||||
///
|
||||
/// Processes can receive asynchronous structured data from the
|
||||
/// process monitor. This method will load and map any structured
|
||||
/// data plugins that support the given set of supported type names.
|
||||
/// Later, if any of these features are enabled, the process monitor
|
||||
/// is free to generate asynchronous structured data. The data must
|
||||
/// come in as a single \b StructuredData::Dictionary. That dictionary
|
||||
/// must have a string field named 'type', with a value that equals
|
||||
/// the relevant type name string (one of the values in
|
||||
/// \b supported_type_names).
|
||||
///
|
||||
/// @param[in] supported_type_names
|
||||
/// An array of zero or more type names. Each must be unique.
|
||||
/// For each entry in the list, a StructuredDataPlugin will be
|
||||
/// searched for that supports the structured data type name.
|
||||
//------------------------------------------------------------------
|
||||
void
|
||||
MapSupportedStructuredDataPlugins(const StructuredData::Array
|
||||
&supported_type_names);
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Route the incoming structured data dictionary to the right plugin.
|
||||
///
|
||||
/// The incoming structured data must be a dictionary, and it must
|
||||
/// have a key named 'type' that stores a string value. The string
|
||||
/// value must be the name of the structured data feature that
|
||||
/// knows how to handle it.
|
||||
///
|
||||
/// @param[in] object_sp
|
||||
/// When non-null and pointing to a dictionary, the 'type'
|
||||
/// key's string value is used to look up the plugin that
|
||||
/// was registered for that structured data type. It then
|
||||
/// calls the following method on the StructuredDataPlugin
|
||||
/// instance:
|
||||
///
|
||||
/// virtual void
|
||||
/// HandleArrivalOfStructuredData(Process &process,
|
||||
/// const ConstString &type_name,
|
||||
/// const StructuredData::ObjectSP
|
||||
/// &object_sp)
|
||||
///
|
||||
/// @return
|
||||
/// True if the structured data was routed to a plugin; otherwise,
|
||||
/// false.
|
||||
//------------------------------------------------------------------
|
||||
bool
|
||||
RouteAsyncStructuredData(const StructuredData::ObjectSP object_sp);
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// Type definitions
|
||||
//------------------------------------------------------------------
|
||||
|
@ -3525,9 +3408,6 @@ protected:
|
|||
{
|
||||
}
|
||||
};
|
||||
|
||||
using StructuredDataPluginMap = std::map<ConstString,
|
||||
lldb::StructuredDataPluginSP>;
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// Member variables
|
||||
|
@ -3597,9 +3477,7 @@ protected:
|
|||
bool m_can_interpret_function_calls; // Some targets, e.g the OSX kernel, don't support the ability to modify the stack.
|
||||
WarningsCollection m_warnings_issued; // A set of object pointers which have already had warnings printed
|
||||
std::mutex m_run_thread_plan_lock;
|
||||
StructuredDataPluginMap m_structured_data_plugin_map;
|
||||
|
||||
|
||||
|
||||
enum {
|
||||
eCanJITDontKnow= 0,
|
||||
eCanJITYes,
|
||||
|
@ -3684,7 +3562,7 @@ protected:
|
|||
|
||||
void
|
||||
BroadcastAsyncProfileData(const std::string &one_profile_data);
|
||||
|
||||
|
||||
static void
|
||||
STDIOReadThreadBytesReceived (void *baton, const void *src, size_t src_len);
|
||||
|
||||
|
|
|
@ -1,204 +0,0 @@
|
|||
//===-- StructuredDataPlugin.h ----------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef StructuredDataPlugin_h
|
||||
#define StructuredDataPlugin_h
|
||||
|
||||
#include "lldb/Core/PluginInterface.h"
|
||||
#include "lldb/Core/StructuredData.h"
|
||||
|
||||
namespace lldb_private
|
||||
{
|
||||
|
||||
class CommandObjectMultiword;
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
/// Plugin that supports process-related structured data sent asynchronously
|
||||
/// from the debug monitor (e.g. debugserver, lldb-server, etc.)
|
||||
///
|
||||
/// This plugin type is activated by a Process-derived instance when that
|
||||
/// instance detects that a given structured data feature is available.
|
||||
///
|
||||
/// StructuredDataPlugin instances are inherently tied to a process. The
|
||||
/// main functionality they support is the ability to consume asynchronously-
|
||||
/// delivered structured data from the process monitor, and do something
|
||||
/// reasonable with it. Something reasonable can include broadcasting a
|
||||
/// StructuredData event, which other parts of the system can then do with
|
||||
/// as they please. An IDE could use this facility to retrieve CPU usage,
|
||||
/// memory usage, and other run-time aspects of the process. That data
|
||||
/// can then be displayed meaningfully to the user through the IDE.
|
||||
|
||||
/// For command-line LLDB, the Debugger instance listens for the structured
|
||||
/// data events raised by the plugin, and give the plugin both the output
|
||||
/// and error streams such that the plugin can display something about the
|
||||
/// event, at a time when the debugger ensures it is safe to write to the
|
||||
/// output or error streams.
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
class StructuredDataPlugin :
|
||||
public PluginInterface,
|
||||
public std::enable_shared_from_this<StructuredDataPlugin>
|
||||
{
|
||||
public:
|
||||
|
||||
virtual ~StructuredDataPlugin();
|
||||
|
||||
lldb::ProcessSP
|
||||
GetProcess() const;
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Public instance API
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
/// Return whether this plugin supports the given StructuredData feature.
|
||||
///
|
||||
/// When Process is informed of a list of process-monitor-supported
|
||||
/// structured data features, Process will go through the list of plugins,
|
||||
/// one at a time, and have the first plugin that supports a given feature
|
||||
/// be the plugin instantiated to handle that feature. There is a 1-1
|
||||
/// correspondence between a Process instance and a StructuredDataPlugin
|
||||
/// mapped to that process. A plugin can support handling multiple
|
||||
/// features, and if that happens, there is a single plugin instance
|
||||
/// created covering all of the mapped features for a given process.
|
||||
///
|
||||
/// @param[in] type_name
|
||||
/// The name of the feature tag supported by a process.
|
||||
/// e.g. "darwin-log".
|
||||
///
|
||||
/// @return
|
||||
/// true if the plugin supports the feature; otherwise, false.
|
||||
// -------------------------------------------------------------------------
|
||||
virtual bool
|
||||
SupportsStructuredDataType(const ConstString &type_name) = 0;
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
/// Handle the arrival of asynchronous structured data from the process.
|
||||
///
|
||||
/// When asynchronous structured data arrives from the process monitor,
|
||||
/// it is immediately delivered to the plugin mapped for that feature
|
||||
/// if one exists. The structured data that arrives from a process
|
||||
/// monitor must be a dictionary, and it must have a string field named
|
||||
/// "type" that must contain the StructuredData feature name set as the
|
||||
/// value. This is the manner in which the data is routed to the proper
|
||||
/// plugin instance.
|
||||
///
|
||||
/// @param[in] process
|
||||
/// The process instance that just received the structured data.
|
||||
/// This will always be the same process for a given instance of
|
||||
/// a plugin.
|
||||
///
|
||||
/// @param[in] type_name
|
||||
/// The name of the feature tag for the asynchronous structured data.
|
||||
/// Note this data will also be present in the \b object_sp dictionary
|
||||
/// under the string value with key "type".
|
||||
///
|
||||
/// @param[in] object_sp
|
||||
/// A shared pointer to the structured data that arrived. This must
|
||||
/// be a dictionary. The only key required is the aforementioned
|
||||
/// key named "type" that must be a string value containing the
|
||||
/// structured data type name.
|
||||
// -------------------------------------------------------------------------
|
||||
virtual void
|
||||
HandleArrivalOfStructuredData(Process &process,
|
||||
const ConstString &type_name,
|
||||
const StructuredData::ObjectSP
|
||||
&object_sp) = 0;
|
||||
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
/// Get a human-readable description of the contents of the data.
|
||||
///
|
||||
/// In command-line LLDB, this method will be called by the Debugger
|
||||
/// instance for each structured data event generated, and the output
|
||||
/// will be printed to the LLDB console. If nothing is added to the stream,
|
||||
/// nothing will be printed; otherwise, a newline will be added to the end
|
||||
/// when displayed.
|
||||
///
|
||||
/// @param[in] object_sp
|
||||
/// A shared pointer to the structured data to format.
|
||||
///
|
||||
/// @param[in] stream
|
||||
/// The stream where the structured data should be pretty printed.
|
||||
///
|
||||
/// @return
|
||||
/// The error if formatting the object contents failed; otherwise,
|
||||
/// success.
|
||||
// -------------------------------------------------------------------------
|
||||
virtual Error
|
||||
GetDescription(const StructuredData::ObjectSP &object_sp,
|
||||
lldb_private::Stream &stream) = 0;
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
/// Returns whether the plugin's features are enabled.
|
||||
///
|
||||
/// This is a convenience method for plugins that can enable or disable
|
||||
/// their functionality. It allows retrieval of this state without
|
||||
/// requiring a cast.
|
||||
///
|
||||
/// @param[in] type_name
|
||||
/// The name of the feature tag for the asynchronous structured data.
|
||||
/// This is needed for plugins that support more than one feature.
|
||||
// -------------------------------------------------------------------------
|
||||
virtual bool
|
||||
GetEnabled(const ConstString &type_name) const;
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
/// Allow the plugin to do work related to modules that loaded in the
|
||||
/// the corresponding process.
|
||||
///
|
||||
/// This method defaults to doing nothing. Plugins can override it
|
||||
/// if they have any behavior they want to enable/modify based on loaded
|
||||
/// modules.
|
||||
///
|
||||
/// @param[in] process
|
||||
/// The process that just was notified of modules having been loaded.
|
||||
/// This will always be the same process for a given instance of
|
||||
/// a plugin.
|
||||
///
|
||||
/// @param[in] module_list
|
||||
/// The list of modules that the process registered as having just
|
||||
/// loaded. See \b Process::ModulesDidLoad(...).
|
||||
// -------------------------------------------------------------------------
|
||||
virtual void
|
||||
ModulesDidLoad(Process &process, ModuleList &module_list);
|
||||
|
||||
protected:
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Derived-class API
|
||||
// -------------------------------------------------------------------------
|
||||
StructuredDataPlugin(const lldb::ProcessWP &process_wp);
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
/// Derived classes must call this before attempting to hook up commands
|
||||
/// to the 'plugin structured-data' tree.
|
||||
///
|
||||
/// This ensures the relevant command and options hook points for all
|
||||
/// StructuredDataPlugin derived classes are available for this debugger.
|
||||
/// If this has already happened, this call is a no-op.
|
||||
///
|
||||
/// @param[in] debugger
|
||||
/// The Debugger instance for which we're creating the required shared
|
||||
/// components for the StructuredDataPlugin derived classes.
|
||||
// -------------------------------------------------------------------------
|
||||
static void
|
||||
InitializeBasePluginForDebugger(Debugger &debugger);
|
||||
|
||||
private:
|
||||
|
||||
lldb::ProcessWP m_process_wp;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(StructuredDataPlugin);
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,69 +0,0 @@
|
|||
//===-- ThreadPlanCallOnFunctionExit.h --------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef ThreadPlanCallOnFunctionExit_h
|
||||
#define ThreadPlanCallOnFunctionExit_h
|
||||
|
||||
#include "lldb/Target/ThreadPlan.h"
|
||||
|
||||
#include <functional>
|
||||
|
||||
namespace lldb_private {
|
||||
|
||||
// =============================================================================
|
||||
/// This thread plan calls a function object when the current function exits.
|
||||
// =============================================================================
|
||||
|
||||
class ThreadPlanCallOnFunctionExit : public ThreadPlan
|
||||
{
|
||||
public:
|
||||
|
||||
/// Definition for the callback made when the currently executing thread
|
||||
/// finishes executing its function.
|
||||
using Callback = std::function<void()>;
|
||||
|
||||
ThreadPlanCallOnFunctionExit(Thread &thread, const Callback &callback);
|
||||
|
||||
void
|
||||
DidPush() override;
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// ThreadPlan API
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
void
|
||||
GetDescription (Stream *s, lldb::DescriptionLevel level) override;
|
||||
|
||||
bool
|
||||
ValidatePlan (Stream *error) override;
|
||||
|
||||
bool
|
||||
ShouldStop (Event *event_ptr) override;
|
||||
|
||||
bool
|
||||
WillStop () override;
|
||||
|
||||
protected:
|
||||
|
||||
bool
|
||||
DoPlanExplainsStop (Event *event_ptr) override;
|
||||
|
||||
lldb::StateType
|
||||
GetPlanRunState () override;
|
||||
|
||||
private:
|
||||
|
||||
Callback m_callback;
|
||||
lldb::ThreadPlanSP m_step_out_threadplan_sp;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif /* ThreadPlanCallOnFunctionExit_h */
|
|
@ -91,7 +91,6 @@ class Error;
|
|||
class EvaluateExpressionOptions;
|
||||
class Event;
|
||||
class EventData;
|
||||
class EventDataStructuredData;
|
||||
class ExecutionContext;
|
||||
class ExecutionContextRef;
|
||||
class ExecutionContextRefLocker;
|
||||
|
@ -216,7 +215,6 @@ class StreamFile;
|
|||
class StreamString;
|
||||
class StringList;
|
||||
struct StringSummaryFormat;
|
||||
class StructuredDataPlugin;
|
||||
class SystemRuntime;
|
||||
class TypeSummaryImpl;
|
||||
class TypeSummaryOptions;
|
||||
|
@ -335,7 +333,6 @@ namespace lldb {
|
|||
typedef std::unique_ptr<lldb_private::DynamicLoader> DynamicLoaderUP;
|
||||
typedef std::shared_ptr<lldb_private::Event> EventSP;
|
||||
typedef std::shared_ptr<lldb_private::EventData> EventDataSP;
|
||||
typedef std::shared_ptr<lldb_private::EventDataStructuredData> EventDataStructuredDataSP;
|
||||
typedef std::shared_ptr<lldb_private::ExecutionContextRef> ExecutionContextRefSP;
|
||||
typedef std::shared_ptr<lldb_private::ExpressionVariable> ExpressionVariableSP;
|
||||
typedef std::shared_ptr<lldb_private::File> FileSP;
|
||||
|
@ -418,10 +415,6 @@ namespace lldb {
|
|||
typedef std::weak_ptr<lldb_private::Stream> StreamWP;
|
||||
typedef std::shared_ptr<lldb_private::StreamFile> StreamFileSP;
|
||||
typedef std::shared_ptr<lldb_private::StringSummaryFormat> StringTypeSummaryImplSP;
|
||||
typedef std::shared_ptr<lldb_private::StructuredDataPlugin>
|
||||
StructuredDataPluginSP;
|
||||
typedef std::weak_ptr<lldb_private::StructuredDataPlugin>
|
||||
StructuredDataPluginWP;
|
||||
typedef std::shared_ptr<lldb_private::SymbolFile> SymbolFileSP;
|
||||
typedef std::shared_ptr<lldb_private::SymbolFileType> SymbolFileTypeSP;
|
||||
typedef std::weak_ptr<lldb_private::SymbolFileType> SymbolFileTypeWP;
|
||||
|
|
|
@ -35,9 +35,6 @@ namespace lldb_private
|
|||
typedef Language *(*LanguageCreateInstance) (lldb::LanguageType language);
|
||||
typedef LanguageRuntime *(*LanguageRuntimeCreateInstance) (Process *process, lldb::LanguageType language);
|
||||
typedef lldb::CommandObjectSP (*LanguageRuntimeGetCommandObject) (CommandInterpreter& interpreter);
|
||||
typedef lldb::StructuredDataPluginSP (*StructuredDataPluginCreateInstance)
|
||||
(Process &process);
|
||||
typedef Error (*StructuredDataFilterLaunchInfo)(ProcessLaunchInfo &launch_info, Target *target);
|
||||
typedef SystemRuntime *(*SystemRuntimeCreateInstance) (Process *process);
|
||||
typedef lldb::PlatformSP (*PlatformCreateInstance) (bool force, const ArchSpec *arch);
|
||||
typedef lldb::ProcessSP (*ProcessCreateInstance) (lldb::TargetSP target_sp, lldb::ListenerSP listener_sp, const FileSpec *crash_file_path);
|
||||
|
|
|
@ -57,8 +57,6 @@
|
|||
23059A0719532B96007B8189 /* LinuxSignals.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 23059A0519532B96007B8189 /* LinuxSignals.cpp */; };
|
||||
23059A101958B319007B8189 /* SBUnixSignals.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 23059A0F1958B319007B8189 /* SBUnixSignals.cpp */; };
|
||||
23059A121958B3B2007B8189 /* SBUnixSignals.h in Headers */ = {isa = PBXBuildFile; fileRef = 23059A111958B37B007B8189 /* SBUnixSignals.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
230EC4591D63C3A7008DF59F /* CMakeLists.txt in CopyFiles */ = {isa = PBXBuildFile; fileRef = 230EC4571D63C3A7008DF59F /* CMakeLists.txt */; };
|
||||
230EC45B1D63C3BA008DF59F /* ThreadPlanCallOnFunctionExit.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 230EC4581D63C3A7008DF59F /* ThreadPlanCallOnFunctionExit.cpp */; };
|
||||
2326CF441BDD643700A5CEAC /* liblldb-core.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 2689FFCA13353D7A00698AC0 /* liblldb-core.a */; };
|
||||
2326CF491BDD67D800A5CEAC /* libncurses.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 2326CF471BDD67C100A5CEAC /* libncurses.dylib */; };
|
||||
2326CF4B1BDD681800A5CEAC /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 2326CF4A1BDD681800A5CEAC /* libz.dylib */; };
|
||||
|
@ -74,15 +72,9 @@
|
|||
233B007F1960CB280090E598 /* ProcessLaunchInfo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 233B007E1960CB280090E598 /* ProcessLaunchInfo.cpp */; };
|
||||
236124A41986B4E2004EFC37 /* IOObject.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 236124A21986B4E2004EFC37 /* IOObject.cpp */; };
|
||||
236124A51986B4E2004EFC37 /* Socket.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 236124A31986B4E2004EFC37 /* Socket.cpp */; };
|
||||
2374D7461D4BAA1D005C9575 /* CMakeLists.txt in CopyFiles */ = {isa = PBXBuildFile; fileRef = 2374D7431D4BAA1D005C9575 /* CMakeLists.txt */; };
|
||||
2374D7521D4BB299005C9575 /* GDBRemoteClientBase.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 2374D74F1D4BB299005C9575 /* GDBRemoteClientBase.h */; };
|
||||
2374D7531D4BB2FF005C9575 /* GDBRemoteClientBase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2374D74E1D4BB299005C9575 /* GDBRemoteClientBase.cpp */; };
|
||||
2377C2F819E613C100737875 /* PipePosix.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2377C2F719E613C100737875 /* PipePosix.cpp */; };
|
||||
238F2B9E1D2C82D0001FF92A /* StructuredDataPlugin.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 238F2B9D1D2C82D0001FF92A /* StructuredDataPlugin.cpp */; };
|
||||
238F2BA11D2C835A001FF92A /* StructuredDataPlugin.h in Headers */ = {isa = PBXBuildFile; fileRef = 238F2B9F1D2C835A001FF92A /* StructuredDataPlugin.h */; };
|
||||
238F2BA21D2C835A001FF92A /* SystemRuntime.h in Headers */ = {isa = PBXBuildFile; fileRef = 238F2BA01D2C835A001FF92A /* SystemRuntime.h */; };
|
||||
238F2BA81D2C85FA001FF92A /* StructuredDataDarwinLog.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 238F2BA61D2C85FA001FF92A /* StructuredDataDarwinLog.cpp */; };
|
||||
238F2BA91D2C85FA001FF92A /* StructuredDataDarwinLog.h in Headers */ = {isa = PBXBuildFile; fileRef = 238F2BA71D2C85FA001FF92A /* StructuredDataDarwinLog.h */; };
|
||||
239481861C59EBDD00DF7168 /* libncurses.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 239481851C59EBDD00DF7168 /* libncurses.dylib */; };
|
||||
239504DE1BDD453200963CEA /* SocketAddressTest.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2321F9391BDD332400BA9A93 /* SocketAddressTest.cpp */; };
|
||||
239504DF1BDD453200963CEA /* SocketTest.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2321F93A1BDD332400BA9A93 /* SocketTest.cpp */; };
|
||||
|
@ -101,11 +93,6 @@
|
|||
23D065911D4A7BEE0008EDE6 /* RenderScriptx86ABIFixups.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 23D065861D4A7BDA0008EDE6 /* RenderScriptx86ABIFixups.cpp */; };
|
||||
23D4007D1C2101F2000C3885 /* DWARFDebugMacro.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 23E77CD61C20F29F007192AD /* DWARFDebugMacro.cpp */; };
|
||||
23D4007E1C210201000C3885 /* DebugMacros.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 23E77CDB1C20F2F2007192AD /* DebugMacros.cpp */; };
|
||||
23DCBE9B1D63E14B0084C36B /* SBLanguageRuntime.i in CopyFiles */ = {isa = PBXBuildFile; fileRef = 23DCBE971D63E14B0084C36B /* SBLanguageRuntime.i */; };
|
||||
23DCBE9D1D63E14B0084C36B /* SBTypeEnumMember.i in CopyFiles */ = {isa = PBXBuildFile; fileRef = 23DCBE991D63E14B0084C36B /* SBTypeEnumMember.i */; };
|
||||
23DCBE9E1D63E14B0084C36B /* SBUnixSignals.i in CopyFiles */ = {isa = PBXBuildFile; fileRef = 23DCBE9A1D63E14B0084C36B /* SBUnixSignals.i */; };
|
||||
23DCBEA21D63E7190084C36B /* SBStructuredData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 23DCBEA01D63E6440084C36B /* SBStructuredData.cpp */; };
|
||||
23DCBEA31D63E71F0084C36B /* SBStructuredData.h in Headers */ = {isa = PBXBuildFile; fileRef = 23DCBE9F1D63E3800084C36B /* SBStructuredData.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
23DCEA461D1C4D0F00A602B4 /* SBMemoryRegionInfo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 23DCEA421D1C4C6900A602B4 /* SBMemoryRegionInfo.cpp */; };
|
||||
23DCEA471D1C4D0F00A602B4 /* SBMemoryRegionInfoList.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 23DCEA431D1C4C6900A602B4 /* SBMemoryRegionInfoList.cpp */; };
|
||||
23DDF226196C3EE600BB8417 /* CommandOptionValidators.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 23DDF224196C3EE600BB8417 /* CommandOptionValidators.cpp */; };
|
||||
|
@ -1164,14 +1151,9 @@
|
|||
2374D7521D4BB299005C9575 /* GDBRemoteClientBase.h in CopyFiles */,
|
||||
23D0658C1D4A7BDA0008EDE6 /* RenderScriptRuntime.h in CopyFiles */,
|
||||
23D0658A1D4A7BDA0008EDE6 /* RenderScriptExpressionOpts.h in CopyFiles */,
|
||||
230EC4591D63C3A7008DF59F /* CMakeLists.txt in CopyFiles */,
|
||||
49DEF1221CD7BD90006A7C7D /* BlockPointer.h in CopyFiles */,
|
||||
2374D7461D4BAA1D005C9575 /* CMakeLists.txt in CopyFiles */,
|
||||
4CC7C6531D5299140076FF94 /* DWARFASTParserOCaml.h in CopyFiles */,
|
||||
23DCBE9D1D63E14B0084C36B /* SBTypeEnumMember.i in CopyFiles */,
|
||||
AF90106515AB7D3600FF120D /* lldb.1 in CopyFiles */,
|
||||
23DCBE9B1D63E14B0084C36B /* SBLanguageRuntime.i in CopyFiles */,
|
||||
23DCBE9E1D63E14B0084C36B /* SBUnixSignals.i in CopyFiles */,
|
||||
23D065881D4A7BDA0008EDE6 /* CMakeLists.txt in CopyFiles */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 1;
|
||||
|
@ -1199,8 +1181,6 @@
|
|||
23059A0619532B96007B8189 /* LinuxSignals.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = LinuxSignals.h; path = Utility/LinuxSignals.h; sourceTree = "<group>"; };
|
||||
23059A0F1958B319007B8189 /* SBUnixSignals.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SBUnixSignals.cpp; path = source/API/SBUnixSignals.cpp; sourceTree = "<group>"; };
|
||||
23059A111958B37B007B8189 /* SBUnixSignals.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SBUnixSignals.h; path = include/lldb/API/SBUnixSignals.h; sourceTree = "<group>"; };
|
||||
230EC4571D63C3A7008DF59F /* CMakeLists.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = CMakeLists.txt; path = source/Target/CMakeLists.txt; sourceTree = "<group>"; };
|
||||
230EC4581D63C3A7008DF59F /* ThreadPlanCallOnFunctionExit.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ThreadPlanCallOnFunctionExit.cpp; path = source/Target/ThreadPlanCallOnFunctionExit.cpp; sourceTree = "<group>"; };
|
||||
23173F8B192BA93F005C708F /* lldb-x86-register-enums.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "lldb-x86-register-enums.h"; path = "Utility/lldb-x86-register-enums.h"; sourceTree = "<group>"; };
|
||||
2321F9381BDD332400BA9A93 /* CMakeLists.txt */ = {isa = PBXFileReference; lastKnownFileType = text; path = CMakeLists.txt; sourceTree = "<group>"; };
|
||||
2321F9391BDD332400BA9A93 /* SocketAddressTest.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = SocketAddressTest.cpp; sourceTree = "<group>"; };
|
||||
|
@ -1241,16 +1221,10 @@
|
|||
236124A31986B4E2004EFC37 /* Socket.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Socket.cpp; sourceTree = "<group>"; };
|
||||
236124A61986B50E004EFC37 /* IOObject.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = IOObject.h; path = include/lldb/Host/IOObject.h; sourceTree = "<group>"; };
|
||||
236124A71986B50E004EFC37 /* Socket.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = Socket.h; path = include/lldb/Host/Socket.h; sourceTree = "<group>"; };
|
||||
2374D7431D4BAA1D005C9575 /* CMakeLists.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = CMakeLists.txt; sourceTree = "<group>"; };
|
||||
2374D74E1D4BB299005C9575 /* GDBRemoteClientBase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GDBRemoteClientBase.cpp; sourceTree = "<group>"; };
|
||||
2374D74F1D4BB299005C9575 /* GDBRemoteClientBase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GDBRemoteClientBase.h; sourceTree = "<group>"; };
|
||||
2377C2F719E613C100737875 /* PipePosix.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PipePosix.cpp; sourceTree = "<group>"; };
|
||||
237C577A19AF9D9F00213D59 /* HostInfoLinux.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = HostInfoLinux.h; path = include/lldb/Host/linux/HostInfoLinux.h; sourceTree = SOURCE_ROOT; };
|
||||
238F2B9D1D2C82D0001FF92A /* StructuredDataPlugin.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = StructuredDataPlugin.cpp; path = source/Target/StructuredDataPlugin.cpp; sourceTree = "<group>"; };
|
||||
238F2B9F1D2C835A001FF92A /* StructuredDataPlugin.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = StructuredDataPlugin.h; path = include/lldb/Target/StructuredDataPlugin.h; sourceTree = "<group>"; };
|
||||
238F2BA01D2C835A001FF92A /* SystemRuntime.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SystemRuntime.h; path = include/lldb/Target/SystemRuntime.h; sourceTree = "<group>"; };
|
||||
238F2BA61D2C85FA001FF92A /* StructuredDataDarwinLog.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StructuredDataDarwinLog.cpp; sourceTree = "<group>"; };
|
||||
238F2BA71D2C85FA001FF92A /* StructuredDataDarwinLog.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StructuredDataDarwinLog.h; sourceTree = "<group>"; };
|
||||
239481851C59EBDD00DF7168 /* libncurses.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libncurses.dylib; path = ../../../../../usr/lib/libncurses.dylib; sourceTree = "<group>"; };
|
||||
239504C21BDD3FD600963CEA /* gtest_common.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = gtest_common.h; sourceTree = "<group>"; };
|
||||
239504C61BDD3FF300963CEA /* CMakeLists.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = CMakeLists.txt; sourceTree = "<group>"; };
|
||||
|
@ -1268,12 +1242,6 @@
|
|||
23D065851D4A7BDA0008EDE6 /* RenderScriptRuntime.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RenderScriptRuntime.h; sourceTree = "<group>"; };
|
||||
23D065861D4A7BDA0008EDE6 /* RenderScriptx86ABIFixups.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RenderScriptx86ABIFixups.cpp; sourceTree = "<group>"; };
|
||||
23D065871D4A7BDA0008EDE6 /* RenderScriptx86ABIFixups.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RenderScriptx86ABIFixups.h; sourceTree = "<group>"; };
|
||||
23DCBE971D63E14B0084C36B /* SBLanguageRuntime.i */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c.preprocessed; path = SBLanguageRuntime.i; sourceTree = "<group>"; };
|
||||
23DCBE981D63E14B0084C36B /* SBStructuredData.i */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c.preprocessed; path = SBStructuredData.i; sourceTree = "<group>"; };
|
||||
23DCBE991D63E14B0084C36B /* SBTypeEnumMember.i */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c.preprocessed; path = SBTypeEnumMember.i; sourceTree = "<group>"; };
|
||||
23DCBE9A1D63E14B0084C36B /* SBUnixSignals.i */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c.preprocessed; path = SBUnixSignals.i; sourceTree = "<group>"; };
|
||||
23DCBE9F1D63E3800084C36B /* SBStructuredData.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SBStructuredData.h; path = include/lldb/API/SBStructuredData.h; sourceTree = "<group>"; };
|
||||
23DCBEA01D63E6440084C36B /* SBStructuredData.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SBStructuredData.cpp; path = source/API/SBStructuredData.cpp; sourceTree = "<group>"; };
|
||||
23DCEA421D1C4C6900A602B4 /* SBMemoryRegionInfo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SBMemoryRegionInfo.cpp; path = source/API/SBMemoryRegionInfo.cpp; sourceTree = "<group>"; };
|
||||
23DCEA431D1C4C6900A602B4 /* SBMemoryRegionInfoList.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SBMemoryRegionInfoList.cpp; path = source/API/SBMemoryRegionInfoList.cpp; sourceTree = "<group>"; };
|
||||
23DDF224196C3EE600BB8417 /* CommandOptionValidators.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CommandOptionValidators.cpp; path = source/Interpreter/CommandOptionValidators.cpp; sourceTree = "<group>"; };
|
||||
|
@ -3267,23 +3235,6 @@
|
|||
path = platforms;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
238F2BA41D2C858F001FF92A /* StructuredData */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
238F2BA51D2C85B2001FF92A /* DarwinLog */,
|
||||
);
|
||||
path = StructuredData;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
238F2BA51D2C85B2001FF92A /* DarwinLog */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
238F2BA71D2C85FA001FF92A /* StructuredDataDarwinLog.h */,
|
||||
238F2BA61D2C85FA001FF92A /* StructuredDataDarwinLog.cpp */,
|
||||
);
|
||||
path = DarwinLog;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
23AB0526199FF5D3003B8084 /* FreeBSD */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
|
@ -3328,7 +3279,6 @@
|
|||
26C5577E132575B6008FD8FE /* Platform */,
|
||||
260C898A10F57C5600BB2B04 /* Process */,
|
||||
3FBA69DA1B6066D20008F44A /* ScriptInterpreter */,
|
||||
238F2BA41D2C858F001FF92A /* StructuredData */,
|
||||
AF11CB34182CA85A00D9B618 /* SystemRuntime */,
|
||||
260C89B110F57C5600BB2B04 /* SymbolFile */,
|
||||
260C89E010F57C5600BB2B04 /* SymbolVendor */,
|
||||
|
@ -3558,8 +3508,9 @@
|
|||
2611FEEE142D83060017FEA3 /* interface */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
2611FEEF142D83060017FEA3 /* SBAddress.i */,
|
||||
254FBBA61A91672800BD6378 /* SBAttachInfo.i */,
|
||||
254FBB921A81AA5200BD6378 /* SBLaunchInfo.i */,
|
||||
2611FEEF142D83060017FEA3 /* SBAddress.i */,
|
||||
2611FEF0142D83060017FEA3 /* SBBlock.i */,
|
||||
2611FEF1142D83060017FEA3 /* SBBreakpoint.i */,
|
||||
2611FEF2142D83060017FEA3 /* SBBreakpointLocation.i */,
|
||||
|
@ -3582,8 +3533,6 @@
|
|||
2611FF00142D83060017FEA3 /* SBHostOS.i */,
|
||||
2611FF02142D83060017FEA3 /* SBInstruction.i */,
|
||||
2611FF03142D83060017FEA3 /* SBInstructionList.i */,
|
||||
23DCBE971D63E14B0084C36B /* SBLanguageRuntime.i */,
|
||||
254FBB921A81AA5200BD6378 /* SBLaunchInfo.i */,
|
||||
2611FF04142D83060017FEA3 /* SBLineEntry.i */,
|
||||
2611FF05142D83060017FEA3 /* SBListener.i */,
|
||||
264297591D1DF2AA003F2BF4 /* SBMemoryRegionInfo.i */,
|
||||
|
@ -3598,7 +3547,6 @@
|
|||
2611FF09142D83060017FEA3 /* SBSourceManager.i */,
|
||||
2611FF0A142D83060017FEA3 /* SBStream.i */,
|
||||
2611FF0B142D83060017FEA3 /* SBStringList.i */,
|
||||
23DCBE981D63E14B0084C36B /* SBStructuredData.i */,
|
||||
2611FF0C142D83060017FEA3 /* SBSymbol.i */,
|
||||
2611FF0D142D83060017FEA3 /* SBSymbolContext.i */,
|
||||
2611FF0E142D83060017FEA3 /* SBSymbolContextList.i */,
|
||||
|
@ -3608,13 +3556,11 @@
|
|||
8CCB018419BA54930009FD44 /* SBThreadCollection.i */,
|
||||
2611FF11142D83060017FEA3 /* SBType.i */,
|
||||
9475C18A14E5EA1C001BFC6D /* SBTypeCategory.i */,
|
||||
23DCBE991D63E14B0084C36B /* SBTypeEnumMember.i */,
|
||||
9461569214E3567F003A195C /* SBTypeFilter.i */,
|
||||
9461569314E3567F003A195C /* SBTypeFormat.i */,
|
||||
9475C18B14E5F818001BFC6D /* SBTypeNameSpecifier.i */,
|
||||
9461569414E3567F003A195C /* SBTypeSummary.i */,
|
||||
9461569514E3567F003A195C /* SBTypeSynthetic.i */,
|
||||
23DCBE9A1D63E14B0084C36B /* SBUnixSignals.i */,
|
||||
2611FF12142D83060017FEA3 /* SBValue.i */,
|
||||
2611FF13142D83060017FEA3 /* SBValueList.i */,
|
||||
94235B9D1A8D601A00EB2EED /* SBVariablesOptions.i */,
|
||||
|
@ -3725,8 +3671,6 @@
|
|||
26C72C951243229A0068DC16 /* SBStream.cpp */,
|
||||
9A357670116E7B5200E8ED2F /* SBStringList.h */,
|
||||
9A357672116E7B6400E8ED2F /* SBStringList.cpp */,
|
||||
23DCBE9F1D63E3800084C36B /* SBStructuredData.h */,
|
||||
23DCBEA01D63E6440084C36B /* SBStructuredData.cpp */,
|
||||
26DE205A11618FF600A093E2 /* SBSymbol.h */,
|
||||
26DE20641161904E00A093E2 /* SBSymbol.cpp */,
|
||||
26DE204011618AB900A093E2 /* SBSymbolContext.h */,
|
||||
|
@ -4967,7 +4911,6 @@
|
|||
26BC7DEF10F1B80200F91463 /* Target */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
230EC4571D63C3A7008DF59F /* CMakeLists.txt */,
|
||||
8CF02AE019DCBF3B00B14BE0 /* InstrumentationRuntime.h */,
|
||||
8CF02ADF19DCBF3B00B14BE0 /* InstrumentationRuntime.cpp */,
|
||||
8CF02AEE19DD15CF00B14BE0 /* InstrumentationRuntimeStopInfo.h */,
|
||||
|
@ -5031,9 +4974,6 @@
|
|||
26BC7F3A10F1B90C00F91463 /* StackID.cpp */,
|
||||
2615DB841208A9C90021781D /* StopInfo.h */,
|
||||
2615DB861208A9E40021781D /* StopInfo.cpp */,
|
||||
238F2B9F1D2C835A001FF92A /* StructuredDataPlugin.h */,
|
||||
238F2B9D1D2C82D0001FF92A /* StructuredDataPlugin.cpp */,
|
||||
238F2BA01D2C835A001FF92A /* SystemRuntime.h */,
|
||||
AF81DEF91828A23F0042CF19 /* SystemRuntime.cpp */,
|
||||
26BC7DF810F1B81A00F91463 /* Target.h */,
|
||||
26BC7F3B10F1B90C00F91463 /* Target.cpp */,
|
||||
|
@ -5053,7 +4993,6 @@
|
|||
49EC3E98118F90AC00B1265E /* ThreadPlanCallFunction.cpp */,
|
||||
EB8375E81B553DFE00BA907D /* ThreadPlanCallFunctionUsingABI.h */,
|
||||
EB8375E61B553DE800BA907D /* ThreadPlanCallFunctionUsingABI.cpp */,
|
||||
230EC4581D63C3A7008DF59F /* ThreadPlanCallOnFunctionExit.cpp */,
|
||||
4C7CF7E31295E10E00B4FBB5 /* ThreadPlanCallUserExpression.h */,
|
||||
4C7CF7E51295E12B00B4FBB5 /* ThreadPlanCallUserExpression.cpp */,
|
||||
4C56543219D1EFB5002E9C44 /* ThreadPlanPython.h */,
|
||||
|
@ -5602,7 +5541,6 @@
|
|||
4CEE62F71145F1C70064CF93 /* GDB Remote */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
2374D7431D4BAA1D005C9575 /* CMakeLists.txt */,
|
||||
2374D74F1D4BB299005C9575 /* GDBRemoteClientBase.h */,
|
||||
2374D74E1D4BB299005C9575 /* GDBRemoteClientBase.cpp */,
|
||||
6D55B2931A8A808400A70529 /* GDBRemoteCommunicationServerCommon.h */,
|
||||
|
@ -6139,7 +6077,6 @@
|
|||
9A357671116E7B5200E8ED2F /* SBStringList.h in Headers */,
|
||||
26DE205B11618FF600A093E2 /* SBSymbol.h in Headers */,
|
||||
262F12B71835469C00AEB384 /* SBPlatform.h in Headers */,
|
||||
23DCBEA31D63E71F0084C36B /* SBStructuredData.h in Headers */,
|
||||
26DE204111618AB900A093E2 /* SBSymbolContext.h in Headers */,
|
||||
268F9D53123AA15200B91E9B /* SBSymbolContextList.h in Headers */,
|
||||
2668022C115FD13D008E1FE4 /* SBTarget.h in Headers */,
|
||||
|
@ -6178,12 +6115,9 @@
|
|||
4984BA181B979C08008658D4 /* ExpressionVariable.h in Headers */,
|
||||
26C7C4841BFFEA7E009BD01F /* WindowsMiniDump.h in Headers */,
|
||||
30B38A001CAAA6D7009524E3 /* ClangUtil.h in Headers */,
|
||||
238F2BA11D2C835A001FF92A /* StructuredDataPlugin.h in Headers */,
|
||||
AF8AD62F1BEC28A400150209 /* PlatformAppleTVSimulator.h in Headers */,
|
||||
238F2BA91D2C85FA001FF92A /* StructuredDataDarwinLog.h in Headers */,
|
||||
AF8AD63A1BEC28C400150209 /* PlatformRemoteAppleWatch.h in Headers */,
|
||||
257906651BD5AFD000178368 /* Acceptor.h in Headers */,
|
||||
238F2BA21D2C835A001FF92A /* SystemRuntime.h in Headers */,
|
||||
260A63171861008E00FECF8E /* IOHandler.h in Headers */,
|
||||
267F68581CC02EAE0086832B /* RegisterContextPOSIX_s390x.h in Headers */,
|
||||
6D0F614F1C80AB0C00A4ECEE /* JavaLanguageRuntime.h in Headers */,
|
||||
|
@ -6646,7 +6580,6 @@
|
|||
9461569D14E358A6003A195C /* SBTypeSynthetic.cpp in Sources */,
|
||||
26680324116005D9008E1FE4 /* SBThread.cpp in Sources */,
|
||||
26680326116005DB008E1FE4 /* SBTarget.cpp in Sources */,
|
||||
23DCBEA21D63E7190084C36B /* SBStructuredData.cpp in Sources */,
|
||||
26680327116005DC008E1FE4 /* SBSourceManager.cpp in Sources */,
|
||||
3F81692C1ABB7A1E001DA9DF /* SystemInitializerFull.cpp in Sources */,
|
||||
26680328116005DE008E1FE4 /* SBProcess.cpp in Sources */,
|
||||
|
@ -6995,7 +6928,6 @@
|
|||
268900C213353E5F00698AC0 /* DWARFDebugPubnamesSet.cpp in Sources */,
|
||||
268900C313353E5F00698AC0 /* DWARFDebugRanges.cpp in Sources */,
|
||||
25EF23781AC09B3700908DF0 /* AdbClient.cpp in Sources */,
|
||||
238F2BA81D2C85FA001FF92A /* StructuredDataDarwinLog.cpp in Sources */,
|
||||
94380B8219940B0A00BFE4A8 /* StringLexer.cpp in Sources */,
|
||||
268900C413353E5F00698AC0 /* DWARFDefines.cpp in Sources */,
|
||||
945563101BEAD0650073F75F /* PlatformiOSSimulatorCoreSimulatorSupport.mm in Sources */,
|
||||
|
@ -7148,7 +7080,6 @@
|
|||
26D5E163135BB054006EA0A7 /* OptionGroupPlatform.cpp in Sources */,
|
||||
94CD131A19BA33B400DB7BED /* TypeValidator.cpp in Sources */,
|
||||
26BD407F135D2AE000237D80 /* FileLineResolver.cpp in Sources */,
|
||||
230EC45B1D63C3BA008DF59F /* ThreadPlanCallOnFunctionExit.cpp in Sources */,
|
||||
AE44FB311BB07EB80033EB62 /* GoLexer.cpp in Sources */,
|
||||
26A7A035135E6E4200FB369E /* OptionValue.cpp in Sources */,
|
||||
9A22A161135E30370024DDC3 /* EmulateInstructionARM.cpp in Sources */,
|
||||
|
@ -7320,7 +7251,6 @@
|
|||
945261C81B9A14D300BF138D /* CXXFunctionPointer.cpp in Sources */,
|
||||
94CB256716B096F10059775D /* TypeCategoryMap.cpp in Sources */,
|
||||
94CB257016B0A4270059775D /* TypeFormat.cpp in Sources */,
|
||||
238F2B9E1D2C82D0001FF92A /* StructuredDataPlugin.cpp in Sources */,
|
||||
94CB257116B0A4270059775D /* TypeSummary.cpp in Sources */,
|
||||
94CB257216B0A4270059775D /* TypeSynthetic.cpp in Sources */,
|
||||
94CB257416B1D3880059775D /* FormatCache.cpp in Sources */,
|
||||
|
|
|
@ -1,430 +0,0 @@
|
|||
"""
|
||||
Base class for DarwinLog tests.
|
||||
"""
|
||||
|
||||
# System imports
|
||||
from __future__ import print_function
|
||||
|
||||
import json
|
||||
import os
|
||||
import pexpect
|
||||
import platform
|
||||
import re
|
||||
import sys
|
||||
import threading
|
||||
|
||||
|
||||
# lldb imports
|
||||
import lldb
|
||||
from lldb import SBProcess, SBTarget
|
||||
|
||||
from lldbsuite.test import decorators
|
||||
from lldbsuite.test import lldbtest
|
||||
from lldbsuite.test import lldbtest_config
|
||||
from lldbsuite.test import lldbutil
|
||||
|
||||
|
||||
def expand_darwinlog_command(command):
|
||||
return "plugin structured-data darwin-log " + command
|
||||
|
||||
|
||||
def expand_darwinlog_settings_set_command(command):
|
||||
return "settings set plugin.structured-data.darwin-log." + command
|
||||
|
||||
|
||||
class DarwinLogTestBase(lldbtest.TestBase):
|
||||
"""Base class for DarwinLog test cases that are pexpect-based."""
|
||||
NO_DEBUG_INFO_TESTCASE = True
|
||||
|
||||
CONTINUE_REGEX = re.compile(r"Process \d+ resuming")
|
||||
|
||||
def setUp(self):
|
||||
# Call super's setUp().
|
||||
super(DarwinLogTestBase, self).setUp()
|
||||
|
||||
# Until other systems support this, exit
|
||||
# early if we're not macOS version 10.12
|
||||
# or greater.
|
||||
version = platform.mac_ver()[0].split('.')
|
||||
if ((int(version[0]) == 10) and (int(version[1]) < 12) or
|
||||
(int(version[0]) < 10)):
|
||||
self.skipTest("DarwinLog tests currently require macOS 10.12+")
|
||||
return
|
||||
|
||||
self.child = None
|
||||
self.child_prompt = '(lldb) '
|
||||
self.strict_sources = False
|
||||
self.enable_process_monitor_logging = False
|
||||
|
||||
def run_lldb_to_breakpoint(self, exe, source_file, line,
|
||||
enable_command=None, settings_commands=None):
|
||||
|
||||
# Set self.child_prompt, which is "(lldb) ".
|
||||
prompt = self.child_prompt
|
||||
|
||||
# So that the child gets torn down after the test.
|
||||
self.child = pexpect.spawn('%s %s %s' % (lldbtest_config.lldbExec,
|
||||
self.lldbOption, exe))
|
||||
child = self.child
|
||||
|
||||
# Turn on logging for what the child sends back.
|
||||
if self.TraceOn():
|
||||
child.logfile_read = sys.stdout
|
||||
|
||||
if self.enable_process_monitor_logging:
|
||||
if platform.system() == 'Darwin':
|
||||
self.runCmd("settings set target.process.extra-startup-command "
|
||||
"QSetLogging:bitmask=LOG_DARWIN_LOG;")
|
||||
self.expect_prompt()
|
||||
|
||||
# Run the enable command if we have one.
|
||||
if enable_command is not None:
|
||||
self.runCmd(enable_command)
|
||||
self.expect_prompt()
|
||||
|
||||
# Disable showing of source lines at our breakpoint.
|
||||
# This is necessary for the logging tests, because the very
|
||||
# text we want to match for output from the running inferior
|
||||
# will show up in the source as well. We don't want the source
|
||||
# output to erroneously make a match with our expected output.
|
||||
self.runCmd("settings set stop-line-count-before 0")
|
||||
self.expect_prompt()
|
||||
self.runCmd("settings set stop-line-count-after 0")
|
||||
self.expect_prompt()
|
||||
|
||||
# While we're debugging, turn on packet logging.
|
||||
self.runCmd("log enable -f /tmp/packets.log gdb-remote packets")
|
||||
self.expect_prompt()
|
||||
|
||||
# Prevent mirroring of NSLog/os_log content to stderr. We want log
|
||||
# messages to come exclusively through our log channel.
|
||||
self.runCmd("settings set target.env-vars IDE_DISABLED_OS_ACTIVITY_DT_MODE=1")
|
||||
self.expect_prompt()
|
||||
|
||||
# Run any darwin-log settings commands now, before we enable logging.
|
||||
if settings_commands is not None:
|
||||
for setting_command in settings_commands:
|
||||
self.runCmd(
|
||||
expand_darwinlog_settings_set_command(setting_command))
|
||||
self.expect_prompt()
|
||||
|
||||
# Set breakpoint right before the os_log() macros. We don't
|
||||
# set it on the os_log*() calls because these are a number of
|
||||
# nested-scoped calls that will cause the debugger to stop
|
||||
# multiple times on the same line. That is difficult to match
|
||||
# os_log() content by since it is non-deterministic what the
|
||||
# ordering between stops and log lines will be. This is why
|
||||
# we stop before, and then have the process run in a sleep
|
||||
# afterwards, so we get the log messages while the target
|
||||
# process is "running" (sleeping).
|
||||
child.sendline('breakpoint set -f %s -l %d' % (source_file, line))
|
||||
child.expect_exact(prompt)
|
||||
|
||||
# Now run to the breakpoint that we just set.
|
||||
child.sendline('run')
|
||||
child.expect_exact(prompt)
|
||||
|
||||
# Ensure we stopped at a breakpoint.
|
||||
self.runCmd("thread list")
|
||||
self.expect(re.compile(r"stop reason = breakpoint"))
|
||||
|
||||
# Now we're ready to check if DarwinLog is available.
|
||||
if not self.darwin_log_available():
|
||||
self.skipTest("DarwinLog not available")
|
||||
|
||||
def runCmd(self, cmd):
|
||||
self.child.sendline(cmd)
|
||||
|
||||
def expect_prompt(self, exactly=True):
|
||||
self.expect(self.child_prompt, exactly=exactly)
|
||||
|
||||
def expect(self, pattern, exactly=False, *args, **kwargs):
|
||||
if exactly:
|
||||
return self.child.expect_exact(pattern, *args, **kwargs)
|
||||
return self.child.expect(pattern, *args, **kwargs)
|
||||
|
||||
def darwin_log_available(self):
|
||||
self.runCmd("plugin structured-data darwin-log status")
|
||||
self.expect(re.compile(r"Availability: ([\S]+)"))
|
||||
return self.child.match is not None and (
|
||||
self.child.match.group(1) == "available")
|
||||
|
||||
def do_test(self, enable_options, expect_regexes=None,
|
||||
settings_commands=None):
|
||||
"""Test that a single fall-through reject rule rejects all logging."""
|
||||
self.build(dictionary=self.d)
|
||||
self.setTearDownCleanup(dictionary=self.d)
|
||||
|
||||
# Build the darwin-log enable command.
|
||||
enable_cmd = expand_darwinlog_command('enable')
|
||||
if enable_options is not None and len(enable_options) > 0:
|
||||
enable_cmd += ' ' + ' '.join(enable_options)
|
||||
|
||||
exe = os.path.join(os.getcwd(), self.exe_name)
|
||||
self.run_lldb_to_breakpoint(exe, self.source, self.line,
|
||||
enable_command=enable_cmd,
|
||||
settings_commands=settings_commands)
|
||||
self.expect_prompt()
|
||||
|
||||
# Now go.
|
||||
self.runCmd("process continue")
|
||||
self.expect(self.CONTINUE_REGEX)
|
||||
|
||||
if expect_regexes is None:
|
||||
# Expect matching a log line or program exit.
|
||||
# Test methods determine which ones are valid.
|
||||
expect_regexes = (
|
||||
[re.compile(r"source-log-([^-]+)-(\S+)"),
|
||||
re.compile(r"exited with status")
|
||||
])
|
||||
self.expect(expect_regexes)
|
||||
|
||||
|
||||
def remove_add_mode_entry(log_entries):
|
||||
"""libtrace creates an "Add Mode:..." message when logging is enabled.
|
||||
Strip this out of results since our test subjects don't create it."""
|
||||
return [entry for entry in log_entries
|
||||
if "message" in entry and
|
||||
not entry["message"].startswith("Add Mode:")]
|
||||
|
||||
|
||||
class DarwinLogEventBasedTestBase(lldbtest.TestBase):
|
||||
"""Base class for event-based DarwinLog tests."""
|
||||
NO_DEBUG_INFO_TESTCASE = True
|
||||
|
||||
class EventListenerThread(threading.Thread):
|
||||
def __init__(self, listener, process, trace_on, max_entry_count):
|
||||
super(DarwinLogEventBasedTestBase.EventListenerThread, self).__init__()
|
||||
self.process = process
|
||||
self.listener = listener
|
||||
self.trace_on = trace_on
|
||||
self.max_entry_count = max_entry_count
|
||||
self.exception = None
|
||||
self.structured_data_event_count = 0
|
||||
self.wait_seconds = 2
|
||||
self.max_timeout_count = 4
|
||||
self.log_entries = []
|
||||
|
||||
def handle_structured_data_event(self, event):
|
||||
structured_data = SBProcess.GetStructuredDataFromEvent(event)
|
||||
if not structured_data.IsValid():
|
||||
if self.trace_on:
|
||||
print("invalid structured data")
|
||||
return
|
||||
|
||||
# Track that we received a valid structured data event.
|
||||
self.structured_data_event_count += 1
|
||||
|
||||
# Grab the individual log entries from the JSON.
|
||||
stream = lldb.SBStream()
|
||||
structured_data.GetAsJSON(stream)
|
||||
dict = json.loads(stream.GetData())
|
||||
self.log_entries.extend(dict["events"])
|
||||
if self.trace_on:
|
||||
print("Structured data (raw):", stream.GetData())
|
||||
|
||||
# Print the pretty-printed version.
|
||||
if self.trace_on:
|
||||
stream.Clear()
|
||||
structured_data.PrettyPrint(stream)
|
||||
print("Structured data (pretty print):",
|
||||
stream.GetData())
|
||||
|
||||
def done(self, timeout_count):
|
||||
"""Returns True when we're done listening for events."""
|
||||
# See if we should consider the number of events retrieved.
|
||||
if self.max_entry_count is not None:
|
||||
if len(self.log_entries) >= self.max_entry_count:
|
||||
# We've received the max threshold of events expected,
|
||||
# we can exit here.
|
||||
if self.trace_on:
|
||||
print("Event listener thread exiting due to max "
|
||||
"expected log entry count being reached.")
|
||||
return True
|
||||
|
||||
# If our event timeout count has exceeded our maximum timeout count,
|
||||
# we're done.
|
||||
if timeout_count >= self.max_timeout_count:
|
||||
if self.trace_on:
|
||||
print("Event listener thread exiting due to max number of "
|
||||
"WaitForEvent() timeouts being reached.")
|
||||
return True
|
||||
|
||||
# If our process is dead, we're done.
|
||||
if not self.process.is_alive:
|
||||
if self.trace_on:
|
||||
print("Event listener thread exiting due to test inferior "
|
||||
"exiting.")
|
||||
return True
|
||||
|
||||
# We're not done.
|
||||
return False
|
||||
|
||||
def run(self):
|
||||
event = lldb.SBEvent()
|
||||
try:
|
||||
timeout_count = 0
|
||||
|
||||
# Wait up to 4 times for the event to arrive.
|
||||
while not self.done(timeout_count):
|
||||
if self.trace_on:
|
||||
print("Calling wait for event...")
|
||||
if self.listener.WaitForEvent(self.wait_seconds, event):
|
||||
while event.IsValid():
|
||||
# Check if it's a process event.
|
||||
if SBProcess.EventIsStructuredDataEvent(event):
|
||||
self.handle_structured_data_event(event)
|
||||
else:
|
||||
if self.trace_on:
|
||||
print("ignoring unexpected event:",
|
||||
lldbutil.get_description(event))
|
||||
# Grab the next event, if there is one.
|
||||
event.Clear()
|
||||
if not self.listener.GetNextEvent(event):
|
||||
if self.trace_on:
|
||||
print("listener has no more events "
|
||||
"available at this time")
|
||||
else:
|
||||
if self.trace_on:
|
||||
print("timeout occurred waiting for event...")
|
||||
timeout_count += 1
|
||||
self.listener.Clear()
|
||||
except Exception as e:
|
||||
self.exception = e
|
||||
|
||||
def setUp(self):
|
||||
# Call super's setUp().
|
||||
super(DarwinLogEventBasedTestBase, self).setUp()
|
||||
|
||||
# Source filename.
|
||||
self.source = 'main.c'
|
||||
|
||||
# Output filename.
|
||||
self.exe_name = 'a.out'
|
||||
self.d = {'C_SOURCES': self.source, 'EXE': self.exe_name}
|
||||
|
||||
# Locate breakpoint.
|
||||
self.line = lldbtest.line_number(self.source, '// break here')
|
||||
|
||||
# Enable debugserver logging of the darwin log collection
|
||||
# mechanism.
|
||||
self.runCmd("settings set target.process.extra-startup-command "
|
||||
"QSetLogging:bitmask=LOG_DARWIN_LOG;")
|
||||
|
||||
def do_test(self, enable_options, settings_commands=None,
|
||||
run_enable_after_breakpoint=False, max_entry_count=None):
|
||||
"""Runs the test inferior, returning collected events.
|
||||
|
||||
This method runs the test inferior to the first breakpoint hit.
|
||||
It then adds a listener for structured data events, and collects
|
||||
all events from that point forward until end of execution of the
|
||||
test inferior. It then returns those events.
|
||||
|
||||
@return
|
||||
A list of structured data events received, in the order they
|
||||
were received.
|
||||
"""
|
||||
self.build(dictionary=self.d)
|
||||
self.setTearDownCleanup(dictionary=self.d)
|
||||
|
||||
exe = os.path.join(os.getcwd(), self.exe_name)
|
||||
|
||||
# Create a target by the debugger.
|
||||
target = self.dbg.CreateTarget(exe)
|
||||
self.assertTrue(target, lldbtest.VALID_TARGET)
|
||||
|
||||
# Run the darwin-log settings commands.
|
||||
if settings_commands is not None:
|
||||
for setting_command in settings_commands:
|
||||
self.runCmd(
|
||||
expand_darwinlog_settings_set_command(setting_command))
|
||||
|
||||
# Build the darwin-log enable command.
|
||||
enable_cmd = expand_darwinlog_command("enable")
|
||||
if enable_options is not None and len(enable_options) > 0:
|
||||
enable_cmd += ' ' + ' '.join(enable_options)
|
||||
|
||||
# Run the darwin-log enable command now if we are not supposed
|
||||
# to do it at the first breakpoint. This tests the start-up
|
||||
# code, which has the benefit of being able to set os_log-related
|
||||
# environment variables.
|
||||
if not run_enable_after_breakpoint:
|
||||
self.runCmd(enable_cmd)
|
||||
|
||||
# Create the breakpoint.
|
||||
breakpoint = target.BreakpointCreateByLocation(self.source, self.line)
|
||||
self.assertIsNotNone(breakpoint)
|
||||
self.assertTrue(breakpoint.IsValid())
|
||||
self.assertEqual(1, breakpoint.GetNumLocations(),
|
||||
"Should have found one breakpoint")
|
||||
|
||||
# Enable packet logging.
|
||||
# self.runCmd("log enable -f /tmp/packets.log gdb-remote packets")
|
||||
# self.runCmd("log enable lldb process")
|
||||
|
||||
# Launch the process - doesn't stop at entry.
|
||||
process = target.LaunchSimple(None, None, os.getcwd())
|
||||
self.assertIsNotNone(process, lldbtest.PROCESS_IS_VALID)
|
||||
|
||||
# Keep track of whether we're tracing output.
|
||||
trace_on = self.TraceOn()
|
||||
|
||||
# Get the next thread that stops.
|
||||
from lldbsuite.test.lldbutil import get_stopped_thread
|
||||
thread = get_stopped_thread(process, lldb.eStopReasonBreakpoint)
|
||||
|
||||
self.assertIsNotNone(thread, "There should be a thread stopped "
|
||||
"due to breakpoint")
|
||||
|
||||
# The process should be stopped at this point.
|
||||
self.expect("process status", lldbtest.PROCESS_STOPPED,
|
||||
patterns=['Process .* stopped'])
|
||||
|
||||
# The stop reason of the thread should be breakpoint.
|
||||
self.expect("thread list", lldbtest.STOPPED_DUE_TO_BREAKPOINT,
|
||||
substrs=['stopped', 'stop reason = breakpoint'])
|
||||
|
||||
# And our one and only breakpoint should have been hit.
|
||||
self.assertEquals(breakpoint.GetHitCount(), 1)
|
||||
|
||||
# Now setup the structured data listener.
|
||||
#
|
||||
# Grab the broadcaster for the process. We'll be attaching our
|
||||
# listener to it.
|
||||
broadcaster = process.GetBroadcaster()
|
||||
self.assertIsNotNone(broadcaster)
|
||||
|
||||
listener = lldb.SBListener("SBStructuredData listener")
|
||||
self.assertIsNotNone(listener)
|
||||
|
||||
rc = broadcaster.AddListener(listener,
|
||||
lldb.SBProcess.eBroadcastBitStructuredData)
|
||||
self.assertTrue(rc, "Successfully add listener to process broadcaster")
|
||||
|
||||
# Start the listening thread to retrieve the events.
|
||||
# Bump up max entry count for the potentially included Add Mode:
|
||||
# entry.
|
||||
if max_entry_count is not None:
|
||||
max_entry_count += 1
|
||||
event_thread = self.EventListenerThread(listener, process, trace_on,
|
||||
max_entry_count)
|
||||
event_thread.start()
|
||||
|
||||
# Continue the test inferior. We should get any events after this.
|
||||
process.Continue()
|
||||
|
||||
# Wait until the event thread terminates.
|
||||
# print("main thread now waiting for event thread to receive events.")
|
||||
event_thread.join()
|
||||
|
||||
# If the process is still alive, we kill it here.
|
||||
if process.is_alive:
|
||||
process.Kill()
|
||||
|
||||
# Fail on any exceptions that occurred during event execution.
|
||||
if event_thread.exception is not None:
|
||||
# Re-raise it here so it shows up as a test error.
|
||||
raise event_thread
|
||||
|
||||
# Return the collected logging events.
|
||||
return remove_add_mode_entry(event_thread.log_entries)
|
|
@ -1,5 +0,0 @@
|
|||
LEVEL = ../../../make
|
||||
|
||||
C_SOURCES := main.c
|
||||
|
||||
include $(LEVEL)/Makefile.rules
|
|
@ -1,34 +0,0 @@
|
|||
"""
|
||||
Test basic DarwinLog functionality provided by the StructuredDataDarwinLog
|
||||
plugin.
|
||||
|
||||
These tests are currently only supported when running against Darwin
|
||||
targets.
|
||||
"""
|
||||
|
||||
# System imports
|
||||
from __future__ import print_function
|
||||
|
||||
# LLDB imports
|
||||
from lldbsuite.test import darwin_log
|
||||
from lldbsuite.test import decorators
|
||||
from lldbsuite.test import lldbtest
|
||||
|
||||
|
||||
class TestDarwinLogBasic(darwin_log.DarwinLogEventBasedTestBase):
|
||||
|
||||
mydir = lldbtest.TestBase.compute_mydir(__file__)
|
||||
|
||||
@decorators.add_test_categories(['pyapi'])
|
||||
@decorators.skipUnlessDarwin
|
||||
def test_SBStructuredData_gets_broadcasted(self):
|
||||
"""Exercise SBStructuredData API."""
|
||||
|
||||
# Run the test.
|
||||
log_entries = self.do_test(None, max_entry_count=2)
|
||||
|
||||
# Validate that we received our two log entries.
|
||||
self.assertEqual(len(log_entries), 1,
|
||||
"Expected one log entry to arrive via events.")
|
||||
self.assertEqual(log_entries[0]['message'], "Hello, world",
|
||||
"Log message should match expected content.")
|
|
@ -1,32 +0,0 @@
|
|||
//===-- main.c --------------------------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include <os/log.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "../common/darwin_log_common.h"
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
os_log_t logger = os_log_create("org.llvm.lldb.test", "basic-test");
|
||||
if (!logger)
|
||||
return 1;
|
||||
|
||||
// Note we cannot use the os_log() line as the breakpoint because, as of
|
||||
// the initial writing of this test, we get multiple breakpoints for that
|
||||
// line, which confuses the pexpect test logic.
|
||||
printf("About to log\n"); // break here
|
||||
os_log(logger, "Hello, world");
|
||||
|
||||
// Sleep, as the darwin log reporting doesn't always happen until a bit
|
||||
// later. We need the message to come out before the process terminates.
|
||||
sleep(FINAL_WAIT_SECONDS);
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -1,6 +0,0 @@
|
|||
// The number of seconds to wait at the end of the test inferior before
|
||||
// exiting. This delay is needed to ensure the logging infrastructure
|
||||
// has flushed out the message. If we finished before all messages were
|
||||
// flushed, then the test will never see the unflushed messages, causing
|
||||
// some test logic to fail.
|
||||
#define FINAL_WAIT_SECONDS 5
|
|
@ -1,5 +0,0 @@
|
|||
LEVEL = ../../../../../make
|
||||
|
||||
C_SOURCES := main.c
|
||||
|
||||
include $(LEVEL)/Makefile.rules
|
|
@ -1,117 +0,0 @@
|
|||
"""
|
||||
Test basic DarwinLog functionality provided by the StructuredDataDarwinLog
|
||||
plugin.
|
||||
|
||||
These tests are currently only supported when running against Darwin
|
||||
targets.
|
||||
"""
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
import lldb
|
||||
import os
|
||||
import re
|
||||
|
||||
from lldbsuite.test import decorators
|
||||
from lldbsuite.test import lldbtest
|
||||
from lldbsuite.test import darwin_log
|
||||
|
||||
|
||||
class TestDarwinLogFilterMatchActivityChain(darwin_log.DarwinLogTestBase):
|
||||
|
||||
mydir = lldbtest.TestBase.compute_mydir(__file__)
|
||||
|
||||
def setUp(self):
|
||||
# Call super's setUp().
|
||||
super(TestDarwinLogFilterMatchActivityChain, self).setUp()
|
||||
|
||||
# Source filename.
|
||||
self.source = 'main.c'
|
||||
|
||||
# Output filename.
|
||||
self.exe_name = 'a.out'
|
||||
self.d = {'C_SOURCES': self.source, 'EXE': self.exe_name}
|
||||
|
||||
# Locate breakpoint.
|
||||
self.line = lldbtest.line_number(self.source, '// break here')
|
||||
|
||||
def tearDown(self):
|
||||
# Shut down the process if it's still running.
|
||||
if self.child:
|
||||
self.runCmd('process kill')
|
||||
self.expect_prompt()
|
||||
self.runCmd('quit')
|
||||
|
||||
# Let parent clean up
|
||||
super(TestDarwinLogFilterMatchActivityChain, self).tearDown()
|
||||
|
||||
# ==========================================================================
|
||||
# activity-chain filter tests
|
||||
# ==========================================================================
|
||||
|
||||
@decorators.skipUnlessDarwin
|
||||
def test_filter_accept_activity_chain_match(self):
|
||||
"""Test that fall-through reject, accept full-match activity chain works."""
|
||||
self.do_test(
|
||||
["--no-match-accepts false",
|
||||
"--filter \"accept activity-chain match "
|
||||
"parent-activity:child-activity\""])
|
||||
|
||||
# We should only see the second log message as we only accept
|
||||
# that activity.
|
||||
self.assertIsNotNone(self.child.match)
|
||||
self.assertTrue((len(self.child.match.groups()) > 1) and
|
||||
(self.child.match.group(2) == "cat2"),
|
||||
"first log line should not be present, second log line "
|
||||
"should be")
|
||||
|
||||
|
||||
@decorators.skipUnlessDarwin
|
||||
def test_filter_reject_activity_chain_partial_match(self):
|
||||
"""Test that fall-through reject, doesn't accept only partial match of activity-chain."""
|
||||
self.do_test(
|
||||
["--no-match-accepts false",
|
||||
"--filter \"accept activity-chain match parent-activity:child-activity\"", # Match the second fully.
|
||||
"--filter \"accept activity-chain match parent-ac\""]) # Only partially match the first.
|
||||
|
||||
# We should only see the second log message as we only accept
|
||||
# that activity.
|
||||
self.assertIsNotNone(self.child.match)
|
||||
self.assertTrue((len(self.child.match.groups()) > 1) and
|
||||
(self.child.match.group(2) == "cat2"),
|
||||
"first log line should not be present, second log line "
|
||||
"should be")
|
||||
|
||||
|
||||
@decorators.skipUnlessDarwin
|
||||
def test_filter_reject_activity_chain_full_match(self):
|
||||
"""Test that fall-through accept, reject match activity-chain works."""
|
||||
self.do_test(
|
||||
["--no-match-accepts true",
|
||||
"--filter \"reject activity-chain match parent-activity\""])
|
||||
|
||||
# We should only see the second log message as we rejected the first
|
||||
# via activity-chain rejection.
|
||||
self.assertIsNotNone(self.child.match)
|
||||
self.assertTrue((len(self.child.match.groups()) > 1) and
|
||||
(self.child.match.group(2) == "cat2"),
|
||||
"first log line should not be present, second log line "
|
||||
"should be")
|
||||
|
||||
|
||||
@decorators.skipUnlessDarwin
|
||||
def test_filter_accept_activity_chain_second_rule(self):
|
||||
"""Test that fall-through reject, accept activity-chain on second rule works."""
|
||||
self.do_test(
|
||||
["--no-match-accepts false",
|
||||
"--filter \"accept activity-chain match non-existent\"",
|
||||
"--filter \"accept activity-chain match parent-activity:child-activity\""])
|
||||
|
||||
# We should only see the second message since we reject by default,
|
||||
# the first filter doesn't match any, and the second filter matches
|
||||
# the activity-chain of the second log message.
|
||||
self.assertIsNotNone(self.child.match)
|
||||
self.assertTrue((len(self.child.match.groups()) > 1) and
|
||||
(self.child.match.group(2) == "cat2"),
|
||||
"first log line should not be present, second log line "
|
||||
"should be")
|
|
@ -1,43 +0,0 @@
|
|||
//===-- main.c --------------------------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include <os/activity.h>
|
||||
#include <os/log.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "../../../common/darwin_log_common.h"
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
os_log_t logger_sub1 = os_log_create("org.llvm.lldb.test.sub1", "cat1");
|
||||
os_log_t logger_sub2 = os_log_create("org.llvm.lldb.test.sub2", "cat2");
|
||||
if (!logger_sub1 || !logger_sub2)
|
||||
return 1;
|
||||
|
||||
// Note we cannot use the os_log() line as the breakpoint because, as of
|
||||
// the initial writing of this test, we get multiple breakpoints for that
|
||||
// line, which confuses the pexpect test logic.
|
||||
printf("About to log\n"); // break here
|
||||
os_activity_t parent_activity = os_activity_create("parent-activity",
|
||||
OS_ACTIVITY_CURRENT, OS_ACTIVITY_FLAG_DEFAULT);
|
||||
os_activity_apply(parent_activity, ^{
|
||||
os_log(logger_sub1, "source-log-sub1-cat1");
|
||||
os_activity_t child_activity = os_activity_create("child-activity",
|
||||
OS_ACTIVITY_CURRENT, OS_ACTIVITY_FLAG_DEFAULT);
|
||||
os_activity_apply(child_activity, ^{
|
||||
os_log(logger_sub2, "source-log-sub2-cat2");
|
||||
});
|
||||
});
|
||||
|
||||
// Sleep, as the darwin log reporting doesn't always happen until a bit
|
||||
// later. We need the message to come out before the process terminates.
|
||||
sleep(FINAL_WAIT_SECONDS);
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -1,5 +0,0 @@
|
|||
LEVEL = ../../../../../make
|
||||
|
||||
C_SOURCES := main.c
|
||||
|
||||
include $(LEVEL)/Makefile.rules
|
|
@ -1,121 +0,0 @@
|
|||
"""
|
||||
Test basic DarwinLog functionality provided by the StructuredDataDarwinLog
|
||||
plugin.
|
||||
|
||||
These tests are currently only supported when running against Darwin
|
||||
targets.
|
||||
"""
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
import lldb
|
||||
import os
|
||||
import re
|
||||
|
||||
from lldbsuite.test import decorators
|
||||
from lldbsuite.test import lldbtest
|
||||
from lldbsuite.test import darwin_log
|
||||
|
||||
|
||||
class TestDarwinLogFilterMatchActivity(darwin_log.DarwinLogTestBase):
|
||||
|
||||
mydir = lldbtest.TestBase.compute_mydir(__file__)
|
||||
|
||||
def setUp(self):
|
||||
# Call super's setUp().
|
||||
super(TestDarwinLogFilterMatchActivity, self).setUp()
|
||||
|
||||
# Source filename.
|
||||
self.source = 'main.c'
|
||||
|
||||
# Output filename.
|
||||
self.exe_name = 'a.out'
|
||||
self.d = {'C_SOURCES': self.source, 'EXE': self.exe_name}
|
||||
|
||||
# Locate breakpoint.
|
||||
self.line = lldbtest.line_number(self.source, '// break here')
|
||||
|
||||
def tearDown(self):
|
||||
# Shut down the process if it's still running.
|
||||
if self.child:
|
||||
self.runCmd('process kill')
|
||||
self.expect_prompt()
|
||||
self.runCmd('quit')
|
||||
|
||||
# Let parent clean up
|
||||
super(TestDarwinLogFilterMatchActivity, self).tearDown()
|
||||
|
||||
# ==========================================================================
|
||||
# activity filter tests
|
||||
# ==========================================================================
|
||||
|
||||
@decorators.skipUnlessDarwin
|
||||
def test_filter_accept_activity_match(self):
|
||||
"""Test that fall-through reject, accept match activity works."""
|
||||
self.do_test(
|
||||
["--no-match-accepts false",
|
||||
"--filter \"accept activity match child-activity\""]
|
||||
)
|
||||
|
||||
# We should only see the second log message as we only accept
|
||||
# that activity.
|
||||
self.assertIsNotNone(self.child.match)
|
||||
self.assertTrue((len(self.child.match.groups()) > 1) and
|
||||
(self.child.match.group(2) == "cat2"),
|
||||
"first log line should not be present, second log line "
|
||||
"should be")
|
||||
|
||||
|
||||
@decorators.skipUnlessDarwin
|
||||
def test_filter_reject_activity_partial_match(self):
|
||||
"""Test that fall-through reject, accept match activity via partial match does not accept."""
|
||||
self.do_test(
|
||||
["--no-match-accepts false",
|
||||
"--filter \"accept activity match child-activity\"", # Fully match second message.
|
||||
"--filter \"accept activity match parent-\""] # Only partially match first message.
|
||||
)
|
||||
|
||||
# We should only see the second log message as we only accept
|
||||
# that activity.
|
||||
self.assertIsNotNone(self.child.match)
|
||||
self.assertTrue((len(self.child.match.groups()) > 1) and
|
||||
(self.child.match.group(2) == "cat2"),
|
||||
"first log line should not be present, second log line "
|
||||
"should be")
|
||||
|
||||
|
||||
@decorators.skipUnlessDarwin
|
||||
def test_filter_reject_activity_full_match(self):
|
||||
"""Test that fall-through accept, reject match activity works."""
|
||||
self.do_test(
|
||||
["--no-match-accepts true",
|
||||
"--filter \"reject activity match parent-activity\""]
|
||||
)
|
||||
|
||||
# We should only see the second log message as we rejected the first
|
||||
# via activity rejection.
|
||||
self.assertIsNotNone(self.child.match)
|
||||
self.assertTrue((len(self.child.match.groups()) > 1) and
|
||||
(self.child.match.group(2) == "cat2"),
|
||||
"first log line should not be present, second log line "
|
||||
"should be")
|
||||
|
||||
|
||||
@decorators.skipUnlessDarwin
|
||||
def test_filter_accept_activity_second_rule(self):
|
||||
"""Test that fall-through reject, accept regex activity on second rule works."""
|
||||
self.do_test(
|
||||
["--no-match-accepts false",
|
||||
"--filter \"accept activity match non-existent\"",
|
||||
"--filter \"accept activity match child-activity\""
|
||||
]
|
||||
)
|
||||
|
||||
# We should only see the second message since we reject by default,
|
||||
# the first filter doesn't match any, and the second filter matches
|
||||
# the activity of the second log message.
|
||||
self.assertIsNotNone(self.child.match)
|
||||
self.assertTrue((len(self.child.match.groups()) > 1) and
|
||||
(self.child.match.group(2) == "cat2"),
|
||||
"first log line should not be present, second log line "
|
||||
"should be")
|
|
@ -1,43 +0,0 @@
|
|||
//===-- main.c --------------------------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include <os/activity.h>
|
||||
#include <os/log.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "../../../common/darwin_log_common.h"
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
os_log_t logger_sub1 = os_log_create("org.llvm.lldb.test.sub1", "cat1");
|
||||
os_log_t logger_sub2 = os_log_create("org.llvm.lldb.test.sub2", "cat2");
|
||||
if (!logger_sub1 || !logger_sub2)
|
||||
return 1;
|
||||
|
||||
// Note we cannot use the os_log() line as the breakpoint because, as of
|
||||
// the initial writing of this test, we get multiple breakpoints for that
|
||||
// line, which confuses the pexpect test logic.
|
||||
printf("About to log\n"); // break here
|
||||
os_activity_t parent_activity = os_activity_create("parent-activity",
|
||||
OS_ACTIVITY_CURRENT, OS_ACTIVITY_FLAG_DEFAULT);
|
||||
os_activity_apply(parent_activity, ^{
|
||||
os_log(logger_sub1, "source-log-sub1-cat1");
|
||||
os_activity_t child_activity = os_activity_create("child-activity",
|
||||
OS_ACTIVITY_CURRENT, OS_ACTIVITY_FLAG_DEFAULT);
|
||||
os_activity_apply(child_activity, ^{
|
||||
os_log(logger_sub2, "source-log-sub2-cat2");
|
||||
});
|
||||
});
|
||||
|
||||
// Sleep, as the darwin log reporting doesn't always happen until a bit
|
||||
// later. We need the message to come out before the process terminates.
|
||||
sleep(FINAL_WAIT_SECONDS);
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -1,5 +0,0 @@
|
|||
LEVEL = ../../../../../make
|
||||
|
||||
C_SOURCES := main.c
|
||||
|
||||
include $(LEVEL)/Makefile.rules
|
|
@ -1,118 +0,0 @@
|
|||
"""
|
||||
Test basic DarwinLog functionality provided by the StructuredDataDarwinLog
|
||||
plugin.
|
||||
|
||||
These tests are currently only supported when running against Darwin
|
||||
targets.
|
||||
"""
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
import lldb
|
||||
import os
|
||||
import re
|
||||
|
||||
from lldbsuite.test import decorators
|
||||
from lldbsuite.test import lldbtest
|
||||
from lldbsuite.test import darwin_log
|
||||
|
||||
|
||||
class TestDarwinLogFilterMatchCategory(darwin_log.DarwinLogTestBase):
|
||||
|
||||
mydir = lldbtest.TestBase.compute_mydir(__file__)
|
||||
|
||||
def setUp(self):
|
||||
# Call super's setUp().
|
||||
super(TestDarwinLogFilterMatchCategory, self).setUp()
|
||||
|
||||
# Source filename.
|
||||
self.source = 'main.c'
|
||||
|
||||
# Output filename.
|
||||
self.exe_name = 'a.out'
|
||||
self.d = {'C_SOURCES': self.source, 'EXE': self.exe_name}
|
||||
|
||||
# Locate breakpoint.
|
||||
self.line = lldbtest.line_number(self.source, '// break here')
|
||||
|
||||
def tearDown(self):
|
||||
# Shut down the process if it's still running.
|
||||
if self.child:
|
||||
self.runCmd('process kill')
|
||||
self.expect_prompt()
|
||||
self.runCmd('quit')
|
||||
|
||||
# Let parent clean up
|
||||
super(TestDarwinLogFilterMatchCategory, self).tearDown()
|
||||
|
||||
# ==========================================================================
|
||||
# category filter tests
|
||||
# ==========================================================================
|
||||
|
||||
@decorators.skipUnlessDarwin
|
||||
def test_filter_accept_category_full_match(self):
|
||||
"""Test that fall-through reject, accept match single category works."""
|
||||
self.do_test(
|
||||
["--no-match-accepts false",
|
||||
"--filter \"accept category match cat2\""]
|
||||
)
|
||||
|
||||
# We should only see the second log message as we only accept
|
||||
# that category.
|
||||
self.assertIsNotNone(self.child.match)
|
||||
self.assertTrue((len(self.child.match.groups()) > 1) and
|
||||
(self.child.match.group(2) == "cat2"),
|
||||
"first log line should not be present, second log line "
|
||||
"should be")
|
||||
|
||||
@decorators.skipUnlessDarwin
|
||||
def test_filter_reject_category_partial_match(self):
|
||||
"""Test that fall-through reject, accept regex category via partial match works."""
|
||||
self.do_test(
|
||||
["--no-match-accepts false",
|
||||
"--filter \"accept category match cat2\"", # Fully match the second message.
|
||||
"--filter \"accept category match at1\""] # Only partially match first message. Should not show up.
|
||||
)
|
||||
|
||||
# We should only see the second log message as we only accept
|
||||
# that category.
|
||||
self.assertIsNotNone(self.child.match)
|
||||
self.assertTrue((len(self.child.match.groups()) > 1) and
|
||||
(self.child.match.group(2) == "cat2"),
|
||||
"first log line should not be present, second log line "
|
||||
"should be")
|
||||
|
||||
@decorators.skipUnlessDarwin
|
||||
def test_filter_reject_category_full_match(self):
|
||||
"""Test that fall-through accept, reject match category works."""
|
||||
self.do_test(
|
||||
["--no-match-accepts true",
|
||||
"--filter \"reject category match cat1\""]
|
||||
)
|
||||
|
||||
# We should only see the second log message as we rejected the first
|
||||
# via category rejection.
|
||||
self.assertIsNotNone(self.child.match)
|
||||
self.assertTrue((len(self.child.match.groups()) > 1) and
|
||||
(self.child.match.group(2) == "cat2"),
|
||||
"first log line should not be present, second log line "
|
||||
"should be")
|
||||
|
||||
@decorators.skipUnlessDarwin
|
||||
def test_filter_accept_category_second_rule(self):
|
||||
"""Test that fall-through reject, accept match category on second rule works."""
|
||||
self.do_test(
|
||||
["--no-match-accepts false",
|
||||
"--filter \"accept category match non-existent\"",
|
||||
"--filter \"accept category match cat2\""
|
||||
]
|
||||
)
|
||||
|
||||
# We should only see the second message since we reject by default,
|
||||
# the first filter doesn't match any, and the second filter matches
|
||||
# the category of the second log message.
|
||||
self.assertIsNotNone(self.child.match)
|
||||
self.assertTrue((len(self.child.match.groups()) > 1) and
|
||||
(self.child.match.group(2) == "cat2"),
|
||||
"first log line should not be present, second log line "
|
||||
"should be")
|
|
@ -1,43 +0,0 @@
|
|||
//===-- main.c --------------------------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include <os/activity.h>
|
||||
#include <os/log.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "../../../common/darwin_log_common.h"
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
os_log_t logger_sub1 = os_log_create("org.llvm.lldb.test.sub1", "cat1");
|
||||
os_log_t logger_sub2 = os_log_create("org.llvm.lldb.test.sub2", "cat2");
|
||||
if (!logger_sub1 || !logger_sub2)
|
||||
return 1;
|
||||
|
||||
// Note we cannot use the os_log() line as the breakpoint because, as of
|
||||
// the initial writing of this test, we get multiple breakpoints for that
|
||||
// line, which confuses the pexpect test logic.
|
||||
printf("About to log\n"); // break here
|
||||
os_activity_t parent_activity = os_activity_create("parent-activity",
|
||||
OS_ACTIVITY_CURRENT, OS_ACTIVITY_FLAG_DEFAULT);
|
||||
os_activity_apply(parent_activity, ^{
|
||||
os_log(logger_sub1, "source-log-sub1-cat1");
|
||||
os_activity_t child_activity = os_activity_create("child-activity",
|
||||
OS_ACTIVITY_CURRENT, OS_ACTIVITY_FLAG_DEFAULT);
|
||||
os_activity_apply(child_activity, ^{
|
||||
os_log(logger_sub2, "source-log-sub2-cat2");
|
||||
});
|
||||
});
|
||||
|
||||
// Sleep, as the darwin log reporting doesn't always happen until a bit
|
||||
// later. We need the message to come out before the process terminates.
|
||||
sleep(FINAL_WAIT_SECONDS);
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -1,5 +0,0 @@
|
|||
LEVEL = ../../../../../make
|
||||
|
||||
C_SOURCES := main.c
|
||||
|
||||
include $(LEVEL)/Makefile.rules
|
|
@ -1,132 +0,0 @@
|
|||
"""
|
||||
Test basic DarwinLog functionality provided by the StructuredDataDarwinLog
|
||||
plugin.
|
||||
|
||||
These tests are currently only supported when running against Darwin
|
||||
targets.
|
||||
"""
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
import lldb
|
||||
import os
|
||||
import re
|
||||
|
||||
from lldbsuite.test import decorators
|
||||
from lldbsuite.test import lldbtest
|
||||
from lldbsuite.test import darwin_log
|
||||
|
||||
|
||||
class TestDarwinLogFilterMatchMessage(darwin_log.DarwinLogTestBase):
|
||||
|
||||
mydir = lldbtest.TestBase.compute_mydir(__file__)
|
||||
|
||||
def setUp(self):
|
||||
# Call super's setUp().
|
||||
super(TestDarwinLogFilterMatchMessage, self).setUp()
|
||||
|
||||
# Source filename.
|
||||
self.source = 'main.c'
|
||||
|
||||
# Output filename.
|
||||
self.exe_name = 'a.out'
|
||||
self.d = {'C_SOURCES': self.source, 'EXE': self.exe_name}
|
||||
|
||||
# Locate breakpoint.
|
||||
self.line = lldbtest.line_number(self.source, '// break here')
|
||||
|
||||
self.strict_sources = True
|
||||
|
||||
# Turn on process monitor logging while we work out issues.
|
||||
self.enable_process_monitor_logging = True
|
||||
|
||||
|
||||
def tearDown(self):
|
||||
# Shut down the process if it's still running.
|
||||
if self.child:
|
||||
self.runCmd('process kill')
|
||||
self.expect_prompt()
|
||||
self.runCmd('quit')
|
||||
|
||||
# Let parent clean up
|
||||
super(TestDarwinLogFilterMatchMessage, self).tearDown()
|
||||
|
||||
# ==========================================================================
|
||||
# category filter tests
|
||||
# ==========================================================================
|
||||
|
||||
EXPECT_REGEXES = [
|
||||
re.compile(r"log message ([^-]+)-(\S+)"),
|
||||
re.compile(r"exited with status")
|
||||
]
|
||||
|
||||
@decorators.skipUnlessDarwin
|
||||
def test_filter_accept_message_full_match(self):
|
||||
"""Test that fall-through reject, accept match whole message works."""
|
||||
self.do_test(
|
||||
["--no-match-accepts false",
|
||||
"--filter \"accept message match log message sub2-cat2\""],
|
||||
expect_regexes=self.EXPECT_REGEXES
|
||||
)
|
||||
|
||||
# We should only see the second log message as we only accept
|
||||
# that message contents.
|
||||
self.assertIsNotNone(self.child.match)
|
||||
self.assertTrue((len(self.child.match.groups()) > 1) and
|
||||
(self.child.match.group(2) == "cat2"),
|
||||
"first log line should not be present, second log line "
|
||||
"should be")
|
||||
|
||||
@decorators.skipUnlessDarwin
|
||||
def test_filter_no_accept_message_partial_match(self):
|
||||
"""Test that fall-through reject, match message via partial content match doesn't accept."""
|
||||
self.do_test(
|
||||
["--no-match-accepts false",
|
||||
"--filter \"accept message match log message sub2-cat2\"",
|
||||
"--filter \"accept message match sub1-cat1\""],
|
||||
expect_regexes=self.EXPECT_REGEXES
|
||||
)
|
||||
|
||||
# We should only see the second log message as the partial match on
|
||||
# the first message should not pass.
|
||||
self.assertIsNotNone(self.child.match)
|
||||
self.assertTrue((len(self.child.match.groups()) > 1) and
|
||||
(self.child.match.group(2) == "cat2"),
|
||||
"first log line should not be present, second log line "
|
||||
"should be")
|
||||
|
||||
@decorators.skipUnlessDarwin
|
||||
def test_filter_reject_category_full_match(self):
|
||||
"""Test that fall-through accept, reject match message works."""
|
||||
self.do_test(
|
||||
["--no-match-accepts true",
|
||||
"--filter \"reject message match log message sub1-cat1\""],
|
||||
expect_regexes=self.EXPECT_REGEXES
|
||||
)
|
||||
|
||||
# We should only see the second log message as we rejected the first
|
||||
# via message contents rejection.
|
||||
self.assertIsNotNone(self.child.match)
|
||||
self.assertTrue((len(self.child.match.groups()) > 1) and
|
||||
(self.child.match.group(2) == "cat2"),
|
||||
"first log line should not be present, second log line "
|
||||
"should be")
|
||||
|
||||
@decorators.skipUnlessDarwin
|
||||
def test_filter_accept_category_second_rule(self):
|
||||
"""Test that fall-through reject, accept match category on second rule works."""
|
||||
self.do_test(
|
||||
["--no-match-accepts false",
|
||||
"--filter \"accept message match non-existent\"",
|
||||
"--filter \"accept message match log message sub2-cat2\""],
|
||||
expect_regexes=self.EXPECT_REGEXES
|
||||
)
|
||||
|
||||
# We should only see the second message since we reject by default,
|
||||
# the first filter doesn't match any, and the second filter matches
|
||||
# the category of the second log message.
|
||||
self.assertIsNotNone(self.child.match)
|
||||
self.assertTrue((len(self.child.match.groups()) > 1) and
|
||||
(self.child.match.group(2) == "cat2"),
|
||||
"first log line should not be present, second log line "
|
||||
"should be")
|
|
@ -1,35 +0,0 @@
|
|||
//===-- main.c --------------------------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include <os/activity.h>
|
||||
#include <os/log.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "../../../common/darwin_log_common.h"
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
os_log_t logger_sub1 = os_log_create("org.llvm.lldb.test.sub1", "cat1");
|
||||
os_log_t logger_sub2 = os_log_create("org.llvm.lldb.test.sub2", "cat2");
|
||||
if (!logger_sub1 || !logger_sub2)
|
||||
return 1;
|
||||
|
||||
// Note we cannot use the os_log() line as the breakpoint because, as of
|
||||
// the initial writing of this test, we get multiple breakpoints for that
|
||||
// line, which confuses the pexpect test logic.
|
||||
printf("About to log\n"); // break here
|
||||
os_log(logger_sub1, "log message sub%d-cat%d", 1, 1);
|
||||
os_log(logger_sub2, "log message sub%d-cat%d", 2, 2);
|
||||
|
||||
// Sleep, as the darwin log reporting doesn't always happen until a bit
|
||||
// later. We need the message to come out before the process terminates.
|
||||
sleep(1);
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -1,5 +0,0 @@
|
|||
LEVEL = ../../../../../make
|
||||
|
||||
C_SOURCES := main.c
|
||||
|
||||
include $(LEVEL)/Makefile.rules
|
|
@ -1,118 +0,0 @@
|
|||
"""
|
||||
Test basic DarwinLog functionality provided by the StructuredDataDarwinLog
|
||||
plugin.
|
||||
|
||||
These tests are currently only supported when running against Darwin
|
||||
targets.
|
||||
"""
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
import lldb
|
||||
import os
|
||||
import re
|
||||
|
||||
from lldbsuite.test import decorators
|
||||
from lldbsuite.test import lldbtest
|
||||
from lldbsuite.test import darwin_log
|
||||
|
||||
|
||||
class TestDarwinLogFilterMatchSubsystem(darwin_log.DarwinLogTestBase):
|
||||
|
||||
mydir = lldbtest.TestBase.compute_mydir(__file__)
|
||||
|
||||
def setUp(self):
|
||||
# Call super's setUp().
|
||||
super(TestDarwinLogFilterMatchSubsystem, self).setUp()
|
||||
|
||||
# Source filename.
|
||||
self.source = 'main.c'
|
||||
|
||||
# Output filename.
|
||||
self.exe_name = 'a.out'
|
||||
self.d = {'C_SOURCES': self.source, 'EXE': self.exe_name}
|
||||
|
||||
# Locate breakpoint.
|
||||
self.line = lldbtest.line_number(self.source, '// break here')
|
||||
|
||||
def tearDown(self):
|
||||
# Shut down the process if it's still running.
|
||||
if self.child:
|
||||
self.runCmd('process kill')
|
||||
self.expect_prompt()
|
||||
self.runCmd('quit')
|
||||
|
||||
# Let parent clean up
|
||||
super(TestDarwinLogFilterMatchSubsystem, self).tearDown()
|
||||
|
||||
# ==========================================================================
|
||||
# subsystem filter tests
|
||||
# ==========================================================================
|
||||
|
||||
@decorators.skipUnlessDarwin
|
||||
def test_filter_accept_subsystem_full_match(self):
|
||||
"""Test that fall-through reject, accept match single subsystem works."""
|
||||
self.do_test(
|
||||
["--no-match-accepts false",
|
||||
"--filter \"accept subsystem match org.llvm.lldb.test.sub2\""]
|
||||
)
|
||||
|
||||
# We should only see the second log message as we only accept
|
||||
# that subsystem.
|
||||
self.assertIsNotNone(self.child.match)
|
||||
self.assertTrue((len(self.child.match.groups()) > 0) and
|
||||
(self.child.match.group(1) == "sub2"),
|
||||
"first log line should not be present, second log line "
|
||||
"should be")
|
||||
|
||||
@decorators.skipUnlessDarwin
|
||||
def test_filter_reject_subsystem_partial_match(self):
|
||||
"""Test that fall-through reject, doesn't accept match subsystem via partial-match."""
|
||||
self.do_test(
|
||||
["--no-match-accepts false",
|
||||
"--filter \"accept subsystem match org.llvm.lldb.test.sub2\"", # Fully match second message subsystem.
|
||||
"--filter \"accept subsystem match sub1\""] # Only partially match first subsystem.
|
||||
)
|
||||
|
||||
# We should only see the second log message as we only accept
|
||||
# that subsystem.
|
||||
self.assertIsNotNone(self.child.match)
|
||||
self.assertTrue((len(self.child.match.groups()) > 0) and
|
||||
(self.child.match.group(1) == "sub2"),
|
||||
"first log line should not be present, second log line "
|
||||
"should be")
|
||||
|
||||
@decorators.skipUnlessDarwin
|
||||
def test_filter_reject_subsystem_full_match(self):
|
||||
"""Test that fall-through accept, reject match subsystem works."""
|
||||
self.do_test(
|
||||
["--no-match-accepts true",
|
||||
"--filter \"reject subsystem match org.llvm.lldb.test.sub1\""]
|
||||
)
|
||||
|
||||
# We should only see the second log message as we rejected the first
|
||||
# via subsystem rejection.
|
||||
self.assertIsNotNone(self.child.match)
|
||||
self.assertTrue((len(self.child.match.groups()) > 0) and
|
||||
(self.child.match.group(1) == "sub2"),
|
||||
"first log line should not be present, second log line "
|
||||
"should be")
|
||||
|
||||
@decorators.skipUnlessDarwin
|
||||
def test_filter_accept_subsystem_second_rule(self):
|
||||
"""Test that fall-through reject, accept match subsystem on second rule works."""
|
||||
self.do_test(
|
||||
["--no-match-accepts false",
|
||||
"--filter \"accept subsystem match non-existent\"",
|
||||
"--filter \"accept subsystem match org.llvm.lldb.test.sub2\""
|
||||
]
|
||||
)
|
||||
|
||||
# We should only see the second message since we reject by default,
|
||||
# the first filter doesn't match any, and the second filter matches
|
||||
# the subsystem of the second log message.
|
||||
self.assertIsNotNone(self.child.match)
|
||||
self.assertTrue((len(self.child.match.groups()) > 0) and
|
||||
(self.child.match.group(1) == "sub2"),
|
||||
"first log line should not be present, second log line "
|
||||
"should be")
|
|
@ -1,43 +0,0 @@
|
|||
//===-- main.c --------------------------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include <os/activity.h>
|
||||
#include <os/log.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "../../../common/darwin_log_common.h"
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
os_log_t logger_sub1 = os_log_create("org.llvm.lldb.test.sub1", "cat1");
|
||||
os_log_t logger_sub2 = os_log_create("org.llvm.lldb.test.sub2", "cat2");
|
||||
if (!logger_sub1 || !logger_sub2)
|
||||
return 1;
|
||||
|
||||
// Note we cannot use the os_log() line as the breakpoint because, as of
|
||||
// the initial writing of this test, we get multiple breakpoints for that
|
||||
// line, which confuses the pexpect test logic.
|
||||
printf("About to log\n"); // break here
|
||||
os_activity_t parent_activity = os_activity_create("parent-activity",
|
||||
OS_ACTIVITY_CURRENT, OS_ACTIVITY_FLAG_DEFAULT);
|
||||
os_activity_apply(parent_activity, ^{
|
||||
os_log(logger_sub1, "source-log-sub1-cat1");
|
||||
os_activity_t child_activity = os_activity_create("child-activity",
|
||||
OS_ACTIVITY_CURRENT, OS_ACTIVITY_FLAG_DEFAULT);
|
||||
os_activity_apply(child_activity, ^{
|
||||
os_log(logger_sub2, "source-log-sub2-cat2");
|
||||
});
|
||||
});
|
||||
|
||||
// Sleep, as the darwin log reporting doesn't always happen until a bit
|
||||
// later. We need the message to come out before the process terminates.
|
||||
sleep(FINAL_WAIT_SECONDS);
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -1,5 +0,0 @@
|
|||
LEVEL = ../../../../../make
|
||||
|
||||
C_SOURCES := main.c
|
||||
|
||||
include $(LEVEL)/Makefile.rules
|
|
@ -1,132 +0,0 @@
|
|||
"""
|
||||
Test basic DarwinLog functionality provided by the StructuredDataDarwinLog
|
||||
plugin.
|
||||
|
||||
These tests are currently only supported when running against Darwin
|
||||
targets.
|
||||
"""
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
import lldb
|
||||
import os
|
||||
import re
|
||||
|
||||
from lldbsuite.test import decorators
|
||||
from lldbsuite.test import lldbtest
|
||||
from lldbsuite.test import darwin_log
|
||||
|
||||
|
||||
class TestDarwinLogFilterRegexActivityChain(darwin_log.DarwinLogTestBase):
|
||||
|
||||
mydir = lldbtest.TestBase.compute_mydir(__file__)
|
||||
|
||||
def setUp(self):
|
||||
# Call super's setUp().
|
||||
super(TestDarwinLogFilterRegexActivityChain, self).setUp()
|
||||
|
||||
# Source filename.
|
||||
self.source = 'main.c'
|
||||
|
||||
# Output filename.
|
||||
self.exe_name = 'a.out'
|
||||
self.d = {'C_SOURCES': self.source, 'EXE': self.exe_name}
|
||||
|
||||
# Locate breakpoint.
|
||||
self.line = lldbtest.line_number(self.source, '// break here')
|
||||
|
||||
def tearDown(self):
|
||||
# Shut down the process if it's still running.
|
||||
if self.child:
|
||||
self.runCmd('process kill')
|
||||
self.expect_prompt()
|
||||
self.runCmd('quit')
|
||||
|
||||
# Let parent clean up
|
||||
super(TestDarwinLogFilterRegexActivityChain, self).tearDown()
|
||||
|
||||
# ==========================================================================
|
||||
# activity-chain filter tests
|
||||
# ==========================================================================
|
||||
|
||||
@decorators.skipUnlessDarwin
|
||||
def test_filter_accept_activity_chain_full_match(self):
|
||||
"""Test that fall-through reject, accept full-match activity chain works."""
|
||||
self.do_test(
|
||||
["--no-match-accepts false",
|
||||
"--filter \"accept activity-chain regex "
|
||||
"parent-activity:child-activity\""])
|
||||
|
||||
# We should only see the second log message as we only accept
|
||||
# that activity.
|
||||
self.assertIsNotNone(self.child.match)
|
||||
self.assertTrue((len(self.child.match.groups()) > 1) and
|
||||
(self.child.match.group(2) == "cat2"),
|
||||
"first log line should not be present, second log line "
|
||||
"should be")
|
||||
|
||||
|
||||
@decorators.skipUnlessDarwin
|
||||
def test_filter_accept_activity_chain_partial_match(self):
|
||||
"""Test that fall-through reject, accept activity-chain via partial match works."""
|
||||
self.do_test(
|
||||
["--no-match-accepts false",
|
||||
"--filter \"accept activity-chain regex :child-activity\""])
|
||||
|
||||
# We should only see the second log message as we only accept
|
||||
# that activity.
|
||||
self.assertIsNotNone(self.child.match)
|
||||
self.assertTrue((len(self.child.match.groups()) > 1) and
|
||||
(self.child.match.group(2) == "cat2"),
|
||||
"first log line should not be present, second log line "
|
||||
"should be")
|
||||
|
||||
|
||||
@decorators.skipUnlessDarwin
|
||||
def test_filter_reject_activity_chain_full_match(self):
|
||||
"""Test that fall-through accept, reject activity-chain works."""
|
||||
self.do_test(
|
||||
["--no-match-accepts true",
|
||||
"--filter \"reject activity-chain regex parent-activity:child-..tivity\""])
|
||||
|
||||
# We should only see the second log message as we rejected the first
|
||||
# via activity-chain rejection.
|
||||
self.assertIsNotNone(self.child.match)
|
||||
self.assertTrue((len(self.child.match.groups()) > 1) and
|
||||
(self.child.match.group(2) == "cat1"),
|
||||
"first log line should not be present, second log line "
|
||||
"should be")
|
||||
|
||||
|
||||
@decorators.skipUnlessDarwin
|
||||
def test_filter_reject_activity_chain_partial_match(self):
|
||||
"""Test that fall-through accept, reject activity-chain by partial match works."""
|
||||
self.do_test(
|
||||
["--no-match-accepts true",
|
||||
"--filter \"reject activity-chain regex ^p[^:]+$\""])
|
||||
|
||||
# We should only see the second log message as we rejected the first
|
||||
# via activity-chain rejection.
|
||||
self.assertIsNotNone(self.child.match)
|
||||
self.assertTrue((len(self.child.match.groups()) > 1) and
|
||||
(self.child.match.group(2) == "cat2"),
|
||||
"first log line should not be present, second log line "
|
||||
"should be")
|
||||
|
||||
|
||||
@decorators.skipUnlessDarwin
|
||||
def test_filter_accept_activity_chain_second_rule(self):
|
||||
"""Test that fall-through reject, accept activity-chain on second rule works."""
|
||||
self.do_test(
|
||||
["--no-match-accepts false",
|
||||
"--filter \"accept activity-chain regex non-existent\"",
|
||||
"--filter \"accept activity-chain regex child-activity\""])
|
||||
|
||||
# We should only see the second message since we reject by default,
|
||||
# the first filter doesn't match any, and the second filter matches
|
||||
# the activity-chain of the second log message.
|
||||
self.assertIsNotNone(self.child.match)
|
||||
self.assertTrue((len(self.child.match.groups()) > 1) and
|
||||
(self.child.match.group(2) == "cat2"),
|
||||
"first log line should not be present, second log line "
|
||||
"should be")
|
|
@ -1,43 +0,0 @@
|
|||
//===-- main.c --------------------------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include <os/activity.h>
|
||||
#include <os/log.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "../../../common/darwin_log_common.h"
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
os_log_t logger_sub1 = os_log_create("org.llvm.lldb.test.sub1", "cat1");
|
||||
os_log_t logger_sub2 = os_log_create("org.llvm.lldb.test.sub2", "cat2");
|
||||
if (!logger_sub1 || !logger_sub2)
|
||||
return 1;
|
||||
|
||||
// Note we cannot use the os_log() line as the breakpoint because, as of
|
||||
// the initial writing of this test, we get multiple breakpoints for that
|
||||
// line, which confuses the pexpect test logic.
|
||||
printf("About to log\n"); // break here
|
||||
os_activity_t parent_activity = os_activity_create("parent-activity",
|
||||
OS_ACTIVITY_CURRENT, OS_ACTIVITY_FLAG_DEFAULT);
|
||||
os_activity_apply(parent_activity, ^{
|
||||
os_log(logger_sub1, "source-log-sub1-cat1");
|
||||
os_activity_t child_activity = os_activity_create("child-activity",
|
||||
OS_ACTIVITY_CURRENT, OS_ACTIVITY_FLAG_DEFAULT);
|
||||
os_activity_apply(child_activity, ^{
|
||||
os_log(logger_sub2, "source-log-sub2-cat2");
|
||||
});
|
||||
});
|
||||
|
||||
// Sleep, as the darwin log reporting doesn't always happen until a bit
|
||||
// later. We need the message to come out before the process terminates.
|
||||
sleep(FINAL_WAIT_SECONDS);
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -1,5 +0,0 @@
|
|||
LEVEL = ../../../../../make
|
||||
|
||||
C_SOURCES := main.c
|
||||
|
||||
include $(LEVEL)/Makefile.rules
|
|
@ -1,137 +0,0 @@
|
|||
"""
|
||||
Test basic DarwinLog functionality provided by the StructuredDataDarwinLog
|
||||
plugin.
|
||||
|
||||
These tests are currently only supported when running against Darwin
|
||||
targets.
|
||||
"""
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
import lldb
|
||||
import os
|
||||
import re
|
||||
|
||||
from lldbsuite.test import decorators
|
||||
from lldbsuite.test import lldbtest
|
||||
from lldbsuite.test import darwin_log
|
||||
|
||||
|
||||
class TestDarwinLogFilterRegexActivity(darwin_log.DarwinLogTestBase):
|
||||
|
||||
mydir = lldbtest.TestBase.compute_mydir(__file__)
|
||||
|
||||
def setUp(self):
|
||||
# Call super's setUp().
|
||||
super(TestDarwinLogFilterRegexActivity, self).setUp()
|
||||
|
||||
# Source filename.
|
||||
self.source = 'main.c'
|
||||
|
||||
# Output filename.
|
||||
self.exe_name = 'a.out'
|
||||
self.d = {'C_SOURCES': self.source, 'EXE': self.exe_name}
|
||||
|
||||
# Locate breakpoint.
|
||||
self.line = lldbtest.line_number(self.source, '// break here')
|
||||
|
||||
def tearDown(self):
|
||||
# Shut down the process if it's still running.
|
||||
if self.child:
|
||||
self.runCmd('process kill')
|
||||
self.expect_prompt()
|
||||
self.runCmd('quit')
|
||||
|
||||
# Let parent clean up
|
||||
super(TestDarwinLogFilterRegexActivity, self).tearDown()
|
||||
|
||||
# ==========================================================================
|
||||
# activity filter tests
|
||||
# ==========================================================================
|
||||
|
||||
@decorators.skipUnlessDarwin
|
||||
def test_filter_accept_activity_full_match(self):
|
||||
"""Test that fall-through reject, accept regex full-match activity works."""
|
||||
self.do_test(
|
||||
["--no-match-accepts false",
|
||||
"--filter \"accept activity regex child-activity\""]
|
||||
)
|
||||
|
||||
# We should only see the second log message as we only accept
|
||||
# that activity.
|
||||
self.assertIsNotNone(self.child.match)
|
||||
self.assertTrue((len(self.child.match.groups()) > 1) and
|
||||
(self.child.match.group(2) == "cat2"),
|
||||
"first log line should not be present, second log line "
|
||||
"should be")
|
||||
|
||||
|
||||
@decorators.skipUnlessDarwin
|
||||
def test_filter_accept_activity_partial_match(self):
|
||||
"""Test that fall-through reject, regex accept activity via partial match works."""
|
||||
self.do_test(
|
||||
["--no-match-accepts false",
|
||||
"--filter \"accept activity regex child-.*\""]
|
||||
)
|
||||
|
||||
# We should only see the second log message as we only accept
|
||||
# that activity.
|
||||
self.assertIsNotNone(self.child.match)
|
||||
self.assertTrue((len(self.child.match.groups()) > 1) and
|
||||
(self.child.match.group(2) == "cat2"),
|
||||
"first log line should not be present, second log line "
|
||||
"should be")
|
||||
|
||||
|
||||
@decorators.skipUnlessDarwin
|
||||
def test_filter_reject_activity_full_match(self):
|
||||
"""Test that fall-through accept, reject regex activity works."""
|
||||
self.do_test(
|
||||
["--no-match-accepts true",
|
||||
"--filter \"reject activity regex parent-activity\""]
|
||||
)
|
||||
|
||||
# We should only see the second log message as we rejected the first
|
||||
# via activity rejection.
|
||||
self.assertIsNotNone(self.child.match)
|
||||
self.assertTrue((len(self.child.match.groups()) > 1) and
|
||||
(self.child.match.group(2) == "cat2"),
|
||||
"first log line should not be present, second log line "
|
||||
"should be")
|
||||
|
||||
|
||||
@decorators.skipUnlessDarwin
|
||||
def test_filter_reject_activity_partial_match(self):
|
||||
"""Test that fall-through accept, reject regex activity by partial match works."""
|
||||
self.do_test(
|
||||
["--no-match-accepts true",
|
||||
"--filter \"reject activity regex p.+-activity\""]
|
||||
)
|
||||
|
||||
# We should only see the second log message as we rejected the first
|
||||
# via activity rejection.
|
||||
self.assertIsNotNone(self.child.match)
|
||||
self.assertTrue((len(self.child.match.groups()) > 1) and
|
||||
(self.child.match.group(2) == "cat2"),
|
||||
"first log line should not be present, second log line "
|
||||
"should be")
|
||||
|
||||
|
||||
@decorators.skipUnlessDarwin
|
||||
def test_filter_accept_activity_second_rule(self):
|
||||
"""Test that fall-through reject, accept regex activity on second rule works."""
|
||||
self.do_test(
|
||||
["--no-match-accepts false",
|
||||
"--filter \"accept activity regex non-existent\"",
|
||||
"--filter \"accept activity regex child-activity\""
|
||||
]
|
||||
)
|
||||
|
||||
# We should only see the second message since we reject by default,
|
||||
# the first filter doesn't match any, and the second filter matches
|
||||
# the activity of the second log message.
|
||||
self.assertIsNotNone(self.child.match)
|
||||
self.assertTrue((len(self.child.match.groups()) > 1) and
|
||||
(self.child.match.group(2) == "cat2"),
|
||||
"first log line should not be present, second log line "
|
||||
"should be")
|
|
@ -1,43 +0,0 @@
|
|||
//===-- main.c --------------------------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include <os/activity.h>
|
||||
#include <os/log.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "../../../common/darwin_log_common.h"
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
os_log_t logger_sub1 = os_log_create("org.llvm.lldb.test.sub1", "cat1");
|
||||
os_log_t logger_sub2 = os_log_create("org.llvm.lldb.test.sub2", "cat2");
|
||||
if (!logger_sub1 || !logger_sub2)
|
||||
return 1;
|
||||
|
||||
// Note we cannot use the os_log() line as the breakpoint because, as of
|
||||
// the initial writing of this test, we get multiple breakpoints for that
|
||||
// line, which confuses the pexpect test logic.
|
||||
printf("About to log\n"); // break here
|
||||
os_activity_t parent_activity = os_activity_create("parent-activity",
|
||||
OS_ACTIVITY_CURRENT, OS_ACTIVITY_FLAG_DEFAULT);
|
||||
os_activity_apply(parent_activity, ^{
|
||||
os_log(logger_sub1, "source-log-sub1-cat1");
|
||||
os_activity_t child_activity = os_activity_create("child-activity",
|
||||
OS_ACTIVITY_CURRENT, OS_ACTIVITY_FLAG_DEFAULT);
|
||||
os_activity_apply(child_activity, ^{
|
||||
os_log(logger_sub2, "source-log-sub2-cat2");
|
||||
});
|
||||
});
|
||||
|
||||
// Sleep, as the darwin log reporting doesn't always happen until a bit
|
||||
// later. We need the message to come out before the process terminates.
|
||||
sleep(FINAL_WAIT_SECONDS);
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -1,5 +0,0 @@
|
|||
LEVEL = ../../../../../make
|
||||
|
||||
C_SOURCES := main.c
|
||||
|
||||
include $(LEVEL)/Makefile.rules
|
|
@ -1,133 +0,0 @@
|
|||
"""
|
||||
Test basic DarwinLog functionality provided by the StructuredDataDarwinLog
|
||||
plugin.
|
||||
|
||||
These tests are currently only supported when running against Darwin
|
||||
targets.
|
||||
"""
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
import lldb
|
||||
import os
|
||||
import re
|
||||
|
||||
from lldbsuite.test import decorators
|
||||
from lldbsuite.test import lldbtest
|
||||
from lldbsuite.test import darwin_log
|
||||
|
||||
|
||||
class TestDarwinLogFilterRegexCategory(darwin_log.DarwinLogTestBase):
|
||||
|
||||
mydir = lldbtest.TestBase.compute_mydir(__file__)
|
||||
|
||||
def setUp(self):
|
||||
# Call super's setUp().
|
||||
super(TestDarwinLogFilterRegexCategory, self).setUp()
|
||||
|
||||
# Source filename.
|
||||
self.source = 'main.c'
|
||||
|
||||
# Output filename.
|
||||
self.exe_name = 'a.out'
|
||||
self.d = {'C_SOURCES': self.source, 'EXE': self.exe_name}
|
||||
|
||||
# Locate breakpoint.
|
||||
self.line = lldbtest.line_number(self.source, '// break here')
|
||||
|
||||
def tearDown(self):
|
||||
# Shut down the process if it's still running.
|
||||
if self.child:
|
||||
self.runCmd('process kill')
|
||||
self.expect_prompt()
|
||||
self.runCmd('quit')
|
||||
|
||||
# Let parent clean up
|
||||
super(TestDarwinLogFilterRegexCategory, self).tearDown()
|
||||
|
||||
# ==========================================================================
|
||||
# category filter tests
|
||||
# ==========================================================================
|
||||
|
||||
@decorators.skipUnlessDarwin
|
||||
def test_filter_accept_category_full_match(self):
|
||||
"""Test that fall-through reject, accept regex single category works."""
|
||||
self.do_test(
|
||||
["--no-match-accepts false",
|
||||
"--filter \"accept category regex cat2\""]
|
||||
)
|
||||
|
||||
# We should only see the second log message as we only accept
|
||||
# that category.
|
||||
self.assertIsNotNone(self.child.match)
|
||||
self.assertTrue((len(self.child.match.groups()) > 1) and
|
||||
(self.child.match.group(2) == "cat2"),
|
||||
"first log line should not be present, second log line "
|
||||
"should be")
|
||||
|
||||
@decorators.skipUnlessDarwin
|
||||
def test_filter_accept_category_partial_match(self):
|
||||
"""Test that fall-through reject, accept regex category via partial match works."""
|
||||
self.do_test(
|
||||
["--no-match-accepts false",
|
||||
"--filter \"accept category regex .+2\""]
|
||||
)
|
||||
|
||||
# We should only see the second log message as we only accept
|
||||
# that category.
|
||||
self.assertIsNotNone(self.child.match)
|
||||
self.assertTrue((len(self.child.match.groups()) > 1) and
|
||||
(self.child.match.group(2) == "cat2"),
|
||||
"first log line should not be present, second log line "
|
||||
"should be")
|
||||
|
||||
@decorators.skipUnlessDarwin
|
||||
def test_filter_reject_category_full_match(self):
|
||||
"""Test that fall-through accept, reject regex category works."""
|
||||
self.do_test(
|
||||
["--no-match-accepts true",
|
||||
"--filter \"reject category regex cat1\""]
|
||||
)
|
||||
|
||||
# We should only see the second log message as we rejected the first
|
||||
# via category rejection.
|
||||
self.assertIsNotNone(self.child.match)
|
||||
self.assertTrue((len(self.child.match.groups()) > 1) and
|
||||
(self.child.match.group(2) == "cat2"),
|
||||
"first log line should not be present, second log line "
|
||||
"should be")
|
||||
|
||||
@decorators.skipUnlessDarwin
|
||||
def test_filter_reject_category_partial_match(self):
|
||||
"""Test that fall-through accept, reject regex category by partial match works."""
|
||||
self.do_test(
|
||||
["--no-match-accepts true",
|
||||
"--filter \"reject category regex t1\""]
|
||||
)
|
||||
|
||||
# We should only see the second log message as we rejected the first
|
||||
# via category rejection.
|
||||
self.assertIsNotNone(self.child.match)
|
||||
self.assertTrue((len(self.child.match.groups()) > 1) and
|
||||
(self.child.match.group(2) == "cat2"),
|
||||
"first log line should not be present, second log line "
|
||||
"should be")
|
||||
|
||||
@decorators.skipUnlessDarwin
|
||||
def test_filter_accept_category_second_rule(self):
|
||||
"""Test that fall-through reject, accept regex category on second rule works."""
|
||||
self.do_test(
|
||||
["--no-match-accepts false",
|
||||
"--filter \"accept category regex non-existent\"",
|
||||
"--filter \"accept category regex cat2\""
|
||||
]
|
||||
)
|
||||
|
||||
# We should only see the second message since we reject by default,
|
||||
# the first filter doesn't match any, and the second filter matches
|
||||
# the category of the second log message.
|
||||
self.assertIsNotNone(self.child.match)
|
||||
self.assertTrue((len(self.child.match.groups()) > 1) and
|
||||
(self.child.match.group(2) == "cat2"),
|
||||
"first log line should not be present, second log line "
|
||||
"should be")
|
|
@ -1,43 +0,0 @@
|
|||
//===-- main.c --------------------------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include <os/activity.h>
|
||||
#include <os/log.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "../../../common/darwin_log_common.h"
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
os_log_t logger_sub1 = os_log_create("org.llvm.lldb.test.sub1", "cat1");
|
||||
os_log_t logger_sub2 = os_log_create("org.llvm.lldb.test.sub2", "cat2");
|
||||
if (!logger_sub1 || !logger_sub2)
|
||||
return 1;
|
||||
|
||||
// Note we cannot use the os_log() line as the breakpoint because, as of
|
||||
// the initial writing of this test, we get multiple breakpoints for that
|
||||
// line, which confuses the pexpect test logic.
|
||||
printf("About to log\n"); // break here
|
||||
os_activity_t parent_activity = os_activity_create("parent-activity",
|
||||
OS_ACTIVITY_CURRENT, OS_ACTIVITY_FLAG_DEFAULT);
|
||||
os_activity_apply(parent_activity, ^{
|
||||
os_log(logger_sub1, "source-log-sub1-cat1");
|
||||
os_activity_t child_activity = os_activity_create("child-activity",
|
||||
OS_ACTIVITY_CURRENT, OS_ACTIVITY_FLAG_DEFAULT);
|
||||
os_activity_apply(child_activity, ^{
|
||||
os_log(logger_sub2, "source-log-sub2-cat2");
|
||||
});
|
||||
});
|
||||
|
||||
// Sleep, as the darwin log reporting doesn't always happen until a bit
|
||||
// later. We need the message to come out before the process terminates.
|
||||
sleep(FINAL_WAIT_SECONDS);
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -1,5 +0,0 @@
|
|||
LEVEL = ../../../../../make
|
||||
|
||||
C_SOURCES := main.c
|
||||
|
||||
include $(LEVEL)/Makefile.rules
|
|
@ -1,118 +0,0 @@
|
|||
"""
|
||||
Test basic DarwinLog functionality provided by the StructuredDataDarwinLog
|
||||
plugin.
|
||||
|
||||
These tests are currently only supported when running against Darwin
|
||||
targets.
|
||||
"""
|
||||
|
||||
# System imports
|
||||
from __future__ import print_function
|
||||
|
||||
import re
|
||||
|
||||
# LLDB imports
|
||||
import lldb
|
||||
|
||||
from lldbsuite.test import decorators
|
||||
from lldbsuite.test import lldbtest
|
||||
from lldbsuite.test import darwin_log
|
||||
|
||||
|
||||
class TestDarwinLogFilterRegexMessage(darwin_log.DarwinLogEventBasedTestBase):
|
||||
|
||||
mydir = lldbtest.TestBase.compute_mydir(__file__)
|
||||
|
||||
@decorators.skipUnlessDarwin
|
||||
def test_filter_accept_message_full_match(self):
|
||||
"""Test that fall-through reject, accept regex whole message works."""
|
||||
log_entries = self.do_test(
|
||||
["--no-match-accepts false",
|
||||
# Note below, the four '\' characters are to get us two
|
||||
# backslashes over on the gdb-remote side, which then
|
||||
# becomes one as the cstr interprets it as an escape
|
||||
# sequence. This needs to be rationalized. Initially I
|
||||
# supported std::regex ECMAScript, which has the
|
||||
# [[:digit:]] character classes and such. That was much
|
||||
# more tenable. The backslashes have to travel through
|
||||
# so many layers of escaping. (And note if you take
|
||||
# off the Python raw string marker here, you need to put
|
||||
# in 8 backslashes to go to two on the remote side.)
|
||||
r'--filter "accept message regex log message sub2-cat\\\\d+"'])
|
||||
|
||||
# We should have received at least one log entry.
|
||||
self.assertIsNotNone(log_entries,
|
||||
"Log entry list should not be None.")
|
||||
self.assertEqual(len(log_entries), 1,
|
||||
"Should receive one log entry.")
|
||||
self.assertRegexpMatches(log_entries[0]["message"], r"sub2-cat2",
|
||||
"First os_log call should have been skipped.")
|
||||
|
||||
@decorators.skipUnlessDarwin
|
||||
def test_filter_accept_message_partial_match(self):
|
||||
"""Test that fall-through reject, accept regex message via partial
|
||||
match works."""
|
||||
log_entries = self.do_test(
|
||||
["--no-match-accepts false",
|
||||
"--filter \"accept message regex [^-]+2\""])
|
||||
|
||||
# We should only see the second log message as we only accept
|
||||
# that message contents.
|
||||
self.assertIsNotNone(log_entries,
|
||||
"Log entry list should not be None.")
|
||||
self.assertEqual(len(log_entries), 1,
|
||||
"Should receive one log entry.")
|
||||
self.assertRegexpMatches(log_entries[0]["message"], r"sub2-cat2",
|
||||
"First os_log call should have been skipped.")
|
||||
|
||||
@decorators.skipUnlessDarwin
|
||||
def test_filter_reject_message_full_match(self):
|
||||
"""Test that fall-through accept, reject regex message works."""
|
||||
log_entries = self.do_test(
|
||||
["--no-match-accepts true",
|
||||
"--filter \"reject message regex log message sub1-cat1\""])
|
||||
|
||||
# We should only see the second log message as we rejected the first
|
||||
# via message contents rejection.
|
||||
self.assertIsNotNone(log_entries,
|
||||
"Log entry list should not be None.")
|
||||
self.assertEqual(len(log_entries), 1,
|
||||
"Should receive one log entry.")
|
||||
self.assertRegexpMatches(log_entries[0]["message"], r"sub2-cat2",
|
||||
"First os_log call should have been skipped.")
|
||||
|
||||
@decorators.skipUnlessDarwin
|
||||
def test_filter_reject_message_partial_match(self):
|
||||
"""Test that fall-through accept, reject regex message by partial
|
||||
match works."""
|
||||
log_entries = self.do_test(
|
||||
["--no-match-accepts true",
|
||||
"--filter \"reject message regex t1\""])
|
||||
|
||||
# We should only see the second log message as we rejected the first
|
||||
# via partial message contents rejection.
|
||||
self.assertIsNotNone(log_entries,
|
||||
"Log entry list should not be None.")
|
||||
self.assertEqual(len(log_entries), 1,
|
||||
"Should receive one log entry.")
|
||||
self.assertRegexpMatches(log_entries[0]["message"], r"sub2-cat2",
|
||||
"First os_log call should have been skipped.")
|
||||
|
||||
@decorators.skipUnlessDarwin
|
||||
def test_filter_accept_message_second_rule(self):
|
||||
"""Test that fall-through reject, accept regex message on second rule
|
||||
works."""
|
||||
log_entries = self.do_test(
|
||||
["--no-match-accepts false",
|
||||
"--filter \"accept message regex non-existent\"",
|
||||
"--filter \"accept message regex cat2\""])
|
||||
|
||||
# We should only see the second message since we reject by default,
|
||||
# the first filter doesn't match any, and the second filter matches
|
||||
# the message of the second log message.
|
||||
self.assertIsNotNone(log_entries,
|
||||
"Log entry list should not be None.")
|
||||
self.assertEqual(len(log_entries), 1,
|
||||
"Should receive one log entry.")
|
||||
self.assertRegexpMatches(log_entries[0]["message"], r"sub2-cat2",
|
||||
"First os_log call should have been skipped.")
|
|
@ -1,35 +0,0 @@
|
|||
//===-- main.c --------------------------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include <os/activity.h>
|
||||
#include <os/log.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "../../../common/darwin_log_common.h"
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
os_log_t logger_sub1 = os_log_create("org.llvm.lldb.test.sub1", "cat1");
|
||||
os_log_t logger_sub2 = os_log_create("org.llvm.lldb.test.sub2", "cat2");
|
||||
if (!logger_sub1 || !logger_sub2)
|
||||
return 1;
|
||||
|
||||
// Note we cannot use the os_log() line as the breakpoint because, as of
|
||||
// the initial writing of this test, we get multiple breakpoints for that
|
||||
// line, which confuses the pexpect test logic.
|
||||
printf("About to log\n"); // break here
|
||||
os_log(logger_sub1, "log message sub%d-cat%d", 1, 1);
|
||||
os_log(logger_sub2, "log message sub%d-cat%d", 2, 2);
|
||||
|
||||
// Sleep, as the darwin log reporting doesn't always happen until a bit
|
||||
// later. We need the message to come out before the process terminates.
|
||||
sleep(FINAL_WAIT_SECONDS);
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -1,5 +0,0 @@
|
|||
LEVEL = ../../../../../make
|
||||
|
||||
C_SOURCES := main.c
|
||||
|
||||
include $(LEVEL)/Makefile.rules
|
|
@ -1,150 +0,0 @@
|
|||
"""
|
||||
Test basic DarwinLog functionality provided by the StructuredDataDarwinLog
|
||||
plugin.
|
||||
|
||||
These tests are currently only supported when running against Darwin
|
||||
targets.
|
||||
"""
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
import lldb
|
||||
import os
|
||||
import re
|
||||
|
||||
from lldbsuite.test import decorators
|
||||
from lldbsuite.test import lldbtest
|
||||
from lldbsuite.test import darwin_log
|
||||
|
||||
|
||||
class TestDarwinLogFilterRegexSubsystem(darwin_log.DarwinLogTestBase):
|
||||
|
||||
mydir = lldbtest.TestBase.compute_mydir(__file__)
|
||||
|
||||
def setUp(self):
|
||||
# Call super's setUp().
|
||||
super(TestDarwinLogFilterRegexSubsystem, self).setUp()
|
||||
|
||||
# Source filename.
|
||||
self.source = 'main.c'
|
||||
|
||||
# Output filename.
|
||||
self.exe_name = 'a.out'
|
||||
self.d = {'C_SOURCES': self.source, 'EXE': self.exe_name}
|
||||
|
||||
# Locate breakpoint.
|
||||
self.line = lldbtest.line_number(self.source, '// break here')
|
||||
|
||||
def tearDown(self):
|
||||
# Shut down the process if it's still running.
|
||||
if self.child:
|
||||
self.runCmd('process kill')
|
||||
self.expect_prompt()
|
||||
self.runCmd('quit')
|
||||
|
||||
# Let parent clean up
|
||||
super(TestDarwinLogFilterRegexSubsystem, self).tearDown()
|
||||
|
||||
# ==========================================================================
|
||||
# basic filter tests
|
||||
# ==========================================================================
|
||||
|
||||
@decorators.skipUnlessDarwin
|
||||
def test_fallthrough_reject(self):
|
||||
"""Test that a single fall-through reject regex rule rejects all logging."""
|
||||
self.do_test(
|
||||
["--no-match-accepts false"]
|
||||
)
|
||||
|
||||
# We should not match any log lines.
|
||||
self.assertIsNotNone(self.child.match)
|
||||
self.assertFalse((len(self.child.match.groups()) > 0) and
|
||||
(self.child.match.group(1) in ["sub1", "sub2"]),
|
||||
"log line should not have been received")
|
||||
|
||||
# ==========================================================================
|
||||
# subsystem filter tests
|
||||
# ==========================================================================
|
||||
|
||||
@decorators.skipUnlessDarwin
|
||||
def test_filter_accept_subsystem_full_match(self):
|
||||
"""Test that fall-through reject, accept regex single subsystem works."""
|
||||
self.do_test(
|
||||
["--no-match-accepts false",
|
||||
"--filter \"accept subsystem regex org.llvm.lldb.test.sub2\""]
|
||||
)
|
||||
|
||||
# We should only see the second log message as we only accept
|
||||
# that subsystem.
|
||||
self.assertIsNotNone(self.child.match)
|
||||
self.assertTrue((len(self.child.match.groups()) > 0) and
|
||||
(self.child.match.group(1) == "sub2"),
|
||||
"first log line should not be present, second log line "
|
||||
"should be")
|
||||
|
||||
@decorators.skipUnlessDarwin
|
||||
def test_filter_accept_subsystem_partial_match(self):
|
||||
"""Test that fall-through reject, accept regex subsystem via partial-match works."""
|
||||
self.do_test(
|
||||
["--no-match-accepts false",
|
||||
"--filter \"accept subsystem regex org.llvm.+.sub2\""]
|
||||
)
|
||||
|
||||
# We should only see the second log message as we only accept
|
||||
# that subsystem.
|
||||
self.assertIsNotNone(self.child.match)
|
||||
self.assertTrue((len(self.child.match.groups()) > 0) and
|
||||
(self.child.match.group(1) == "sub2"),
|
||||
"first log line should not be present, second log line "
|
||||
"should be")
|
||||
|
||||
@decorators.skipUnlessDarwin
|
||||
def test_filter_reject_subsystem_full_match(self):
|
||||
"""Test that fall-through accept, reject regex subsystem works."""
|
||||
self.do_test(
|
||||
["--no-match-accepts true",
|
||||
"--filter \"reject subsystem regex org.llvm.lldb.test.sub1\""]
|
||||
)
|
||||
|
||||
# We should only see the second log message as we rejected the first
|
||||
# via subsystem rejection.
|
||||
self.assertIsNotNone(self.child.match)
|
||||
self.assertTrue((len(self.child.match.groups()) > 0) and
|
||||
(self.child.match.group(1) == "sub2"),
|
||||
"first log line should not be present, second log line "
|
||||
"should be")
|
||||
|
||||
@decorators.skipUnlessDarwin
|
||||
def test_filter_reject_subsystem_partial_match(self):
|
||||
"""Test that fall-through accept, reject regex subsystem by partial match works."""
|
||||
self.do_test(
|
||||
["--no-match-accepts true",
|
||||
"--filter \"reject subsystem regex org.*sub1\""]
|
||||
)
|
||||
|
||||
# We should only see the second log message as we rejected the first
|
||||
# via subsystem rejection.
|
||||
self.assertIsNotNone(self.child.match)
|
||||
self.assertTrue((len(self.child.match.groups()) > 0) and
|
||||
(self.child.match.group(1) == "sub2"),
|
||||
"first log line should not be present, second log line "
|
||||
"should be")
|
||||
|
||||
@decorators.skipUnlessDarwin
|
||||
def test_filter_accept_subsystem_second_rule(self):
|
||||
"""Test that fall-through reject, accept regex subsystem on second rule works."""
|
||||
self.do_test(
|
||||
["--no-match-accepts false",
|
||||
"--filter \"accept subsystem regex non-existent\"",
|
||||
"--filter \"accept subsystem regex org.llvm.lldb.test.sub2\""
|
||||
]
|
||||
)
|
||||
|
||||
# We should only see the second message since we reject by default,
|
||||
# the first filter doesn't match any, and the second filter matches
|
||||
# the subsystem of the second log message.
|
||||
self.assertIsNotNone(self.child.match)
|
||||
self.assertTrue((len(self.child.match.groups()) > 0) and
|
||||
(self.child.match.group(1) == "sub2"),
|
||||
"first log line should not be present, second log line "
|
||||
"should be")
|
|
@ -1,43 +0,0 @@
|
|||
//===-- main.c --------------------------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include <os/activity.h>
|
||||
#include <os/log.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "../../../common/darwin_log_common.h"
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
os_log_t logger_sub1 = os_log_create("org.llvm.lldb.test.sub1", "cat1");
|
||||
os_log_t logger_sub2 = os_log_create("org.llvm.lldb.test.sub2", "cat2");
|
||||
if (!logger_sub1 || !logger_sub2)
|
||||
return 1;
|
||||
|
||||
// Note we cannot use the os_log() line as the breakpoint because, as of
|
||||
// the initial writing of this test, we get multiple breakpoints for that
|
||||
// line, which confuses the pexpect test logic.
|
||||
printf("About to log\n"); // break here
|
||||
os_activity_t parent_activity = os_activity_create("parent-activity",
|
||||
OS_ACTIVITY_CURRENT, OS_ACTIVITY_FLAG_DEFAULT);
|
||||
os_activity_apply(parent_activity, ^{
|
||||
os_log(logger_sub1, "source-log-sub1-cat1");
|
||||
os_activity_t child_activity = os_activity_create("child-activity",
|
||||
OS_ACTIVITY_CURRENT, OS_ACTIVITY_FLAG_DEFAULT);
|
||||
os_activity_apply(child_activity, ^{
|
||||
os_log(logger_sub2, "source-log-sub2-cat2");
|
||||
});
|
||||
});
|
||||
|
||||
// Sleep, as the darwin log reporting doesn't always happen until a bit
|
||||
// later. We need the message to come out before the process terminates.
|
||||
sleep(FINAL_WAIT_SECONDS);
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -1,5 +0,0 @@
|
|||
LEVEL = ../../../make
|
||||
|
||||
C_SOURCES := main.c
|
||||
|
||||
include $(LEVEL)/Makefile.rules
|
|
@ -1,189 +0,0 @@
|
|||
"""
|
||||
Test DarwinLog log message formatting options provided by the
|
||||
StructuredDataDarwinLog plugin.
|
||||
|
||||
These tests are currently only supported when running against Darwin
|
||||
targets.
|
||||
"""
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
import lldb
|
||||
import re
|
||||
|
||||
from lldbsuite.test import decorators
|
||||
from lldbsuite.test import lldbtest
|
||||
from lldbsuite.test import darwin_log
|
||||
|
||||
|
||||
class TestDarwinLogMessageFormat(darwin_log.DarwinLogTestBase):
|
||||
|
||||
mydir = lldbtest.TestBase.compute_mydir(__file__)
|
||||
|
||||
def setUp(self):
|
||||
# Call super's setUp().
|
||||
super(TestDarwinLogMessageFormat, self).setUp()
|
||||
|
||||
# Source filename.
|
||||
self.source = 'main.c'
|
||||
|
||||
# Output filename.
|
||||
self.exe_name = 'a.out'
|
||||
self.d = {'C_SOURCES': self.source, 'EXE': self.exe_name}
|
||||
|
||||
# Locate breakpoint.
|
||||
self.line = lldbtest.line_number(self.source, '// break here')
|
||||
|
||||
def tearDown(self):
|
||||
# Shut down the process if it's still running.
|
||||
if self.child:
|
||||
self.runCmd('process kill')
|
||||
self.expect_prompt()
|
||||
self.runCmd('quit')
|
||||
|
||||
# Let parent clean up
|
||||
super(TestDarwinLogMessageFormat, self).tearDown()
|
||||
|
||||
# ==========================================================================
|
||||
# Test settings around log message formatting
|
||||
# ==========================================================================
|
||||
|
||||
REGEXES = [
|
||||
re.compile(r"\[([^]]+)\] This is the log message."), # Match log
|
||||
# with header.
|
||||
re.compile(r"This is the log message."), # Match no-header content.
|
||||
re.compile(r"exited with status") # Fallback if no log emitted.
|
||||
]
|
||||
|
||||
@decorators.skipUnlessDarwin
|
||||
def test_display_without_header_works(self):
|
||||
"""Test that turning off log message headers works as advertised."""
|
||||
self.do_test([], expect_regexes=self.REGEXES)
|
||||
|
||||
# We should not match the first pattern as we shouldn't have header
|
||||
# content.
|
||||
self.assertIsNotNone(self.child.match)
|
||||
self.assertFalse((len(self.child.match.groups()) > 0) and
|
||||
(self.child.match.group(1) != ""),
|
||||
"we should not have seen a header")
|
||||
|
||||
|
||||
@decorators.skipUnlessDarwin
|
||||
def test_display_with_header_works(self):
|
||||
"""Test that displaying any header works."""
|
||||
self.do_test(
|
||||
["--timestamp-relative", "--subsystem", "--category",
|
||||
"--activity-chain"],
|
||||
expect_regexes=self.REGEXES,
|
||||
settings_commands=[
|
||||
"display-header true"
|
||||
])
|
||||
|
||||
# We should match the first pattern as we should have header
|
||||
# content.
|
||||
self.assertIsNotNone(self.child.match)
|
||||
self.assertTrue((len(self.child.match.groups()) > 0) and
|
||||
(self.child.match.group(1) != ""),
|
||||
"we should have printed a header")
|
||||
|
||||
def assert_header_contains_timestamp(self, header):
|
||||
fields = header.split(',')
|
||||
self.assertGreater(len(fields), 0,
|
||||
"there should have been header content present")
|
||||
self.assertRegexpMatches(fields[0],
|
||||
r"^\d+:\d{2}:\d{2}.\d{9}$",
|
||||
"time field should match expected format")
|
||||
|
||||
@decorators.skipUnlessDarwin
|
||||
def test_header_timefield_only_works(self):
|
||||
"""Test that displaying a header with only the timestamp works."""
|
||||
self.do_test(["--timestamp-relative"], expect_regexes=self.REGEXES)
|
||||
|
||||
# We should match the first pattern as we should have header
|
||||
# content.
|
||||
self.assertIsNotNone(self.child.match)
|
||||
self.assertTrue((len(self.child.match.groups()) > 0) and
|
||||
(self.child.match.group(1) != ""),
|
||||
"we should have printed a header")
|
||||
header = self.child.match.group(1)
|
||||
self.assertEqual(len(header.split(',')), 1,
|
||||
"there should only be one header field")
|
||||
self.assert_header_contains_timestamp(header)
|
||||
|
||||
@decorators.skipUnlessDarwin
|
||||
def test_header_subsystem_only_works(self):
|
||||
"""Test that displaying a header with only the subsystem works."""
|
||||
self.do_test(["--subsystem"], expect_regexes=self.REGEXES)
|
||||
|
||||
# We should match the first pattern as we should have header
|
||||
# content.
|
||||
self.assertIsNotNone(self.child.match)
|
||||
self.assertTrue((len(self.child.match.groups()) > 0) and
|
||||
(self.child.match.group(1) != ""),
|
||||
"we should have printed a header")
|
||||
header = self.child.match.group(1)
|
||||
self.assertEqual(len(header.split(',')), 1,
|
||||
"there should only be one header field")
|
||||
self.assertEquals(header,
|
||||
"subsystem=org.llvm.lldb.test.sub1")
|
||||
|
||||
@decorators.skipUnlessDarwin
|
||||
def test_header_category_only_works(self):
|
||||
"""Test that displaying a header with only the category works."""
|
||||
self.do_test(["--category"], expect_regexes=self.REGEXES)
|
||||
|
||||
# We should match the first pattern as we should have header
|
||||
# content.
|
||||
self.assertIsNotNone(self.child.match)
|
||||
self.assertTrue((len(self.child.match.groups()) > 0) and
|
||||
(self.child.match.group(1) != ""),
|
||||
"we should have printed a header")
|
||||
header = self.child.match.group(1)
|
||||
self.assertEqual(len(header.split(',')), 1,
|
||||
"there should only be one header field")
|
||||
self.assertEquals(header,
|
||||
"category=cat1")
|
||||
|
||||
@decorators.skipUnlessDarwin
|
||||
def test_header_activity_chain_only_works(self):
|
||||
"""Test that displaying a header with only the activity chain works."""
|
||||
self.do_test(["--activity-chain"], expect_regexes=self.REGEXES)
|
||||
|
||||
# We should match the first pattern as we should have header
|
||||
# content.
|
||||
self.assertIsNotNone(self.child.match)
|
||||
self.assertTrue((len(self.child.match.groups()) > 0) and
|
||||
(self.child.match.group(1) != ""),
|
||||
"we should have printed a header")
|
||||
header = self.child.match.group(1)
|
||||
self.assertEqual(len(header.split(',')), 1,
|
||||
"there should only be one header field")
|
||||
self.assertEquals(header,
|
||||
"activity-chain=parent-activity:child-activity")
|
||||
|
||||
# @decorators.skipUnlessDarwin
|
||||
# def test_header_activity_no_chain_only_works(self):
|
||||
# """Test that displaying a header with only the activity works."""
|
||||
# self.do_test(
|
||||
# [],
|
||||
# expect_regexes=self.REGEXES,
|
||||
# settings_commands=[
|
||||
# "display-header true",
|
||||
# "format-include-timestamp false",
|
||||
# "format-include-activity true",
|
||||
# "format-include-category false",
|
||||
# "format-include-subsystem false",
|
||||
# "display-activity-chain false"
|
||||
# ])
|
||||
|
||||
# # We should match the first pattern as we should have header
|
||||
# # content.
|
||||
# self.assertIsNotNone(self.child.match)
|
||||
# self.assertTrue((len(self.child.match.groups()) > 0) and
|
||||
# (self.child.match.group(1) != ""),
|
||||
# "we should have printed a header")
|
||||
# header = self.child.match.group(1)
|
||||
# self.assertEqual(len(header.split(',')), 1,
|
||||
# "there should only be one header field")
|
||||
# self.assertEquals(header,
|
||||
# "activity=child-activity")
|
|
@ -1,41 +0,0 @@
|
|||
//===-- main.c --------------------------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include <os/activity.h>
|
||||
#include <os/log.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "../common/darwin_log_common.h"
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
os_log_t logger_sub1 = os_log_create("org.llvm.lldb.test.sub1", "cat1");
|
||||
if (!logger_sub1)
|
||||
return 1;
|
||||
|
||||
// Note we cannot use the os_log() line as the breakpoint because, as of
|
||||
// the initial writing of this test, we get multiple breakpoints for that
|
||||
// line, which confuses the pexpect test logic.
|
||||
printf("About to log\n"); // break here
|
||||
os_activity_t parent_activity = os_activity_create("parent-activity",
|
||||
OS_ACTIVITY_CURRENT, OS_ACTIVITY_FLAG_DEFAULT);
|
||||
os_activity_apply(parent_activity, ^{
|
||||
os_activity_t child_activity = os_activity_create("child-activity",
|
||||
OS_ACTIVITY_CURRENT, OS_ACTIVITY_FLAG_DEFAULT);
|
||||
os_activity_apply(child_activity, ^{
|
||||
os_log(logger_sub1, "This is the log message.");
|
||||
});
|
||||
});
|
||||
|
||||
// Sleep, as the darwin log reporting doesn't always happen until a bit
|
||||
// later. We need the message to come out before the process terminates.
|
||||
sleep(FINAL_WAIT_SECONDS);
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -1,5 +0,0 @@
|
|||
LEVEL = ../../../../make
|
||||
|
||||
C_SOURCES := main.c
|
||||
|
||||
include $(LEVEL)/Makefile.rules
|
|
@ -1,79 +0,0 @@
|
|||
"""
|
||||
Test DarwinLog "source include debug-level" functionality provided by the
|
||||
StructuredDataDarwinLog plugin.
|
||||
|
||||
These tests are currently only supported when running against Darwin
|
||||
targets.
|
||||
"""
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
import lldb
|
||||
import os
|
||||
import re
|
||||
|
||||
from lldbsuite.test import decorators
|
||||
from lldbsuite.test import lldbtest
|
||||
from lldbsuite.test import darwin_log
|
||||
|
||||
|
||||
class TestDarwinLogSourceDebug(darwin_log.DarwinLogTestBase):
|
||||
|
||||
mydir = lldbtest.TestBase.compute_mydir(__file__)
|
||||
|
||||
def setUp(self):
|
||||
# Call super's setUp().
|
||||
super(TestDarwinLogSourceDebug, self).setUp()
|
||||
|
||||
# Source filename.
|
||||
self.source = 'main.c'
|
||||
|
||||
# Output filename.
|
||||
self.exe_name = 'a.out'
|
||||
self.d = {'C_SOURCES': self.source, 'EXE': self.exe_name}
|
||||
|
||||
# Locate breakpoint.
|
||||
self.line = lldbtest.line_number(self.source, '// break here')
|
||||
|
||||
# Indicate we want strict-sources behavior.
|
||||
self.strict_sources = True
|
||||
|
||||
def tearDown(self):
|
||||
# Shut down the process if it's still running.
|
||||
if self.child:
|
||||
self.runCmd('process kill')
|
||||
self.expect_prompt()
|
||||
self.runCmd('quit')
|
||||
|
||||
# Let parent clean up
|
||||
super(TestDarwinLogSourceDebug, self).tearDown()
|
||||
|
||||
# ==========================================================================
|
||||
# source include/exclude debug filter tests
|
||||
# ==========================================================================
|
||||
|
||||
@decorators.skipUnlessDarwin
|
||||
def test_source_default_exclude_debug(self):
|
||||
"""Test that default excluding of debug-level log messages works."""
|
||||
self.do_test([])
|
||||
|
||||
# We should only see the second log message as the first is a
|
||||
# debug-level message and we're not including debug-level messages.
|
||||
self.assertIsNotNone(self.child.match)
|
||||
self.assertTrue((len(self.child.match.groups()) > 1) and
|
||||
(self.child.match.group(2) == "cat2"),
|
||||
"first log line should not be present, second log line "
|
||||
"should be")
|
||||
|
||||
@decorators.skipUnlessDarwin
|
||||
def test_source_explicitly_include_debug(self):
|
||||
"""Test that explicitly including debug-level log messages works."""
|
||||
self.do_test(["--debug"])
|
||||
|
||||
# We should only see the second log message as the first is a
|
||||
# debug-level message and we're not including debug-level messages.
|
||||
self.assertIsNotNone(self.child.match)
|
||||
self.assertTrue((len(self.child.match.groups()) > 1) and
|
||||
(self.child.match.group(2) == "cat1"),
|
||||
"first log line should be present since we're "
|
||||
"including debug-level log messages")
|
|
@ -1,34 +0,0 @@
|
|||
//===-- main.c --------------------------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include <os/log.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "../../common/darwin_log_common.h"
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
os_log_t logger_sub1 = os_log_create("org.llvm.lldb.test.sub1", "cat1");
|
||||
os_log_t logger_sub2 = os_log_create("org.llvm.lldb.test.sub2", "cat2");
|
||||
if (!logger_sub1 || !logger_sub2)
|
||||
return 1;
|
||||
|
||||
// Note we cannot use the os_log() line as the breakpoint because, as of
|
||||
// the initial writing of this test, we get multiple breakpoints for that
|
||||
// line, which confuses the pexpect test logic.
|
||||
printf("About to log\n"); // break here
|
||||
os_log_debug(logger_sub1, "source-log-sub1-cat1");
|
||||
os_log(logger_sub2, "source-log-sub2-cat2");
|
||||
|
||||
// Sleep, as the darwin log reporting doesn't always happen until a bit
|
||||
// later. We need the message to come out before the process terminates.
|
||||
sleep(FINAL_WAIT_SECONDS);
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -1,5 +0,0 @@
|
|||
LEVEL = ../../../../make
|
||||
|
||||
C_SOURCES := main.c
|
||||
|
||||
include $(LEVEL)/Makefile.rules
|
|
@ -1,82 +0,0 @@
|
|||
"""
|
||||
Test DarwinLog "source include info-level" functionality provided by the
|
||||
StructuredDataDarwinLog plugin.
|
||||
|
||||
These tests are currently only supported when running against Darwin
|
||||
targets.
|
||||
"""
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
import lldb
|
||||
import os
|
||||
import re
|
||||
|
||||
from lldbsuite.test import decorators
|
||||
from lldbsuite.test import lldbtest
|
||||
from lldbsuite.test import darwin_log
|
||||
|
||||
|
||||
class TestDarwinLogSourceInfo(darwin_log.DarwinLogTestBase):
|
||||
|
||||
mydir = lldbtest.TestBase.compute_mydir(__file__)
|
||||
|
||||
def setUp(self):
|
||||
# Call super's setUp().
|
||||
super(TestDarwinLogSourceInfo, self).setUp()
|
||||
|
||||
# Source filename.
|
||||
self.source = 'main.c'
|
||||
|
||||
# Output filename.
|
||||
self.exe_name = 'a.out'
|
||||
self.d = {'C_SOURCES': self.source, 'EXE': self.exe_name}
|
||||
|
||||
# Locate breakpoint.
|
||||
self.line = lldbtest.line_number(self.source, '// break here')
|
||||
|
||||
# Indicate we want strict-sources behavior.
|
||||
self.strict_sources = True
|
||||
|
||||
def tearDown(self):
|
||||
# Shut down the process if it's still running.
|
||||
if self.child:
|
||||
self.runCmd('process kill')
|
||||
self.expect_prompt()
|
||||
self.runCmd('quit')
|
||||
|
||||
# Let parent clean up
|
||||
super(TestDarwinLogSourceInfo, self).tearDown()
|
||||
|
||||
# ==========================================================================
|
||||
# source include/exclude debug filter tests
|
||||
# ==========================================================================
|
||||
|
||||
@decorators.skipUnlessDarwin
|
||||
@decorators.expectedFailureAll(bugnumber="rdar://27316264")
|
||||
def test_source_exclude_info_level(self):
|
||||
"""Test that default excluding of info-level log messages works."""
|
||||
self.do_test([])
|
||||
|
||||
# We should only see the second log message as the first is an
|
||||
# info-level message and we're not including debug-level messages.
|
||||
self.assertIsNotNone(self.child.match)
|
||||
self.assertTrue((len(self.child.match.groups()) > 1) and
|
||||
(self.child.match.group(2) == "cat2"),
|
||||
"first log line should not be present, second log line "
|
||||
"should be")
|
||||
|
||||
@decorators.skipUnlessDarwin
|
||||
def test_source_include_info_level(self):
|
||||
"""Test that explicitly including info-level log messages works."""
|
||||
self.do_test(
|
||||
["--info"]
|
||||
)
|
||||
|
||||
# We should only see the second log message as the first is a
|
||||
# debug-level message and we're not including debug-level messages.
|
||||
self.assertIsNotNone(self.child.match)
|
||||
self.assertTrue((len(self.child.match.groups()) > 1) and
|
||||
(self.child.match.group(2) == "cat1"),
|
||||
"first log line should be present since we're "
|
||||
"including info-level log messages")
|
|
@ -1,34 +0,0 @@
|
|||
//===-- main.c --------------------------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include <os/log.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "../../common/darwin_log_common.h"
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
os_log_t logger_sub1 = os_log_create("org.llvm.lldb.test.sub1", "cat1");
|
||||
os_log_t logger_sub2 = os_log_create("org.llvm.lldb.test.sub2", "cat2");
|
||||
if (!logger_sub1 || !logger_sub2)
|
||||
return 1;
|
||||
|
||||
// Note we cannot use the os_log() line as the breakpoint because, as of
|
||||
// the initial writing of this test, we get multiple breakpoints for that
|
||||
// line, which confuses the pexpect test logic.
|
||||
printf("About to log\n"); // break here
|
||||
os_log_info(logger_sub1, "source-log-sub1-cat1");
|
||||
os_log(logger_sub2, "source-log-sub2-cat2");
|
||||
|
||||
// Sleep, as the darwin log reporting doesn't always happen until a bit
|
||||
// later. We need the message to come out before the process terminates.
|
||||
sleep(FINAL_WAIT_SECONDS);
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -44,8 +44,7 @@ public:
|
|||
eBroadcastBitInterrupt = (1 << 1),
|
||||
eBroadcastBitSTDOUT = (1 << 2),
|
||||
eBroadcastBitSTDERR = (1 << 3),
|
||||
eBroadcastBitProfileData = (1 << 4),
|
||||
eBroadcastBitStructuredData = (1 << 5)
|
||||
eBroadcastBitProfileData = (1 << 4)
|
||||
};
|
||||
|
||||
SBProcess ();
|
||||
|
@ -352,15 +351,9 @@ public:
|
|||
static bool
|
||||
GetInterruptedFromEvent (const lldb::SBEvent &event);
|
||||
|
||||
static lldb::SBStructuredData
|
||||
GetStructuredDataFromEvent (const lldb::SBEvent &event);
|
||||
|
||||
static bool
|
||||
EventIsProcessEvent (const lldb::SBEvent &event);
|
||||
|
||||
static bool
|
||||
EventIsStructuredDataEvent (const lldb::SBEvent &event);
|
||||
|
||||
lldb::SBBroadcaster
|
||||
GetBroadcaster () const;
|
||||
|
||||
|
|
|
@ -1,42 +0,0 @@
|
|||
//===-- SWIG Interface for SBStructuredData ---------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
namespace lldb {
|
||||
|
||||
%feature("docstring",
|
||||
"A class representing a StructuredData event.
|
||||
|
||||
This class wraps the event type generated by StructuredData
|
||||
features."
|
||||
) SBStructuredData;
|
||||
class SBStructuredData
|
||||
{
|
||||
public:
|
||||
|
||||
SBStructuredData();
|
||||
|
||||
SBStructuredData(const lldb::SBStructuredData &rhs);
|
||||
|
||||
SBStructuredData(const lldb::EventSP &event_sp);
|
||||
|
||||
~SBStructuredData();
|
||||
|
||||
bool
|
||||
IsValid() const;
|
||||
|
||||
void
|
||||
Clear();
|
||||
|
||||
lldb::SBError
|
||||
GetAsJSON(lldb::SBStream &stream) const;
|
||||
|
||||
lldb::SBError
|
||||
GetDescription(lldb::SBStream &stream) const;
|
||||
};
|
||||
}
|
|
@ -178,7 +178,7 @@ public:
|
|||
/// Some launch options specified by logical OR'ing
|
||||
/// lldb::LaunchFlags enumeration values together.
|
||||
///
|
||||
/// @param[in] stop_at_entry
|
||||
/// @param[in] stop_at_endtry
|
||||
/// If false do not stop the inferior at the entry point.
|
||||
///
|
||||
/// @param[out]
|
||||
|
|
|
@ -95,7 +95,6 @@ import six
|
|||
#include "lldb/API/SBSourceManager.h"
|
||||
#include "lldb/API/SBStream.h"
|
||||
#include "lldb/API/SBStringList.h"
|
||||
#include "lldb/API/SBStructuredData.h"
|
||||
#include "lldb/API/SBSymbol.h"
|
||||
#include "lldb/API/SBSymbolContext.h"
|
||||
#include "lldb/API/SBSymbolContextList.h"
|
||||
|
@ -178,7 +177,6 @@ import six
|
|||
%include "./interface/SBSourceManager.i"
|
||||
%include "./interface/SBStream.i"
|
||||
%include "./interface/SBStringList.i"
|
||||
%include "./interface/SBStructuredData.i"
|
||||
%include "./interface/SBSymbol.i"
|
||||
%include "./interface/SBSymbolContext.i"
|
||||
%include "./interface/SBSymbolContextList.i"
|
||||
|
|
|
@ -47,7 +47,6 @@ add_lldb_library(liblldb SHARED
|
|||
SBSourceManager.cpp
|
||||
SBStream.cpp
|
||||
SBStringList.cpp
|
||||
SBStructuredData.cpp
|
||||
SBSymbol.cpp
|
||||
SBSymbolContext.cpp
|
||||
SBSymbolContextList.cpp
|
||||
|
|
|
@ -491,7 +491,7 @@ SBDebugger::HandleProcessEvent (const SBProcess &process, const SBEvent &event,
|
|||
if (err != nullptr)
|
||||
::fwrite (stdio_buffer, 1, len, err);
|
||||
}
|
||||
|
||||
|
||||
if (event_type & Process::eBroadcastBitStateChanged)
|
||||
{
|
||||
StateType event_state = SBProcess::GetStateFromEvent (event);
|
||||
|
|
|
@ -39,7 +39,6 @@
|
|||
#include "lldb/API/SBFileSpec.h"
|
||||
#include "lldb/API/SBMemoryRegionInfo.h"
|
||||
#include "lldb/API/SBMemoryRegionInfoList.h"
|
||||
#include "lldb/API/SBStructuredData.h"
|
||||
#include "lldb/API/SBThread.h"
|
||||
#include "lldb/API/SBThreadCollection.h"
|
||||
#include "lldb/API/SBStream.h"
|
||||
|
@ -1030,16 +1029,8 @@ SBProcess::GetRestartedReasonAtIndexFromEvent (const lldb::SBEvent &event, size_
|
|||
SBProcess
|
||||
SBProcess::GetProcessFromEvent (const SBEvent &event)
|
||||
{
|
||||
ProcessSP process_sp =
|
||||
Process::ProcessEventData::GetProcessFromEvent (event.get());
|
||||
if (!process_sp)
|
||||
{
|
||||
// StructuredData events also know the process they come from.
|
||||
// Try that.
|
||||
process_sp = EventDataStructuredData::GetProcessFromEvent(event.get());
|
||||
}
|
||||
|
||||
return SBProcess(process_sp);
|
||||
SBProcess process(Process::ProcessEventData::GetProcessFromEvent (event.get()));
|
||||
return process;
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -1048,26 +1039,10 @@ SBProcess::GetInterruptedFromEvent (const SBEvent &event)
|
|||
return Process::ProcessEventData::GetInterruptedFromEvent(event.get());
|
||||
}
|
||||
|
||||
lldb::SBStructuredData
|
||||
SBProcess::GetStructuredDataFromEvent (const lldb::SBEvent &event)
|
||||
{
|
||||
return SBStructuredData(event.GetSP());
|
||||
}
|
||||
|
||||
bool
|
||||
SBProcess::EventIsProcessEvent (const SBEvent &event)
|
||||
{
|
||||
return (event.GetBroadcasterClass() == SBProcess::GetBroadcasterClass()) &&
|
||||
!EventIsStructuredDataEvent (event);
|
||||
}
|
||||
|
||||
bool
|
||||
SBProcess::EventIsStructuredDataEvent (const lldb::SBEvent &event)
|
||||
{
|
||||
EventSP event_sp = event.GetSP();
|
||||
EventData *event_data = event_sp ? event_sp->GetData() : nullptr;
|
||||
return event_data &&
|
||||
(event_data->GetFlavor() == EventDataStructuredData::GetFlavorString());
|
||||
return event.GetBroadcasterClass() == SBProcess::GetBroadcasterClass();
|
||||
}
|
||||
|
||||
SBBroadcaster
|
||||
|
|
|
@ -1,165 +0,0 @@
|
|||
//===-- SBStructuredData.cpp ------------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "lldb/API/SBStructuredData.h"
|
||||
|
||||
#include "lldb/API/SBStream.h"
|
||||
#include "lldb/Core/Error.h"
|
||||
#include "lldb/Core/Event.h"
|
||||
#include "lldb/Core/Stream.h"
|
||||
#include "lldb/Core/StructuredData.h"
|
||||
#include "lldb/Target/StructuredDataPlugin.h"
|
||||
|
||||
using namespace lldb;
|
||||
using namespace lldb_private;
|
||||
|
||||
#pragma mark --
|
||||
#pragma mark Impl
|
||||
|
||||
class SBStructuredData::Impl
|
||||
{
|
||||
public:
|
||||
|
||||
Impl() :
|
||||
m_plugin_wp(),
|
||||
m_data_sp()
|
||||
{
|
||||
}
|
||||
|
||||
Impl(const Impl &rhs) = default;
|
||||
|
||||
Impl(const EventSP &event_sp) :
|
||||
m_plugin_wp(EventDataStructuredData::GetPluginFromEvent(event_sp.get())),
|
||||
m_data_sp(EventDataStructuredData::GetObjectFromEvent(event_sp.get()))
|
||||
{
|
||||
}
|
||||
|
||||
~Impl() = default;
|
||||
|
||||
Impl&
|
||||
operator =(const Impl &rhs) = default;
|
||||
|
||||
bool
|
||||
IsValid() const
|
||||
{
|
||||
return m_data_sp.get() != nullptr;
|
||||
}
|
||||
|
||||
void
|
||||
Clear()
|
||||
{
|
||||
m_plugin_wp.reset();
|
||||
m_data_sp.reset();
|
||||
}
|
||||
|
||||
SBError
|
||||
GetAsJSON(lldb::SBStream &stream) const
|
||||
{
|
||||
SBError sb_error;
|
||||
|
||||
if (!m_data_sp)
|
||||
{
|
||||
sb_error.SetErrorString("No structured data.");
|
||||
return sb_error;
|
||||
}
|
||||
|
||||
m_data_sp->Dump(stream.ref());
|
||||
return sb_error;
|
||||
}
|
||||
|
||||
lldb::SBError
|
||||
GetDescription(lldb::SBStream &stream) const
|
||||
{
|
||||
SBError sb_error;
|
||||
|
||||
if (!m_data_sp)
|
||||
{
|
||||
sb_error.SetErrorString("Cannot pretty print structured data: "
|
||||
"no data to print.");
|
||||
return sb_error;
|
||||
}
|
||||
|
||||
// Grab the plugin.
|
||||
auto plugin_sp = StructuredDataPluginSP(m_plugin_wp);
|
||||
if (!plugin_sp)
|
||||
{
|
||||
sb_error.SetErrorString("Cannot pretty print structured data: "
|
||||
"plugin doesn't exist.");
|
||||
return sb_error;
|
||||
}
|
||||
|
||||
// Get the data's description.
|
||||
auto error = plugin_sp->GetDescription(m_data_sp, stream.ref());
|
||||
if (!error.Success())
|
||||
sb_error.SetError(error);
|
||||
|
||||
return sb_error;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
StructuredDataPluginWP m_plugin_wp;
|
||||
StructuredData::ObjectSP m_data_sp;
|
||||
|
||||
};
|
||||
|
||||
#pragma mark --
|
||||
#pragma mark SBStructuredData
|
||||
|
||||
|
||||
SBStructuredData::SBStructuredData() :
|
||||
m_impl_up(new Impl())
|
||||
{
|
||||
}
|
||||
|
||||
SBStructuredData::SBStructuredData(const lldb::SBStructuredData &rhs) :
|
||||
m_impl_up(new Impl(*rhs.m_impl_up.get()))
|
||||
{
|
||||
}
|
||||
|
||||
SBStructuredData::SBStructuredData(const lldb::EventSP &event_sp) :
|
||||
m_impl_up(new Impl(event_sp))
|
||||
{
|
||||
}
|
||||
|
||||
SBStructuredData::~SBStructuredData()
|
||||
{
|
||||
}
|
||||
|
||||
SBStructuredData &
|
||||
SBStructuredData::operator =(const lldb::SBStructuredData &rhs)
|
||||
{
|
||||
*m_impl_up = *rhs.m_impl_up;
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool
|
||||
SBStructuredData::IsValid() const
|
||||
{
|
||||
return m_impl_up->IsValid();
|
||||
}
|
||||
|
||||
void
|
||||
SBStructuredData::Clear()
|
||||
{
|
||||
m_impl_up->Clear();
|
||||
}
|
||||
|
||||
SBError
|
||||
SBStructuredData::GetAsJSON(lldb::SBStream &stream) const
|
||||
{
|
||||
return m_impl_up->GetAsJSON(stream);
|
||||
}
|
||||
|
||||
lldb::SBError
|
||||
SBStructuredData::GetDescription(lldb::SBStream &stream) const
|
||||
{
|
||||
return m_impl_up->GetDescription(stream);
|
||||
}
|
||||
|
|
@ -100,7 +100,6 @@
|
|||
#include "Plugins/Process/mach-core/ProcessMachCore.h"
|
||||
#include "Plugins/SymbolVendor/MacOSX/SymbolVendorMacOSX.h"
|
||||
#endif
|
||||
#include "Plugins/StructuredData/DarwinLog/StructuredDataDarwinLog.h"
|
||||
|
||||
#if defined(__FreeBSD__)
|
||||
#include "Plugins/Process/FreeBSD/ProcessFreeBSD.h"
|
||||
|
@ -382,11 +381,6 @@ SystemInitializerFull::Initialize()
|
|||
PlatformRemoteAppleWatch::Initialize();
|
||||
DynamicLoaderDarwinKernel::Initialize();
|
||||
#endif
|
||||
|
||||
// This plugin is valid on any host that talks to a Darwin remote.
|
||||
// It shouldn't be limited to __APPLE__.
|
||||
StructuredDataDarwinLog::Initialize();
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// Platform agnostic plugins
|
||||
//----------------------------------------------------------------------
|
||||
|
@ -519,8 +513,6 @@ SystemInitializerFull::Terminate()
|
|||
|
||||
platform_gdb_server::PlatformRemoteGDBServer::Terminate();
|
||||
process_gdb_remote::ProcessGDBRemote::Terminate();
|
||||
StructuredDataDarwinLog::Terminate();
|
||||
|
||||
DynamicLoaderMacOSXDYLD::Terminate();
|
||||
DynamicLoaderMacOS::Terminate();
|
||||
DynamicLoaderPOSIXDYLD::Terminate();
|
||||
|
|
|
@ -56,7 +56,6 @@
|
|||
#include "lldb/Target/RegisterContext.h"
|
||||
#include "lldb/Target/SectionLoadList.h"
|
||||
#include "lldb/Target/StopInfo.h"
|
||||
#include "lldb/Target/StructuredDataPlugin.h"
|
||||
#include "lldb/Target/Target.h"
|
||||
#include "lldb/Target/Thread.h"
|
||||
#include "lldb/Utility/AnsiTerminal.h"
|
||||
|
@ -1477,15 +1476,14 @@ Debugger::GetProcessSTDERR (Process *process, Stream *stream)
|
|||
return total_bytes;
|
||||
}
|
||||
|
||||
|
||||
// This function handles events that were broadcast by the process.
|
||||
void
|
||||
Debugger::HandleProcessEvent (const EventSP &event_sp)
|
||||
{
|
||||
using namespace lldb;
|
||||
const uint32_t event_type = event_sp->GetType();
|
||||
ProcessSP process_sp = (event_type == Process::eBroadcastBitStructuredData)
|
||||
? EventDataStructuredData::GetProcessFromEvent(event_sp.get())
|
||||
: Process::ProcessEventData::GetProcessFromEvent(event_sp.get());
|
||||
ProcessSP process_sp = Process::ProcessEventData::GetProcessFromEvent(event_sp.get());
|
||||
|
||||
StreamSP output_stream_sp = GetAsyncOutputStream();
|
||||
StreamSP error_stream_sp = GetAsyncErrorStream();
|
||||
|
@ -1500,9 +1498,6 @@ Debugger::HandleProcessEvent (const EventSP &event_sp)
|
|||
const bool got_state_changed = (event_type & Process::eBroadcastBitStateChanged) != 0;
|
||||
const bool got_stdout = (event_type & Process::eBroadcastBitSTDOUT) != 0;
|
||||
const bool got_stderr = (event_type & Process::eBroadcastBitSTDERR) != 0;
|
||||
const bool got_structured_data = (event_type &
|
||||
Process::eBroadcastBitStructuredData) != 0;
|
||||
|
||||
if (got_state_changed)
|
||||
{
|
||||
StateType event_state = Process::ProcessEventData::GetStateFromEvent (event_sp.get());
|
||||
|
@ -1527,45 +1522,6 @@ Debugger::HandleProcessEvent (const EventSP &event_sp)
|
|||
GetProcessSTDERR (process_sp.get(), error_stream_sp.get());
|
||||
}
|
||||
|
||||
// Give structured data events an opportunity to display.
|
||||
if (got_structured_data)
|
||||
{
|
||||
StructuredDataPluginSP plugin_sp =
|
||||
EventDataStructuredData::GetPluginFromEvent(event_sp.get());
|
||||
if (plugin_sp)
|
||||
{
|
||||
auto structured_data_sp =
|
||||
EventDataStructuredData::GetObjectFromEvent(event_sp.get());
|
||||
if (output_stream_sp)
|
||||
{
|
||||
StreamString content_stream;
|
||||
Error error = plugin_sp->GetDescription(structured_data_sp,
|
||||
content_stream);
|
||||
if (error.Success())
|
||||
{
|
||||
if (!content_stream.GetString().empty())
|
||||
{
|
||||
// Add newline.
|
||||
content_stream.PutChar('\n');
|
||||
content_stream.Flush();
|
||||
|
||||
// Print it.
|
||||
output_stream_sp->PutCString(content_stream
|
||||
.GetString().c_str());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
error_stream_sp->Printf("Failed to print structured "
|
||||
"data with plugin %s: %s",
|
||||
plugin_sp->GetPluginName()
|
||||
.AsCString(),
|
||||
error.AsCString());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Now display any stopped state changes after any STDIO
|
||||
if (got_state_changed && state_is_stopped)
|
||||
{
|
||||
|
@ -1630,8 +1586,7 @@ Debugger::DefaultEventHandler()
|
|||
BroadcastEventSpec process_event_spec (broadcaster_class_process,
|
||||
Process::eBroadcastBitStateChanged |
|
||||
Process::eBroadcastBitSTDOUT |
|
||||
Process::eBroadcastBitSTDERR |
|
||||
Process::eBroadcastBitStructuredData);
|
||||
Process::eBroadcastBitSTDERR);
|
||||
|
||||
BroadcastEventSpec thread_event_spec (broadcaster_class_thread,
|
||||
Thread::eBroadcastBitStackChanged |
|
||||
|
|
|
@ -25,13 +25,6 @@
|
|||
using namespace lldb;
|
||||
using namespace lldb_private;
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark Event
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// Event functions
|
||||
//------------------------------------------------------------------
|
||||
|
||||
Event::Event (Broadcaster *broadcaster, uint32_t event_type, EventData *data) :
|
||||
m_broadcaster_wp(broadcaster->GetBroadcasterImpl()),
|
||||
m_type(event_type),
|
||||
|
@ -108,13 +101,6 @@ Event::DoOnRemoval ()
|
|||
m_data_sp->DoOnRemoval (this);
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark EventData
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// EventData functions
|
||||
//------------------------------------------------------------------
|
||||
|
||||
EventData::EventData() = default;
|
||||
|
||||
EventData::~EventData() = default;
|
||||
|
@ -125,14 +111,6 @@ EventData::Dump (Stream *s) const
|
|||
s->PutCString ("Generic Event Data");
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark EventDataBytes
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// EventDataBytes functions
|
||||
//------------------------------------------------------------------
|
||||
|
||||
|
||||
EventDataBytes::EventDataBytes () :
|
||||
m_bytes()
|
||||
{
|
||||
|
@ -246,150 +224,3 @@ EventDataBytes::SwapBytes (std::string &new_bytes)
|
|||
{
|
||||
m_bytes.swap (new_bytes);
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark EventStructuredData
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// EventDataStructuredData definitions
|
||||
//------------------------------------------------------------------
|
||||
|
||||
EventDataStructuredData::EventDataStructuredData() :
|
||||
EventData(),
|
||||
m_process_sp(),
|
||||
m_object_sp(),
|
||||
m_plugin_sp()
|
||||
{
|
||||
}
|
||||
|
||||
EventDataStructuredData::EventDataStructuredData(const ProcessSP &process_sp,
|
||||
const StructuredData::ObjectSP
|
||||
&object_sp,
|
||||
const
|
||||
lldb::StructuredDataPluginSP
|
||||
&plugin_sp) :
|
||||
EventData(),
|
||||
m_process_sp(process_sp),
|
||||
m_object_sp(object_sp),
|
||||
m_plugin_sp(plugin_sp)
|
||||
{
|
||||
}
|
||||
|
||||
EventDataStructuredData::~EventDataStructuredData()
|
||||
{
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// EventDataStructuredData member functions
|
||||
//------------------------------------------------------------------
|
||||
|
||||
const ConstString &
|
||||
EventDataStructuredData::GetFlavor() const
|
||||
{
|
||||
return EventDataStructuredData::GetFlavorString();
|
||||
}
|
||||
|
||||
void
|
||||
EventDataStructuredData::Dump(Stream *s) const
|
||||
{
|
||||
if (!s)
|
||||
return;
|
||||
|
||||
if (m_object_sp)
|
||||
m_object_sp->Dump(*s);
|
||||
}
|
||||
|
||||
const ProcessSP&
|
||||
EventDataStructuredData::GetProcess() const
|
||||
{
|
||||
return m_process_sp;
|
||||
}
|
||||
|
||||
const StructuredData::ObjectSP&
|
||||
EventDataStructuredData::GetObject() const
|
||||
{
|
||||
return m_object_sp;
|
||||
}
|
||||
|
||||
const lldb::StructuredDataPluginSP&
|
||||
EventDataStructuredData::GetStructuredDataPlugin() const
|
||||
{
|
||||
return m_plugin_sp;
|
||||
}
|
||||
|
||||
void
|
||||
EventDataStructuredData::SetProcess(const ProcessSP &process_sp)
|
||||
{
|
||||
m_process_sp = process_sp;
|
||||
}
|
||||
|
||||
void
|
||||
EventDataStructuredData::SetObject(const StructuredData::ObjectSP &object_sp)
|
||||
{
|
||||
m_object_sp = object_sp;
|
||||
}
|
||||
|
||||
void
|
||||
EventDataStructuredData::SetStructuredDataPlugin(const
|
||||
lldb::StructuredDataPluginSP
|
||||
&plugin_sp)
|
||||
{
|
||||
m_plugin_sp = plugin_sp;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// EventDataStructuredData static functions
|
||||
//------------------------------------------------------------------
|
||||
|
||||
const EventDataStructuredData*
|
||||
EventDataStructuredData::GetEventDataFromEvent(const Event *event_ptr)
|
||||
{
|
||||
if (event_ptr == nullptr)
|
||||
return nullptr;
|
||||
|
||||
const EventData *event_data = event_ptr->GetData();
|
||||
if (!event_data || event_data->GetFlavor() !=
|
||||
EventDataStructuredData::GetFlavorString())
|
||||
return nullptr;
|
||||
|
||||
return static_cast<const EventDataStructuredData*>(event_data);
|
||||
}
|
||||
|
||||
ProcessSP
|
||||
EventDataStructuredData::GetProcessFromEvent(const Event *event_ptr)
|
||||
{
|
||||
auto event_data = EventDataStructuredData::GetEventDataFromEvent(event_ptr);
|
||||
if (event_data)
|
||||
return event_data->GetProcess();
|
||||
else
|
||||
return ProcessSP();
|
||||
}
|
||||
|
||||
StructuredData::ObjectSP
|
||||
EventDataStructuredData::GetObjectFromEvent(const Event *event_ptr)
|
||||
{
|
||||
auto event_data = EventDataStructuredData::GetEventDataFromEvent(event_ptr);
|
||||
if (event_data)
|
||||
return event_data->GetObject();
|
||||
else
|
||||
return StructuredData::ObjectSP();
|
||||
}
|
||||
|
||||
lldb::StructuredDataPluginSP
|
||||
EventDataStructuredData::GetPluginFromEvent(const Event *event_ptr)
|
||||
{
|
||||
auto event_data = EventDataStructuredData::GetEventDataFromEvent(event_ptr);
|
||||
if (event_data)
|
||||
return event_data->GetStructuredDataPlugin();
|
||||
else
|
||||
return StructuredDataPluginSP();
|
||||
}
|
||||
|
||||
const ConstString &
|
||||
EventDataStructuredData::GetFlavorString ()
|
||||
{
|
||||
static ConstString s_flavor("EventDataStructuredData");
|
||||
return s_flavor;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1917,146 +1917,6 @@ PluginManager::GetScriptInterpreterForLanguage(lldb::ScriptLanguage script_lang,
|
|||
return none_instance(interpreter);
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark StructuredDataPlugin
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// StructuredDataPlugin
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
struct StructuredDataPluginInstance
|
||||
{
|
||||
StructuredDataPluginInstance() :
|
||||
name(),
|
||||
description(),
|
||||
create_callback(nullptr),
|
||||
debugger_init_callback(nullptr),
|
||||
filter_callback(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
ConstString name;
|
||||
std::string description;
|
||||
StructuredDataPluginCreateInstance create_callback;
|
||||
DebuggerInitializeCallback debugger_init_callback;
|
||||
StructuredDataFilterLaunchInfo filter_callback;
|
||||
};
|
||||
|
||||
typedef std::vector<StructuredDataPluginInstance> StructuredDataPluginInstances;
|
||||
|
||||
static std::recursive_mutex &
|
||||
GetStructuredDataPluginMutex()
|
||||
{
|
||||
static std::recursive_mutex g_instances_mutex;
|
||||
return g_instances_mutex;
|
||||
}
|
||||
|
||||
static StructuredDataPluginInstances &
|
||||
GetStructuredDataPluginInstances ()
|
||||
{
|
||||
static StructuredDataPluginInstances g_instances;
|
||||
return g_instances;
|
||||
}
|
||||
|
||||
bool
|
||||
PluginManager::RegisterPlugin(const ConstString &name,
|
||||
const char *description,
|
||||
StructuredDataPluginCreateInstance
|
||||
create_callback,
|
||||
DebuggerInitializeCallback debugger_init_callback,
|
||||
StructuredDataFilterLaunchInfo filter_callback)
|
||||
{
|
||||
if (create_callback)
|
||||
{
|
||||
StructuredDataPluginInstance instance;
|
||||
assert((bool)name);
|
||||
instance.name = name;
|
||||
if (description && description[0])
|
||||
instance.description = description;
|
||||
instance.create_callback = create_callback;
|
||||
instance.debugger_init_callback = debugger_init_callback;
|
||||
instance.filter_callback = filter_callback;
|
||||
std::lock_guard<std::recursive_mutex> guard(
|
||||
GetStructuredDataPluginMutex());
|
||||
GetStructuredDataPluginInstances().push_back(instance);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
PluginManager::UnregisterPlugin(StructuredDataPluginCreateInstance create_callback)
|
||||
{
|
||||
if (create_callback)
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> guard(
|
||||
GetStructuredDataPluginMutex());
|
||||
StructuredDataPluginInstances &instances =
|
||||
GetStructuredDataPluginInstances();
|
||||
|
||||
StructuredDataPluginInstances::iterator pos, end = instances.end();
|
||||
for (pos = instances.begin(); pos != end; ++ pos)
|
||||
{
|
||||
if (pos->create_callback == create_callback)
|
||||
{
|
||||
instances.erase(pos);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
StructuredDataPluginCreateInstance
|
||||
PluginManager::GetStructuredDataPluginCreateCallbackAtIndex(uint32_t idx)
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> guard(GetStructuredDataPluginMutex());
|
||||
StructuredDataPluginInstances &instances =
|
||||
GetStructuredDataPluginInstances();
|
||||
if (idx < instances.size())
|
||||
return instances[idx].create_callback;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
StructuredDataPluginCreateInstance
|
||||
PluginManager::GetStructuredDataPluginCreateCallbackForPluginName(
|
||||
const ConstString &name)
|
||||
{
|
||||
if (name)
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> guard(
|
||||
GetStructuredDataPluginMutex());
|
||||
StructuredDataPluginInstances &instances =
|
||||
GetStructuredDataPluginInstances();
|
||||
|
||||
StructuredDataPluginInstances::iterator pos, end = instances.end();
|
||||
for (pos = instances.begin(); pos != end; ++ pos)
|
||||
{
|
||||
if (name == pos->name)
|
||||
return pos->create_callback;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
StructuredDataFilterLaunchInfo
|
||||
PluginManager::GetStructuredDataFilterCallbackAtIndex(uint32_t idx,
|
||||
bool &iteration_complete)
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> guard(GetStructuredDataPluginMutex());
|
||||
StructuredDataPluginInstances &instances =
|
||||
GetStructuredDataPluginInstances();
|
||||
if (idx < instances.size())
|
||||
{
|
||||
iteration_complete = false;
|
||||
return instances[idx].filter_callback;
|
||||
}
|
||||
else
|
||||
{
|
||||
iteration_complete = true;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
#pragma mark SymbolFile
|
||||
|
||||
struct SymbolFileInstance
|
||||
|
@ -2912,17 +2772,6 @@ PluginManager::DebuggerInitialize (Debugger &debugger)
|
|||
os.debugger_init_callback(debugger);
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize the StructuredDataPlugin plugins
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex>
|
||||
guard(GetStructuredDataPluginMutex());
|
||||
for (auto &plugin: GetStructuredDataPluginInstances())
|
||||
{
|
||||
if (plugin.debugger_init_callback)
|
||||
plugin.debugger_init_callback(debugger);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// This is the preferred new way to register plugin specific settings. e.g.
|
||||
|
@ -3056,7 +2905,6 @@ const char* kPlatformPluginName("platform");
|
|||
const char* kProcessPluginName("process");
|
||||
const char* kSymbolFilePluginName("symbol-file");
|
||||
const char* kJITLoaderPluginName("jit-loader");
|
||||
const char* kStructuredDataPluginName("structured-data");
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
|
@ -3201,24 +3049,3 @@ PluginManager::CreateSettingForOperatingSystemPlugin(Debugger &debugger,
|
|||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
lldb::OptionValuePropertiesSP
|
||||
PluginManager::GetSettingForStructuredDataPlugin(Debugger &debugger,
|
||||
const ConstString &setting_name)
|
||||
{
|
||||
return GetSettingForPlugin(debugger, setting_name, ConstString(kStructuredDataPluginName));
|
||||
}
|
||||
|
||||
bool
|
||||
PluginManager::CreateSettingForStructuredDataPlugin(Debugger &debugger,
|
||||
const lldb::OptionValuePropertiesSP &properties_sp,
|
||||
const ConstString &description,
|
||||
bool is_global_property)
|
||||
{
|
||||
return CreateSettingForPlugin(debugger,
|
||||
ConstString(kStructuredDataPluginName),
|
||||
ConstString("Settings for structured data plug-ins"),
|
||||
properties_sp,
|
||||
description,
|
||||
is_global_property);
|
||||
}
|
||||
|
|
|
@ -1170,48 +1170,8 @@ Args::LongestCommonPrefix (std::string &common_prefix)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
Args::AddOrReplaceEnvironmentVariable(const char *env_var_name,
|
||||
const char *new_value)
|
||||
{
|
||||
if (!env_var_name || !new_value)
|
||||
return;
|
||||
|
||||
// Build the new entry.
|
||||
StreamString stream;
|
||||
stream << env_var_name;
|
||||
stream << '=';
|
||||
stream << new_value;
|
||||
stream.Flush();
|
||||
|
||||
// Find the environment variable if present and replace it.
|
||||
for (size_t i = 0; i < GetArgumentCount(); ++i)
|
||||
{
|
||||
// Get the env var value.
|
||||
const char *arg_value = GetArgumentAtIndex(i);
|
||||
if (!arg_value)
|
||||
continue;
|
||||
|
||||
// Find the name of the env var: before the first =.
|
||||
auto equal_p = strchr(arg_value, '=');
|
||||
if (!equal_p)
|
||||
continue;
|
||||
|
||||
// Check if the name matches the given env_var_name.
|
||||
if (strncmp(env_var_name, arg_value, equal_p - arg_value) == 0)
|
||||
{
|
||||
ReplaceArgumentAtIndex(i, stream.GetString().c_str());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// We didn't find it. Append it instead.
|
||||
AppendArgument(stream.GetString().c_str());
|
||||
}
|
||||
|
||||
bool
|
||||
Args::ContainsEnvironmentVariable(const char *env_var_name,
|
||||
size_t *argument_index) const
|
||||
Args::ContainsEnvironmentVariable(const char *env_var_name) const
|
||||
{
|
||||
// Validate args.
|
||||
if (!env_var_name)
|
||||
|
@ -1233,8 +1193,6 @@ Args::ContainsEnvironmentVariable(const char *env_var_name,
|
|||
equal_p - argument_value) == 0)
|
||||
{
|
||||
// We matched.
|
||||
if (argument_index)
|
||||
*argument_index = i;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -1244,8 +1202,6 @@ Args::ContainsEnvironmentVariable(const char *env_var_name,
|
|||
if (strcmp(argument_value, env_var_name) == 0)
|
||||
{
|
||||
// We matched.
|
||||
if (argument_index)
|
||||
*argument_index = i;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,7 +11,6 @@
|
|||
|
||||
#include "llvm/ADT/StringExtras.h"
|
||||
|
||||
#include "lldb/Target/Process.h"
|
||||
#include "lldb/Target/UnixSignals.h"
|
||||
#include "lldb/Utility/LLDBAssert.h"
|
||||
|
||||
|
@ -101,41 +100,6 @@ GDBRemoteClientBase::SendContinuePacketAndWaitForResponse(ContinueDelegate &dele
|
|||
case 'A':
|
||||
delegate.HandleAsyncMisc(llvm::StringRef(response.GetStringRef()).substr(1));
|
||||
break;
|
||||
|
||||
case 'J':
|
||||
// Asynchronous JSON packet, destined for a
|
||||
// StructuredDataPlugin.
|
||||
{
|
||||
// Parse the content into a StructuredData instance.
|
||||
auto payload_index = strlen("JSON-async:");
|
||||
StructuredData::ObjectSP json_sp =
|
||||
StructuredData::ParseJSON(response.GetStringRef()
|
||||
.substr(payload_index));
|
||||
if (log)
|
||||
{
|
||||
if (json_sp)
|
||||
log->Printf(
|
||||
"GDBRemoteCommmunicationClientBase::%s() "
|
||||
"received Async StructuredData packet: %s",
|
||||
__FUNCTION__,
|
||||
response.GetStringRef().
|
||||
substr(payload_index).c_str());
|
||||
else
|
||||
log->Printf("GDBRemoteCommmunicationClientBase::%s"
|
||||
"() received StructuredData packet:"
|
||||
" parse failure", __FUNCTION__);
|
||||
}
|
||||
|
||||
// Pass the data to the process to route to the
|
||||
// appropriate plugin. The plugin controls what happens
|
||||
// to it from there.
|
||||
bool routed = delegate.HandleAsyncStructuredData(json_sp);
|
||||
if (log)
|
||||
log->Printf("GDBRemoteCommmunicationClientBase::%s()"
|
||||
" packet %s", __FUNCTION__,
|
||||
routed ? "handled" : "not handled");
|
||||
break;
|
||||
}
|
||||
case 'T':
|
||||
case 'S':
|
||||
// Do this with the continue lock held.
|
||||
|
|
|
@ -31,16 +31,6 @@ public:
|
|||
HandleAsyncMisc(llvm::StringRef data) = 0;
|
||||
virtual void
|
||||
HandleStopReply() = 0;
|
||||
|
||||
//
|
||||
/// Processes async structured data.
|
||||
///
|
||||
/// @return
|
||||
/// true if the data was handled; otherwise, false.
|
||||
//
|
||||
virtual bool
|
||||
HandleAsyncStructuredData(const StructuredData::ObjectSP
|
||||
&object_sp) = 0;
|
||||
};
|
||||
|
||||
GDBRemoteClientBase(const char *comm_name, const char *listener_name);
|
||||
|
|
|
@ -30,8 +30,6 @@
|
|||
#include "lldb/Interpreter/Args.h"
|
||||
#include "lldb/Symbol/Symbol.h"
|
||||
#include "lldb/Target/MemoryRegionInfo.h"
|
||||
#include "lldb/Target/UnixSignals.h"
|
||||
#include "lldb/Utility/LLDBAssert.h"
|
||||
#include "lldb/Target/Target.h"
|
||||
|
||||
// Project includes
|
||||
|
@ -116,10 +114,7 @@ GDBRemoteCommunicationClient::GDBRemoteCommunicationClient()
|
|||
m_gdb_server_name(),
|
||||
m_gdb_server_version(UINT32_MAX),
|
||||
m_default_packet_timeout(0),
|
||||
m_max_packet_size(0),
|
||||
m_qSupported_response(),
|
||||
m_supported_async_json_packets_is_valid(false),
|
||||
m_supported_async_json_packets_sp()
|
||||
m_max_packet_size(0)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -383,9 +378,6 @@ GDBRemoteCommunicationClient::ResetDiscoverableSettings (bool did_exec)
|
|||
m_gdb_server_version = UINT32_MAX;
|
||||
m_default_packet_timeout = 0;
|
||||
m_max_packet_size = 0;
|
||||
m_qSupported_response.clear();
|
||||
m_supported_async_json_packets_is_valid = false;
|
||||
m_supported_async_json_packets_sp.reset();
|
||||
}
|
||||
|
||||
// These flags should be reset when we first connect to a GDB server
|
||||
|
@ -421,12 +413,6 @@ GDBRemoteCommunicationClient::GetRemoteQSupported ()
|
|||
/*send_async=*/false) == PacketResult::Success)
|
||||
{
|
||||
const char *response_cstr = response.GetStringRef().c_str();
|
||||
|
||||
// Hang on to the qSupported packet, so that platforms can do custom
|
||||
// configuration of the transport before attaching/launching the
|
||||
// process.
|
||||
m_qSupported_response = response_cstr;
|
||||
|
||||
if (::strstr (response_cstr, "qXfer:auxv:read+"))
|
||||
m_supports_qXfer_auxv_read = eLazyBoolYes;
|
||||
if (::strstr (response_cstr, "qXfer:libraries-svr4:read+"))
|
||||
|
@ -3920,126 +3906,6 @@ GDBRemoteCommunicationClient::ServeSymbolLookups(lldb_private::Process *process)
|
|||
}
|
||||
}
|
||||
|
||||
StructuredData::Array*
|
||||
GDBRemoteCommunicationClient::GetSupportedStructuredDataPlugins()
|
||||
{
|
||||
if (!m_supported_async_json_packets_is_valid)
|
||||
{
|
||||
// Query the server for the array of supported asynchronous JSON
|
||||
// packets.
|
||||
m_supported_async_json_packets_is_valid = true;
|
||||
|
||||
Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(
|
||||
GDBR_LOG_PROCESS));
|
||||
|
||||
// Poll it now.
|
||||
StringExtractorGDBRemote response;
|
||||
const bool send_async = false;
|
||||
if (SendPacketAndWaitForResponse("qStructuredDataPlugins", response,
|
||||
send_async) == PacketResult::Success)
|
||||
{
|
||||
m_supported_async_json_packets_sp = StructuredData::ParseJSON(
|
||||
response.GetStringRef());
|
||||
if (m_supported_async_json_packets_sp &&
|
||||
!m_supported_async_json_packets_sp->GetAsArray())
|
||||
{
|
||||
// We were returned something other than a JSON array. This
|
||||
// is invalid. Clear it out.
|
||||
if (log)
|
||||
log->Printf("GDBRemoteCommunicationClient::%s(): "
|
||||
"QSupportedAsyncJSONPackets returned invalid "
|
||||
"result: %s", __FUNCTION__,
|
||||
response.GetStringRef().c_str());
|
||||
m_supported_async_json_packets_sp.reset();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (log)
|
||||
log->Printf("GDBRemoteCommunicationClient::%s(): "
|
||||
"QSupportedAsyncJSONPackets unsupported",
|
||||
__FUNCTION__);
|
||||
}
|
||||
|
||||
if (log && m_supported_async_json_packets_is_valid)
|
||||
{
|
||||
StreamString stream;
|
||||
m_supported_async_json_packets_sp->Dump(stream);
|
||||
log->Printf("GDBRemoteCommunicationClient::%s(): supported async "
|
||||
"JSON packets: %s", __FUNCTION__,
|
||||
stream.GetString().c_str());
|
||||
}
|
||||
}
|
||||
|
||||
return m_supported_async_json_packets_sp
|
||||
? m_supported_async_json_packets_sp->GetAsArray()
|
||||
: nullptr;
|
||||
}
|
||||
|
||||
Error
|
||||
GDBRemoteCommunicationClient::ConfigureRemoteStructuredData(
|
||||
const ConstString &type_name,
|
||||
const StructuredData::ObjectSP &config_sp)
|
||||
{
|
||||
Error error;
|
||||
|
||||
if (type_name.GetLength() == 0)
|
||||
{
|
||||
error.SetErrorString("invalid type_name argument");
|
||||
return error;
|
||||
}
|
||||
|
||||
// Build command: Configure{type_name}: serialized config
|
||||
// data.
|
||||
StreamGDBRemote stream;
|
||||
stream.PutCString("QConfigure");
|
||||
stream.PutCString(type_name.AsCString());
|
||||
stream.PutChar(':');
|
||||
if (config_sp)
|
||||
{
|
||||
// Gather the plain-text version of the configuration data.
|
||||
StreamString unescaped_stream;
|
||||
config_sp->Dump(unescaped_stream);
|
||||
unescaped_stream.Flush();
|
||||
|
||||
// Add it to the stream in escaped fashion.
|
||||
stream.PutEscapedBytes(unescaped_stream.GetData(),
|
||||
unescaped_stream.GetSize());
|
||||
}
|
||||
stream.Flush();
|
||||
|
||||
// Send the packet.
|
||||
const bool send_async = false;
|
||||
StringExtractorGDBRemote response;
|
||||
auto result = SendPacketAndWaitForResponse(stream.GetString().c_str(),
|
||||
response, send_async);
|
||||
if (result == PacketResult::Success)
|
||||
{
|
||||
// We failed if the config result comes back other than OK.
|
||||
if (strcmp(response.GetStringRef().c_str(), "OK") == 0)
|
||||
{
|
||||
// Okay!
|
||||
error.Clear();
|
||||
}
|
||||
else
|
||||
{
|
||||
error.SetErrorStringWithFormat("configuring StructuredData feature "
|
||||
"%s failed with error %s",
|
||||
type_name.AsCString(),
|
||||
response.GetStringRef().c_str());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Can we get more data here on the failure?
|
||||
error.SetErrorStringWithFormat("configuring StructuredData feature %s "
|
||||
"failed when sending packet: "
|
||||
"PacketResult=%d", type_name.AsCString(),
|
||||
result);
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
void
|
||||
GDBRemoteCommunicationClient::OnRunPacketSent(bool first)
|
||||
{
|
||||
|
|
|
@ -547,53 +547,6 @@ public:
|
|||
void
|
||||
ServeSymbolLookups(lldb_private::Process *process);
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Return the feature set supported by the gdb-remote server.
|
||||
///
|
||||
/// This method returns the remote side's response to the qSupported
|
||||
/// packet. The response is the complete string payload returned
|
||||
/// to the client.
|
||||
///
|
||||
/// @return
|
||||
/// The string returned by the server to the qSupported query.
|
||||
//------------------------------------------------------------------
|
||||
const std::string&
|
||||
GetServerSupportedFeatures() const
|
||||
{
|
||||
return m_qSupported_response;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Return the array of async JSON packet types supported by the remote.
|
||||
///
|
||||
/// This method returns the remote side's array of supported JSON
|
||||
/// packet types as a list of type names. Each of the results are
|
||||
/// expected to have an Enable{type_name} command to enable and configure
|
||||
/// the related feature. Each type_name for an enabled feature will
|
||||
/// possibly send async-style packets that contain a payload of a
|
||||
/// binhex-encoded JSON dictionary. The dictionary will have a
|
||||
/// string field named 'type', that contains the type_name of the
|
||||
/// supported packet type.
|
||||
///
|
||||
/// There is a Plugin category called structured-data plugins.
|
||||
/// A plugin indicates whether it knows how to handle a type_name.
|
||||
/// If so, it can be used to process the async JSON packet.
|
||||
///
|
||||
/// @return
|
||||
/// The string returned by the server to the qSupported query.
|
||||
//------------------------------------------------------------------
|
||||
lldb_private::StructuredData::Array*
|
||||
GetSupportedStructuredDataPlugins();
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Configure a StructuredData feature on the remote end.
|
||||
///
|
||||
/// @see \b Process::ConfigureStructuredData(...) for details.
|
||||
//------------------------------------------------------------------
|
||||
Error
|
||||
ConfigureRemoteStructuredData(const ConstString &type_name,
|
||||
const StructuredData::ObjectSP &config_sp);
|
||||
|
||||
protected:
|
||||
LazyBool m_supports_not_sending_acks;
|
||||
LazyBool m_supports_thread_suffix;
|
||||
|
@ -664,10 +617,6 @@ protected:
|
|||
uint32_t m_gdb_server_version; // from reply to qGDBServerVersion, zero if qGDBServerVersion is not supported
|
||||
uint32_t m_default_packet_timeout;
|
||||
uint64_t m_max_packet_size; // as returned by qSupported
|
||||
std::string m_qSupported_response; // the complete response to qSupported
|
||||
|
||||
bool m_supported_async_json_packets_is_valid;
|
||||
lldb_private::StructuredData::ObjectSP m_supported_async_json_packets_sp;
|
||||
|
||||
bool
|
||||
GetCurrentProcessInfo (bool allow_lazy_pid = true);
|
||||
|
|
|
@ -1175,7 +1175,7 @@ ProcessGDBRemote::DidLaunchOrAttach (ArchSpec& process_arch)
|
|||
{
|
||||
Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS));
|
||||
if (log)
|
||||
log->Printf ("ProcessGDBRemote::%s()", __FUNCTION__);
|
||||
log->Printf ("ProcessGDBRemote::DidLaunch()");
|
||||
if (GetID() != LLDB_INVALID_PROCESS_ID)
|
||||
{
|
||||
BuildDynamicRegisterInfo (false);
|
||||
|
@ -1271,13 +1271,6 @@ ProcessGDBRemote::DidLaunchOrAttach (ArchSpec& process_arch)
|
|||
GetTarget().SetArchitecture (process_arch);
|
||||
}
|
||||
}
|
||||
|
||||
// Find out which StructuredDataPlugins are supported by the
|
||||
// debug monitor. These plugins transmit data over async $J packets.
|
||||
auto supported_packets_array =
|
||||
m_gdb_comm.GetSupportedStructuredDataPlugins();
|
||||
if (supported_packets_array)
|
||||
MapSupportedStructuredDataPlugins(*supported_packets_array);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4349,13 +4342,6 @@ ProcessGDBRemote::GetSharedCacheInfo ()
|
|||
return object_sp;
|
||||
}
|
||||
|
||||
Error
|
||||
ProcessGDBRemote::ConfigureStructuredData(const ConstString &type_name,
|
||||
const StructuredData::ObjectSP
|
||||
&config_sp)
|
||||
{
|
||||
return m_gdb_comm.ConfigureRemoteStructuredData(type_name, config_sp);
|
||||
}
|
||||
|
||||
// Establish the largest memory read/write payloads we should use.
|
||||
// If the remote stub has a max packet size, stay under that size.
|
||||
|
@ -5249,13 +5235,6 @@ ProcessGDBRemote::HandleStopReply()
|
|||
BuildDynamicRegisterInfo(true);
|
||||
}
|
||||
|
||||
bool
|
||||
ProcessGDBRemote::HandleAsyncStructuredData(const StructuredData::ObjectSP
|
||||
&object_sp)
|
||||
{
|
||||
return RouteAsyncStructuredData(object_sp);
|
||||
}
|
||||
|
||||
class CommandObjectProcessGDBRemoteSpeedTest: public CommandObjectParsed
|
||||
{
|
||||
public:
|
||||
|
|
|
@ -261,10 +261,6 @@ public:
|
|||
StructuredData::ObjectSP
|
||||
GetLoadedDynamicLibrariesInfos (lldb::addr_t image_list_address, lldb::addr_t image_count) override;
|
||||
|
||||
Error
|
||||
ConfigureStructuredData(const ConstString &type_name,
|
||||
const StructuredData::ObjectSP &config_sp) override;
|
||||
|
||||
StructuredData::ObjectSP
|
||||
GetLoadedDynamicLibrariesInfos () override;
|
||||
|
||||
|
@ -510,9 +506,6 @@ private:
|
|||
HandleAsyncMisc(llvm::StringRef data) override;
|
||||
void
|
||||
HandleStopReply() override;
|
||||
bool
|
||||
HandleAsyncStructuredData(const StructuredData::ObjectSP
|
||||
&object_sp) override;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN (ProcessGDBRemote);
|
||||
};
|
||||
|
|
|
@ -1,2 +0,0 @@
|
|||
add_subdirectory(DarwinLog)
|
||||
|
|
@ -1,5 +0,0 @@
|
|||
list(APPEND SOURCES
|
||||
StructuredDataDarwinLog.cpp
|
||||
)
|
||||
|
||||
add_lldb_library(lldbPluginStructuredDataDarwinLog ${SOURCES})
|
File diff suppressed because it is too large
Load Diff
|
@ -1,164 +0,0 @@
|
|||
//===-- StructuredDataDarwinLog.h -------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
|
||||
#ifndef StructuredDataDarwinLog_h
|
||||
#define StructuredDataDarwinLog_h
|
||||
|
||||
#include "lldb/Target/StructuredDataPlugin.h"
|
||||
|
||||
#include <mutex>
|
||||
|
||||
// Forward declarations
|
||||
namespace sddarwinlog_private
|
||||
{
|
||||
class EnableCommand;
|
||||
}
|
||||
|
||||
namespace lldb_private
|
||||
{
|
||||
|
||||
class StructuredDataDarwinLog : public StructuredDataPlugin
|
||||
{
|
||||
friend sddarwinlog_private::EnableCommand;
|
||||
|
||||
public:
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Public static API
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
static void
|
||||
Initialize();
|
||||
|
||||
static void
|
||||
Terminate();
|
||||
|
||||
static const ConstString&
|
||||
GetStaticPluginName();
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
/// Return whether the DarwinLog functionality is enabled.
|
||||
///
|
||||
/// The DarwinLog functionality is enabled if the user expicitly enabled
|
||||
/// it with the enable command, or if the user has the setting set
|
||||
/// that controls if we always enable it for newly created/attached
|
||||
/// processes.
|
||||
///
|
||||
/// @return
|
||||
/// True if DarwinLog support is/will be enabled for existing or
|
||||
/// newly launched/attached processes.
|
||||
// -------------------------------------------------------------------------
|
||||
static bool
|
||||
IsEnabled();
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// PluginInterface API
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
ConstString
|
||||
GetPluginName() override;
|
||||
|
||||
uint32_t
|
||||
GetPluginVersion() override;
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// StructuredDataPlugin API
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
bool
|
||||
SupportsStructuredDataType(const ConstString &type_name) override;
|
||||
|
||||
void
|
||||
HandleArrivalOfStructuredData(Process &process,
|
||||
const ConstString &type_name,
|
||||
const StructuredData::ObjectSP
|
||||
&object_sp) override;
|
||||
|
||||
Error
|
||||
GetDescription(const StructuredData::ObjectSP &object_sp,
|
||||
lldb_private::Stream &stream) override;
|
||||
|
||||
|
||||
bool
|
||||
GetEnabled(const ConstString &type_name) const override;
|
||||
|
||||
void
|
||||
ModulesDidLoad(Process &process, ModuleList &module_list) override;
|
||||
|
||||
private:
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Private constructors
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
StructuredDataDarwinLog(const lldb::ProcessWP &process_wp);
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Private static methods
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
static lldb::StructuredDataPluginSP
|
||||
CreateInstance(Process &process);
|
||||
|
||||
static void
|
||||
DebuggerInitialize(Debugger &debugger);
|
||||
|
||||
static bool
|
||||
InitCompletionHookCallback(void *baton, StoppointCallbackContext *context,
|
||||
lldb::user_id_t break_id,
|
||||
lldb::user_id_t break_loc_id);
|
||||
|
||||
static Error
|
||||
FilterLaunchInfo(ProcessLaunchInfo &launch_info, Target *target);
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Internal helper methods used by friend classes
|
||||
// -------------------------------------------------------------------------
|
||||
void
|
||||
SetEnabled(bool enabled);
|
||||
|
||||
void
|
||||
AddInitCompletionHook(Process &process);
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Private methods
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
void
|
||||
DumpTimestamp(Stream &stream, uint64_t timestamp);
|
||||
|
||||
size_t
|
||||
DumpHeader(Stream &stream, const StructuredData::Dictionary &event);
|
||||
|
||||
size_t
|
||||
HandleDisplayOfEvent(const StructuredData::Dictionary &event,
|
||||
Stream &stream);
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
/// Call the enable command again, using whatever settings were initially
|
||||
/// made.
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
void
|
||||
EnableNow();
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Private data
|
||||
// -------------------------------------------------------------------------
|
||||
bool m_recorded_first_timestamp;
|
||||
uint64_t m_first_timestamp_seen;
|
||||
bool m_is_enabled;
|
||||
std::mutex m_added_breakpoint_mutex;
|
||||
bool m_added_breakpoint;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif /* StructuredDataPluginDarwinLog_hpp */
|
|
@ -30,7 +30,6 @@ add_lldb_library(lldbTarget
|
|||
StackFrameList.cpp
|
||||
StackID.cpp
|
||||
StopInfo.cpp
|
||||
StructuredDataPlugin.cpp
|
||||
SystemRuntime.cpp
|
||||
Target.cpp
|
||||
TargetList.cpp
|
||||
|
@ -41,7 +40,6 @@ add_lldb_library(lldbTarget
|
|||
ThreadPlanBase.cpp
|
||||
ThreadPlanCallFunction.cpp
|
||||
ThreadPlanCallFunctionUsingABI.cpp
|
||||
ThreadPlanCallOnFunctionExit.cpp
|
||||
ThreadPlanCallUserExpression.cpp
|
||||
ThreadPlanPython.cpp
|
||||
ThreadPlanRunToAddress.cpp
|
||||
|
|
|
@ -1314,34 +1314,7 @@ Platform::DebugProcess (ProcessLaunchInfo &launch_info,
|
|||
// group, since then we can handle ^C interrupts ourselves w/o having to worry
|
||||
// about the target getting them as well.
|
||||
launch_info.SetLaunchInSeparateProcessGroup(true);
|
||||
|
||||
// Allow any StructuredData process-bound plugins to adjust the launch info
|
||||
// if needed
|
||||
size_t i = 0;
|
||||
bool iteration_complete = false;
|
||||
// Note iteration can't simply go until a nullptr callback is returned, as
|
||||
// it is valid for a plugin to not supply a filter.
|
||||
auto get_filter_func =
|
||||
PluginManager::GetStructuredDataFilterCallbackAtIndex;
|
||||
for (auto filter_callback = get_filter_func(i, iteration_complete);
|
||||
!iteration_complete;
|
||||
filter_callback = get_filter_func(++i, iteration_complete))
|
||||
{
|
||||
if (filter_callback)
|
||||
{
|
||||
// Give this ProcessLaunchInfo filter a chance to adjust the launch
|
||||
// info.
|
||||
error = (*filter_callback)(launch_info, target);
|
||||
if (!error.Success())
|
||||
{
|
||||
if (log)
|
||||
log->Printf("Platform::%s() StructuredDataPlugin launch "
|
||||
"filter failed.", __FUNCTION__);
|
||||
return process_sp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
error = LaunchProcess (launch_info);
|
||||
if (error.Success())
|
||||
{
|
||||
|
|
|
@ -54,7 +54,6 @@
|
|||
#include "lldb/Target/Process.h"
|
||||
#include "lldb/Target/RegisterContext.h"
|
||||
#include "lldb/Target/StopInfo.h"
|
||||
#include "lldb/Target/StructuredDataPlugin.h"
|
||||
#include "lldb/Target/SystemRuntime.h"
|
||||
#include "lldb/Target/Target.h"
|
||||
#include "lldb/Target/TargetList.h"
|
||||
|
@ -798,7 +797,6 @@ Process::Process(lldb::TargetSP target_sp, ListenerSP listener_sp, const UnixSig
|
|||
SetEventName(eBroadcastBitSTDOUT, "stdout-available");
|
||||
SetEventName(eBroadcastBitSTDERR, "stderr-available");
|
||||
SetEventName(eBroadcastBitProfileData, "profile-data-available");
|
||||
SetEventName(eBroadcastBitStructuredData, "structured-data-available");
|
||||
|
||||
m_private_state_control_broadcaster.SetEventName(eBroadcastInternalStateControlStop, "control-stop");
|
||||
m_private_state_control_broadcaster.SetEventName(eBroadcastInternalStateControlPause, "control-pause");
|
||||
|
@ -806,8 +804,7 @@ Process::Process(lldb::TargetSP target_sp, ListenerSP listener_sp, const UnixSig
|
|||
|
||||
m_listener_sp->StartListeningForEvents(this, eBroadcastBitStateChanged | eBroadcastBitInterrupt |
|
||||
eBroadcastBitSTDOUT | eBroadcastBitSTDERR |
|
||||
eBroadcastBitProfileData |
|
||||
eBroadcastBitStructuredData);
|
||||
eBroadcastBitProfileData);
|
||||
|
||||
m_private_state_listener_sp->StartListeningForEvents(&m_private_state_broadcaster,
|
||||
eBroadcastBitStateChanged | eBroadcastBitInterrupt);
|
||||
|
@ -4798,25 +4795,6 @@ Process::BroadcastAsyncProfileData(const std::string &one_profile_data)
|
|||
BroadcastEventIfUnique (eBroadcastBitProfileData, new ProcessEventData (shared_from_this(), GetState()));
|
||||
}
|
||||
|
||||
void
|
||||
Process::BroadcastStructuredData(const StructuredData::ObjectSP &object_sp,
|
||||
const StructuredDataPluginSP &plugin_sp)
|
||||
{
|
||||
BroadcastEvent(eBroadcastBitStructuredData,
|
||||
new EventDataStructuredData(shared_from_this(),
|
||||
object_sp, plugin_sp));
|
||||
}
|
||||
|
||||
StructuredDataPluginSP
|
||||
Process::GetStructuredDataPlugin(const ConstString &type_name) const
|
||||
{
|
||||
auto find_it = m_structured_data_plugin_map.find(type_name);
|
||||
if (find_it != m_structured_data_plugin_map.end())
|
||||
return find_it->second;
|
||||
else
|
||||
return StructuredDataPluginSP();
|
||||
}
|
||||
|
||||
size_t
|
||||
Process::GetAsyncProfileData (char *buf, size_t buf_size, Error &error)
|
||||
{
|
||||
|
@ -6403,13 +6381,6 @@ Process::ModulesDidLoad (ModuleList &module_list)
|
|||
// loading shared libraries might cause a new one to try and load
|
||||
if (!m_os_ap)
|
||||
LoadOperatingSystemPlugin(false);
|
||||
|
||||
// Give structured-data plugins a chance to see the modified modules.
|
||||
for (auto pair : m_structured_data_plugin_map)
|
||||
{
|
||||
if (pair.second)
|
||||
pair.second->ModulesDidLoad(*this, module_list);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -6627,129 +6598,5 @@ Process::GetMemoryRegions (std::vector<lldb::MemoryRegionInfoSP>& region_list)
|
|||
} while (range_end != LLDB_INVALID_ADDRESS);
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
Error
|
||||
Process::ConfigureStructuredData(const ConstString &type_name,
|
||||
const StructuredData::ObjectSP &config_sp)
|
||||
{
|
||||
// If you get this, the Process-derived class needs to implement a method
|
||||
// to enable an already-reported asynchronous structured data feature.
|
||||
// See ProcessGDBRemote for an example implementation over gdb-remote.
|
||||
return Error("unimplemented");
|
||||
}
|
||||
|
||||
void
|
||||
Process::MapSupportedStructuredDataPlugins(const StructuredData::Array
|
||||
&supported_type_names)
|
||||
{
|
||||
Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
|
||||
|
||||
// Bail out early if there are no type names to map.
|
||||
if (supported_type_names.GetSize() == 0)
|
||||
{
|
||||
if (log)
|
||||
log->Printf("Process::%s(): no structured data types supported",
|
||||
__FUNCTION__);
|
||||
return;
|
||||
}
|
||||
|
||||
// Convert StructuredData type names to ConstString instances.
|
||||
std::set<ConstString> const_type_names;
|
||||
|
||||
if (log)
|
||||
log->Printf("Process::%s(): the process supports the following async "
|
||||
"structured data types:", __FUNCTION__);
|
||||
|
||||
supported_type_names.ForEach([&const_type_names, &log]
|
||||
(StructuredData::Object *object) {
|
||||
if (!object)
|
||||
{
|
||||
// Invalid - shouldn't be null objects in the array.
|
||||
return false;
|
||||
}
|
||||
|
||||
auto type_name = object->GetAsString();
|
||||
if (!type_name)
|
||||
{
|
||||
// Invalid format - all type names should be strings.
|
||||
return false;
|
||||
}
|
||||
|
||||
const_type_names.insert(ConstString(type_name->GetValue()));
|
||||
if (log)
|
||||
log->Printf("- %s", type_name->GetValue().c_str());
|
||||
return true;
|
||||
});
|
||||
|
||||
// For each StructuredDataPlugin, if the plugin handles any of the
|
||||
// types in the supported_type_names, map that type name to that plugin.
|
||||
uint32_t plugin_index = 0;
|
||||
for (auto create_instance =
|
||||
PluginManager::GetStructuredDataPluginCreateCallbackAtIndex(plugin_index);
|
||||
create_instance && !const_type_names.empty();
|
||||
++plugin_index)
|
||||
{
|
||||
// Create the plugin.
|
||||
StructuredDataPluginSP plugin_sp = (*create_instance)(*this);
|
||||
if (!plugin_sp)
|
||||
{
|
||||
// This plugin doesn't think it can work with the process.
|
||||
// Move on to the next.
|
||||
continue;
|
||||
}
|
||||
|
||||
// For any of the remaining type names, map any that this plugin
|
||||
// supports.
|
||||
std::vector<ConstString> names_to_remove;
|
||||
for (auto &type_name : const_type_names)
|
||||
{
|
||||
if (plugin_sp->SupportsStructuredDataType(type_name))
|
||||
{
|
||||
m_structured_data_plugin_map.insert(std::make_pair(type_name,
|
||||
plugin_sp));
|
||||
names_to_remove.push_back(type_name);
|
||||
if (log)
|
||||
log->Printf("Process::%s(): using plugin %s for type name "
|
||||
"%s", __FUNCTION__,
|
||||
plugin_sp->GetPluginName().GetCString(),
|
||||
type_name.GetCString());
|
||||
}
|
||||
}
|
||||
|
||||
// Remove the type names that were consumed by this plugin.
|
||||
for (auto &type_name : names_to_remove)
|
||||
const_type_names.erase(type_name);
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
Process::RouteAsyncStructuredData(const StructuredData::ObjectSP object_sp)
|
||||
{
|
||||
// Nothing to do if there's no data.
|
||||
if (!object_sp)
|
||||
return false;
|
||||
|
||||
// The contract is this must be a dictionary, so we can look up the
|
||||
// routing key via the top-level 'type' string value within the dictionary.
|
||||
StructuredData::Dictionary *dictionary = object_sp->GetAsDictionary();
|
||||
if (!dictionary)
|
||||
return false;
|
||||
|
||||
// Grab the async structured type name (i.e. the feature/plugin name).
|
||||
ConstString type_name;
|
||||
if (!dictionary->GetValueForKeyAsString("type", type_name))
|
||||
return false;
|
||||
|
||||
// Check if there's a plugin registered for this type name.
|
||||
auto find_it = m_structured_data_plugin_map.find(type_name);
|
||||
if (find_it == m_structured_data_plugin_map.end())
|
||||
{
|
||||
// We don't have a mapping for this structured data type.
|
||||
return false;
|
||||
}
|
||||
|
||||
// Route the structured data to the plugin.
|
||||
find_it->second->HandleArrivalOfStructuredData(*this, type_name, object_sp);
|
||||
return true;
|
||||
|
||||
}
|
||||
|
|
|
@ -1,89 +0,0 @@
|
|||
//===-- StructuredDataPlugin.cpp --------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "lldb/Target/StructuredDataPlugin.h"
|
||||
|
||||
#include "lldb/Core/Debugger.h"
|
||||
#include "lldb/Interpreter/CommandInterpreter.h"
|
||||
#include "lldb/Interpreter/CommandObjectMultiword.h"
|
||||
|
||||
using namespace lldb;
|
||||
using namespace lldb_private;
|
||||
|
||||
namespace
|
||||
{
|
||||
class CommandStructuredData : public CommandObjectMultiword
|
||||
{
|
||||
public:
|
||||
CommandStructuredData(CommandInterpreter &interpreter) :
|
||||
CommandObjectMultiword(interpreter,
|
||||
"structured-data",
|
||||
"Parent for per-plugin structured data commands",
|
||||
"plugin structured-data <plugin>")
|
||||
{
|
||||
}
|
||||
|
||||
~CommandStructuredData()
|
||||
{
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
StructuredDataPlugin::StructuredDataPlugin(const ProcessWP &process_wp) :
|
||||
PluginInterface(),
|
||||
m_process_wp(process_wp)
|
||||
{
|
||||
}
|
||||
|
||||
StructuredDataPlugin::~StructuredDataPlugin()
|
||||
{
|
||||
}
|
||||
|
||||
bool
|
||||
StructuredDataPlugin::GetEnabled(const ConstString &type_name) const
|
||||
{
|
||||
// By default, plugins are always enabled. Plugin authors should override
|
||||
// this if there is an enabled/disabled state for their plugin.
|
||||
}
|
||||
|
||||
ProcessSP
|
||||
StructuredDataPlugin::GetProcess() const
|
||||
{
|
||||
return m_process_wp.lock();
|
||||
}
|
||||
|
||||
void
|
||||
StructuredDataPlugin::InitializeBasePluginForDebugger(Debugger &debugger)
|
||||
{
|
||||
// Create our mutliword command anchor if it doesn't already exist.
|
||||
auto &interpreter = debugger.GetCommandInterpreter();
|
||||
if (!interpreter.GetCommandObject("plugin structured-data"))
|
||||
{
|
||||
// Find the parent command.
|
||||
auto parent_command =
|
||||
debugger.GetCommandInterpreter().GetCommandObject("plugin");
|
||||
if (!parent_command)
|
||||
return;
|
||||
|
||||
// Create the structured-data ommand object.
|
||||
auto command_name = "structured-data";
|
||||
auto command_sp =
|
||||
CommandObjectSP(new CommandStructuredData(interpreter));
|
||||
|
||||
// Hook it up under the top-level plugin command.
|
||||
parent_command->LoadSubCommand(command_name,
|
||||
command_sp);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
StructuredDataPlugin::ModulesDidLoad(Process &process, ModuleList &module_list)
|
||||
{
|
||||
// Default implementation does nothing.
|
||||
}
|
|
@ -1,119 +0,0 @@
|
|||
//===-- ThreadPlanCallOnFunctionExit.cpp ------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "lldb/Target/ThreadPlanCallOnFunctionExit.h"
|
||||
|
||||
using namespace lldb;
|
||||
using namespace lldb_private;
|
||||
|
||||
ThreadPlanCallOnFunctionExit::ThreadPlanCallOnFunctionExit(Thread &thread,
|
||||
const Callback
|
||||
&callback) :
|
||||
ThreadPlan(ThreadPlanKind::eKindGeneric, "CallOnFunctionExit",
|
||||
thread,
|
||||
eVoteNoOpinion, eVoteNoOpinion // TODO check with Jim on these
|
||||
),
|
||||
m_callback(callback)
|
||||
{
|
||||
// We are not a user-generated plan.
|
||||
SetIsMasterPlan(false);
|
||||
}
|
||||
|
||||
void
|
||||
ThreadPlanCallOnFunctionExit::DidPush()
|
||||
{
|
||||
// We now want to queue the "step out" thread plan so it executes
|
||||
// and completes.
|
||||
|
||||
// Set stop vote to eVoteNo.
|
||||
m_step_out_threadplan_sp = GetThread()
|
||||
.QueueThreadPlanForStepOut(false, // abort other plans
|
||||
nullptr, // addr_context
|
||||
true, // first instruction
|
||||
true, // stop other threads
|
||||
eVoteNo, // do not say "we're stopping"
|
||||
eVoteNoOpinion, // don't care about
|
||||
// run state broadcasting
|
||||
0, // frame_idx
|
||||
eLazyBoolCalculate // avoid code w/o debinfo
|
||||
);
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// ThreadPlan API
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
void
|
||||
ThreadPlanCallOnFunctionExit::GetDescription(Stream *s, lldb::DescriptionLevel
|
||||
level)
|
||||
{
|
||||
if (!s)
|
||||
return;
|
||||
s->Printf("Running until completion of current function, then making "
|
||||
"callback.");
|
||||
}
|
||||
|
||||
bool
|
||||
ThreadPlanCallOnFunctionExit::ValidatePlan(Stream *error)
|
||||
{
|
||||
// We'll say we're always good since I don't know what would make this
|
||||
// invalid.
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
ThreadPlanCallOnFunctionExit::ShouldStop(Event *event_ptr)
|
||||
{
|
||||
// If this is where we find out that an internal stop came in, then:
|
||||
// Check if the step-out plan completed. If it did, then we want to
|
||||
// run the callback here (our reason for living...)
|
||||
if (m_step_out_threadplan_sp &&
|
||||
m_step_out_threadplan_sp->IsPlanComplete())
|
||||
{
|
||||
m_callback();
|
||||
|
||||
// We no longer need the pointer to the step-out thread plan.
|
||||
m_step_out_threadplan_sp.reset();
|
||||
|
||||
// Indicate that this plan is done and can be discarded.
|
||||
SetPlanComplete();
|
||||
|
||||
// We're done now, but we want to return false so that we
|
||||
// don't cause the thread to really stop.
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
ThreadPlanCallOnFunctionExit::WillStop()
|
||||
{
|
||||
// The code looks like the return value is ignored via ThreadList::
|
||||
// ShouldStop().
|
||||
// This is called when we really are going to stop. We don't care
|
||||
// and don't need to do anything here.
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
ThreadPlanCallOnFunctionExit::DoPlanExplainsStop (Event *event_ptr)
|
||||
{
|
||||
// We don't ever explain a stop. The only stop that is relevant
|
||||
// to us directly is the step_out plan we added to do the heavy lifting
|
||||
// of getting us past the current method.
|
||||
return false;
|
||||
}
|
||||
|
||||
lldb::StateType
|
||||
ThreadPlanCallOnFunctionExit::GetPlanRunState()
|
||||
{
|
||||
// This value doesn't matter - we'll never be the top thread plan, so
|
||||
// nobody will ask us this question.
|
||||
return eStateRunning;
|
||||
}
|
|
@ -7,28 +7,6 @@
|
|||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
23043C9D1D35DBEC00FC25CA /* JSON.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 233B4EA51D2DB54300E98261 /* JSON.cpp */; };
|
||||
23043C9E1D35DBFA00FC25CA /* StringConvert.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 233B4EA81D2DB96A00E98261 /* StringConvert.cpp */; };
|
||||
2307CCCB1D4A5D630016ABC0 /* LogFilterExactMatch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 237821AE1D4917D20028B7A1 /* LogFilterExactMatch.cpp */; };
|
||||
233B4EA71D2DB54300E98261 /* JSON.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 233B4EA51D2DB54300E98261 /* JSON.cpp */; };
|
||||
233B4EA91D2DB96A00E98261 /* StringConvert.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 233B4EA81D2DB96A00E98261 /* StringConvert.cpp */; };
|
||||
23562ED21D3424DF00AB2BD4 /* LogMessageOsLog.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 23562ED01D3424DF00AB2BD4 /* LogMessageOsLog.cpp */; };
|
||||
23562ED31D3424DF00AB2BD4 /* LogMessageOsLog.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 23562ED01D3424DF00AB2BD4 /* LogMessageOsLog.cpp */; };
|
||||
23562ED61D342A5A00AB2BD4 /* ActivityStore.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 23562ED51D342A5A00AB2BD4 /* ActivityStore.cpp */; };
|
||||
23562ED71D342A5A00AB2BD4 /* ActivityStore.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 23562ED51D342A5A00AB2BD4 /* ActivityStore.cpp */; };
|
||||
23562ED91D342B0000AB2BD4 /* LogMessage.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 23562ED81D342B0000AB2BD4 /* LogMessage.cpp */; };
|
||||
23562EDA1D342B0000AB2BD4 /* LogMessage.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 23562ED81D342B0000AB2BD4 /* LogMessage.cpp */; };
|
||||
237821B01D4917D20028B7A1 /* LogFilterExactMatch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 237821AE1D4917D20028B7A1 /* LogFilterExactMatch.cpp */; };
|
||||
23AC04C61D2F41A00072351D /* LogFilter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 23AC04C41D2F41A00072351D /* LogFilter.cpp */; };
|
||||
23AC04C71D2F41A00072351D /* LogFilter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 23AC04C41D2F41A00072351D /* LogFilter.cpp */; };
|
||||
23AC04CA1D2F42250072351D /* LogFilterChain.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 23AC04C81D2F42250072351D /* LogFilterChain.cpp */; };
|
||||
23AC04CB1D2F42250072351D /* LogFilterChain.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 23AC04C81D2F42250072351D /* LogFilterChain.cpp */; };
|
||||
23AC04CF1D2F58AF0072351D /* LogFilterRegex.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 23AC04CD1D2F58AF0072351D /* LogFilterRegex.cpp */; };
|
||||
23AC04D01D2F58AF0072351D /* LogFilterRegex.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 23AC04CD1D2F58AF0072351D /* LogFilterRegex.cpp */; };
|
||||
23AE72E41D25DECF00945BCE /* DarwinLogCollector.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 23AE72E21D25DECF00945BCE /* DarwinLogCollector.cpp */; };
|
||||
23AE72E51D25DEE100945BCE /* DarwinLogCollector.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 23AE72E21D25DECF00945BCE /* DarwinLogCollector.cpp */; };
|
||||
23D1B0291D497E8B00FF831B /* OsLogger.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 23D1B0271D497E8B00FF831B /* OsLogger.cpp */; };
|
||||
23D1B02A1D497E8B00FF831B /* OsLogger.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 23D1B0271D497E8B00FF831B /* OsLogger.cpp */; };
|
||||
264D5D581293835600ED4C01 /* DNBArch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 264D5D571293835600ED4C01 /* DNBArch.cpp */; };
|
||||
2660D9CE1192280900958FBD /* StringExtractor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2660D9CC1192280900958FBD /* StringExtractor.cpp */; };
|
||||
266B5ED11460A68200E43F0A /* DNBArchImplARM64.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 266B5ECF1460A68200E43F0A /* DNBArchImplARM64.cpp */; };
|
||||
|
@ -104,33 +82,6 @@
|
|||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
2307CCCC1D4A5DAE0016ABC0 /* CMakeLists.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = CMakeLists.txt; sourceTree = "<group>"; };
|
||||
233B4EA51D2DB54300E98261 /* JSON.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSON.cpp; sourceTree = "<group>"; };
|
||||
233B4EA61D2DB54300E98261 /* JSON.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSON.h; sourceTree = "<group>"; };
|
||||
233B4EA81D2DB96A00E98261 /* StringConvert.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = StringConvert.cpp; path = ../../../source/Host/common/StringConvert.cpp; sourceTree = "<group>"; };
|
||||
23562ECF1D34110D00AB2BD4 /* DarwinLogTypes.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DarwinLogTypes.h; sourceTree = "<group>"; };
|
||||
23562ED01D3424DF00AB2BD4 /* LogMessageOsLog.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LogMessageOsLog.cpp; sourceTree = "<group>"; };
|
||||
23562ED11D3424DF00AB2BD4 /* LogMessageOsLog.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LogMessageOsLog.h; sourceTree = "<group>"; };
|
||||
23562ED41D3426DD00AB2BD4 /* ActivityStore.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ActivityStore.h; sourceTree = "<group>"; };
|
||||
23562ED51D342A5A00AB2BD4 /* ActivityStore.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ActivityStore.cpp; sourceTree = "<group>"; };
|
||||
23562ED81D342B0000AB2BD4 /* LogMessage.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LogMessage.cpp; sourceTree = "<group>"; };
|
||||
237821AD1D4917D20028B7A1 /* CMakeLists.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = CMakeLists.txt; sourceTree = "<group>"; };
|
||||
237821AE1D4917D20028B7A1 /* LogFilterExactMatch.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LogFilterExactMatch.cpp; sourceTree = "<group>"; };
|
||||
237821AF1D4917D20028B7A1 /* LogFilterExactMatch.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LogFilterExactMatch.h; sourceTree = "<group>"; };
|
||||
23AC04C41D2F41A00072351D /* LogFilter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LogFilter.cpp; sourceTree = "<group>"; };
|
||||
23AC04C51D2F41A00072351D /* LogFilter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LogFilter.h; sourceTree = "<group>"; };
|
||||
23AC04C81D2F42250072351D /* LogFilterChain.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LogFilterChain.cpp; sourceTree = "<group>"; };
|
||||
23AC04C91D2F42250072351D /* LogFilterChain.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LogFilterChain.h; sourceTree = "<group>"; };
|
||||
23AC04CC1D2F42F10072351D /* DarwinLogInterfaces.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DarwinLogInterfaces.h; sourceTree = "<group>"; };
|
||||
23AC04CD1D2F58AF0072351D /* LogFilterRegex.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LogFilterRegex.cpp; sourceTree = "<group>"; };
|
||||
23AC04CE1D2F58AF0072351D /* LogFilterRegex.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LogFilterRegex.h; sourceTree = "<group>"; };
|
||||
23AC04D11D2F60130072351D /* LogMessage.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = LogMessage.h; sourceTree = "<group>"; };
|
||||
23AE72E21D25DECF00945BCE /* DarwinLogCollector.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DarwinLogCollector.cpp; sourceTree = "<group>"; };
|
||||
23AE72E31D25DECF00945BCE /* DarwinLogCollector.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DarwinLogCollector.h; sourceTree = "<group>"; };
|
||||
23AE72E61D25DEFB00945BCE /* ActivityStreamSPI.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ActivityStreamSPI.h; sourceTree = "<group>"; };
|
||||
23CF6F5E1D28A3760088ADC9 /* DarwinLogEvent.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DarwinLogEvent.h; sourceTree = "<group>"; };
|
||||
23D1B0271D497E8B00FF831B /* OsLogger.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = OsLogger.cpp; sourceTree = "<group>"; };
|
||||
23D1B0281D497E8B00FF831B /* OsLogger.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OsLogger.h; sourceTree = "<group>"; };
|
||||
260828DE0CBAF7F400F95054 /* DNBRuntimeAction.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DNBRuntimeAction.h; sourceTree = "<group>"; };
|
||||
260E7331114BFFE600D1DFB3 /* DNBThreadResumeActions.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DNBThreadResumeActions.cpp; sourceTree = "<group>"; };
|
||||
260E7332114BFFE600D1DFB3 /* DNBThreadResumeActions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DNBThreadResumeActions.h; sourceTree = "<group>"; };
|
||||
|
@ -266,34 +217,6 @@
|
|||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
23AC04C31D2F3E9A0072351D /* DarwinLog */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
237821AD1D4917D20028B7A1 /* CMakeLists.txt */,
|
||||
23562ED41D3426DD00AB2BD4 /* ActivityStore.h */,
|
||||
23562ED51D342A5A00AB2BD4 /* ActivityStore.cpp */,
|
||||
23AE72E61D25DEFB00945BCE /* ActivityStreamSPI.h */,
|
||||
23AE72E31D25DECF00945BCE /* DarwinLogCollector.h */,
|
||||
23AE72E21D25DECF00945BCE /* DarwinLogCollector.cpp */,
|
||||
23CF6F5E1D28A3760088ADC9 /* DarwinLogEvent.h */,
|
||||
23AC04CC1D2F42F10072351D /* DarwinLogInterfaces.h */,
|
||||
23562ECF1D34110D00AB2BD4 /* DarwinLogTypes.h */,
|
||||
23AC04C51D2F41A00072351D /* LogFilter.h */,
|
||||
23AC04C41D2F41A00072351D /* LogFilter.cpp */,
|
||||
23AC04C91D2F42250072351D /* LogFilterChain.h */,
|
||||
23AC04C81D2F42250072351D /* LogFilterChain.cpp */,
|
||||
237821AF1D4917D20028B7A1 /* LogFilterExactMatch.h */,
|
||||
237821AE1D4917D20028B7A1 /* LogFilterExactMatch.cpp */,
|
||||
23AC04CE1D2F58AF0072351D /* LogFilterRegex.h */,
|
||||
23AC04CD1D2F58AF0072351D /* LogFilterRegex.cpp */,
|
||||
23AC04D11D2F60130072351D /* LogMessage.h */,
|
||||
23562ED81D342B0000AB2BD4 /* LogMessage.cpp */,
|
||||
23562ED11D3424DF00AB2BD4 /* LogMessageOsLog.h */,
|
||||
23562ED01D3424DF00AB2BD4 /* LogMessageOsLog.cpp */,
|
||||
);
|
||||
path = DarwinLog;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
266B5ECE1460A68200E43F0A /* arm64 */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
|
@ -350,8 +273,6 @@
|
|||
26C637E20C71334A0024798E /* DNBRegisterInfo.cpp */,
|
||||
260E7332114BFFE600D1DFB3 /* DNBThreadResumeActions.h */,
|
||||
260E7331114BFFE600D1DFB3 /* DNBThreadResumeActions.cpp */,
|
||||
233B4EA61D2DB54300E98261 /* JSON.h */,
|
||||
233B4EA51D2DB54300E98261 /* JSON.cpp */,
|
||||
264F679A1B2F9EB200140093 /* JSONGenerator.h */,
|
||||
AF67AC000D34604D0022D128 /* PseudoTerminal.h */,
|
||||
AF67ABFF0D34604D0022D128 /* PseudoTerminal.cpp */,
|
||||
|
@ -360,7 +281,6 @@
|
|||
26C637FE0C71334A0024798E /* PThreadEvent.cpp */,
|
||||
26C638000C71334A0024798E /* PThreadMutex.h */,
|
||||
2672DBEE0EEF446700E92059 /* PThreadMutex.cpp */,
|
||||
233B4EA81D2DB96A00E98261 /* StringConvert.cpp */,
|
||||
26C638020C71334A0024798E /* SysSignal.h */,
|
||||
26C638010C71334A0024798E /* SysSignal.cpp */,
|
||||
26C638060C71334A0024798E /* TTYState.h */,
|
||||
|
@ -395,13 +315,13 @@
|
|||
26C637E60C71334A0024798E /* MacOSX */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
23AC04C31D2F3E9A0072351D /* DarwinLog */,
|
||||
AF0934BA18E12B92005A11FD /* Genealogy.h */,
|
||||
AF0934BB18E12B92005A11FD /* GenealogySPI.h */,
|
||||
2695DD920D3EBFF6007E4CA2 /* CFBundle.h */,
|
||||
2695DD910D3EBFF6007E4CA2 /* CFBundle.cpp */,
|
||||
2695DD9A0D3EC160007E4CA2 /* CFString.h */,
|
||||
2695DD9B0D3EC160007E4CA2 /* CFString.cpp */,
|
||||
26C637E70C71334A0024798E /* CFUtils.h */,
|
||||
2307CCCC1D4A5DAE0016ABC0 /* CMakeLists.txt */,
|
||||
2675D41C0CCEB6CF000F49AF /* arm */,
|
||||
266B5ECE1460A68200E43F0A /* arm64 */,
|
||||
26C637E90C71334A0024798E /* i386 */,
|
||||
|
@ -411,8 +331,6 @@
|
|||
4971AE7113D10F4F00649E37 /* HasAVX.s */,
|
||||
26C637E80C71334A0024798E /* dbgnub-mig.defs */,
|
||||
AFEC3363194A8B0B00FF05C6 /* Genealogy.cpp */,
|
||||
AF0934BA18E12B92005A11FD /* Genealogy.h */,
|
||||
AF0934BB18E12B92005A11FD /* GenealogySPI.h */,
|
||||
26C637EF0C71334A0024798E /* MachException.h */,
|
||||
26C637EE0C71334A0024798E /* MachException.cpp */,
|
||||
26C637F10C71334A0024798E /* MachProcess.h */,
|
||||
|
@ -427,8 +345,6 @@
|
|||
26C637F80C71334A0024798E /* MachVMRegion.cpp */,
|
||||
26B67DE00EE9BC30006C8BC0 /* MachTask.h */,
|
||||
26B67DE10EE9BC30006C8BC0 /* MachTask.mm */,
|
||||
23D1B0281D497E8B00FF831B /* OsLogger.h */,
|
||||
23D1B0271D497E8B00FF831B /* OsLogger.cpp */,
|
||||
9457ECF61419864100DFE7D8 /* stack_logging.h */,
|
||||
);
|
||||
path = MacOSX;
|
||||
|
@ -574,47 +490,35 @@
|
|||
26CE05A9115C36250022F371 /* debugserver.cpp in Sources */,
|
||||
26CE05AA115C36260022F371 /* RNBContext.cpp in Sources */,
|
||||
26CE05AB115C36270022F371 /* RNBServices.cpp in Sources */,
|
||||
23D1B0291D497E8B00FF831B /* OsLogger.cpp in Sources */,
|
||||
26CE05AC115C36280022F371 /* RNBSocket.cpp in Sources */,
|
||||
26CE05AD115C36280022F371 /* RNBRemote.cpp in Sources */,
|
||||
26CE05AE115C36320022F371 /* dbgnub-mig.defs in Sources */,
|
||||
26CE05B0115C36340022F371 /* MachException.cpp in Sources */,
|
||||
26CE05B1115C36350022F371 /* MachProcess.mm in Sources */,
|
||||
26CE05B2115C36360022F371 /* MachThread.cpp in Sources */,
|
||||
233B4EA71D2DB54300E98261 /* JSON.cpp in Sources */,
|
||||
26CE05B3115C36370022F371 /* MachThreadList.cpp in Sources */,
|
||||
26CE05B4115C36380022F371 /* MachVMMemory.cpp in Sources */,
|
||||
26CE05B5115C36380022F371 /* MachVMRegion.cpp in Sources */,
|
||||
26CE05B6115C36390022F371 /* MachTask.mm in Sources */,
|
||||
26CE05B7115C363B0022F371 /* DNB.cpp in Sources */,
|
||||
AFEC3364194A8B0B00FF05C6 /* Genealogy.cpp in Sources */,
|
||||
23AC04CF1D2F58AF0072351D /* LogFilterRegex.cpp in Sources */,
|
||||
233B4EA91D2DB96A00E98261 /* StringConvert.cpp in Sources */,
|
||||
23562ED21D3424DF00AB2BD4 /* LogMessageOsLog.cpp in Sources */,
|
||||
26CE05B8115C363C0022F371 /* DNBBreakpoint.cpp in Sources */,
|
||||
26CE05B9115C363D0022F371 /* DNBDataRef.cpp in Sources */,
|
||||
23AC04CA1D2F42250072351D /* LogFilterChain.cpp in Sources */,
|
||||
23562ED61D342A5A00AB2BD4 /* ActivityStore.cpp in Sources */,
|
||||
26CE05BA115C363E0022F371 /* DNBLog.cpp in Sources */,
|
||||
23AC04C61D2F41A00072351D /* LogFilter.cpp in Sources */,
|
||||
26CE05BB115C363F0022F371 /* DNBRegisterInfo.cpp in Sources */,
|
||||
26CE05BC115C36420022F371 /* PThreadEvent.cpp in Sources */,
|
||||
26CE05BD115C36430022F371 /* PThreadMutex.cpp in Sources */,
|
||||
26CE05BE115C36440022F371 /* SysSignal.cpp in Sources */,
|
||||
23AE72E41D25DECF00945BCE /* DarwinLogCollector.cpp in Sources */,
|
||||
26CE05BF115C364D0022F371 /* DNBArchImplX86_64.cpp in Sources */,
|
||||
26CE05C0115C364F0022F371 /* DNBArchImplI386.cpp in Sources */,
|
||||
26CE05C1115C36510022F371 /* DNBArchImpl.cpp in Sources */,
|
||||
26CE05C2115C36550022F371 /* DNBArchImpl.cpp in Sources */,
|
||||
26CE05C5115C36590022F371 /* CFBundle.cpp in Sources */,
|
||||
26CE05C3115C36580022F371 /* CFString.cpp in Sources */,
|
||||
26CE05C4115C36590022F371 /* CFData.cpp in Sources */,
|
||||
23562ED91D342B0000AB2BD4 /* LogMessage.cpp in Sources */,
|
||||
26CE05C5115C36590022F371 /* CFBundle.cpp in Sources */,
|
||||
26CE05F1115C387C0022F371 /* PseudoTerminal.cpp in Sources */,
|
||||
2660D9CE1192280900958FBD /* StringExtractor.cpp in Sources */,
|
||||
264D5D581293835600ED4C01 /* DNBArch.cpp in Sources */,
|
||||
4971AE7213D10F4F00649E37 /* HasAVX.s in Sources */,
|
||||
237821B01D4917D20028B7A1 /* LogFilterExactMatch.cpp in Sources */,
|
||||
266B5ED11460A68200E43F0A /* DNBArchImplARM64.cpp in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
|
@ -626,49 +530,37 @@
|
|||
456F67461AD46CE9002850C2 /* DNBError.cpp in Sources */,
|
||||
456F67471AD46CE9002850C2 /* DNBThreadResumeActions.cpp in Sources */,
|
||||
456F67481AD46CE9002850C2 /* debugserver.cpp in Sources */,
|
||||
23043C9D1D35DBEC00FC25CA /* JSON.cpp in Sources */,
|
||||
456F67491AD46CE9002850C2 /* RNBContext.cpp in Sources */,
|
||||
23D1B02A1D497E8B00FF831B /* OsLogger.cpp in Sources */,
|
||||
456F674A1AD46CE9002850C2 /* RNBServices.cpp in Sources */,
|
||||
456F674B1AD46CE9002850C2 /* RNBSocket.cpp in Sources */,
|
||||
456F674C1AD46CE9002850C2 /* RNBRemote.cpp in Sources */,
|
||||
456F674D1AD46CE9002850C2 /* dbgnub-mig.defs in Sources */,
|
||||
456F674E1AD46CE9002850C2 /* MachException.cpp in Sources */,
|
||||
456F674F1AD46CE9002850C2 /* MachProcess.mm in Sources */,
|
||||
2307CCCB1D4A5D630016ABC0 /* LogFilterExactMatch.cpp in Sources */,
|
||||
456F67501AD46CE9002850C2 /* MachThread.cpp in Sources */,
|
||||
456F67511AD46CE9002850C2 /* MachThreadList.cpp in Sources */,
|
||||
456F67521AD46CE9002850C2 /* MachVMMemory.cpp in Sources */,
|
||||
456F67531AD46CE9002850C2 /* MachVMRegion.cpp in Sources */,
|
||||
23562ED71D342A5A00AB2BD4 /* ActivityStore.cpp in Sources */,
|
||||
456F67541AD46CE9002850C2 /* MachTask.mm in Sources */,
|
||||
456F67551AD46CE9002850C2 /* DNB.cpp in Sources */,
|
||||
456F67561AD46CE9002850C2 /* Genealogy.cpp in Sources */,
|
||||
456F67571AD46CE9002850C2 /* DNBBreakpoint.cpp in Sources */,
|
||||
456F67581AD46CE9002850C2 /* DNBDataRef.cpp in Sources */,
|
||||
456F67591AD46CE9002850C2 /* DNBLog.cpp in Sources */,
|
||||
23562ED31D3424DF00AB2BD4 /* LogMessageOsLog.cpp in Sources */,
|
||||
456F675A1AD46CE9002850C2 /* DNBRegisterInfo.cpp in Sources */,
|
||||
456F675B1AD46CE9002850C2 /* PThreadEvent.cpp in Sources */,
|
||||
456F675C1AD46CE9002850C2 /* PThreadMutex.cpp in Sources */,
|
||||
456F675D1AD46CE9002850C2 /* SysSignal.cpp in Sources */,
|
||||
23AE72E51D25DEE100945BCE /* DarwinLogCollector.cpp in Sources */,
|
||||
456F675E1AD46CE9002850C2 /* DNBArchImplX86_64.cpp in Sources */,
|
||||
23562EDA1D342B0000AB2BD4 /* LogMessage.cpp in Sources */,
|
||||
456F675F1AD46CE9002850C2 /* DNBArchImplI386.cpp in Sources */,
|
||||
456F67601AD46CE9002850C2 /* DNBArchImpl.cpp in Sources */,
|
||||
23AC04C71D2F41A00072351D /* LogFilter.cpp in Sources */,
|
||||
23043C9E1D35DBFA00FC25CA /* StringConvert.cpp in Sources */,
|
||||
456F67611AD46CE9002850C2 /* DNBArchImpl.cpp in Sources */,
|
||||
456F67621AD46CE9002850C2 /* CFString.cpp in Sources */,
|
||||
456F67631AD46CE9002850C2 /* CFData.cpp in Sources */,
|
||||
23AC04CB1D2F42250072351D /* LogFilterChain.cpp in Sources */,
|
||||
456F67641AD46CE9002850C2 /* CFBundle.cpp in Sources */,
|
||||
456F67651AD46CE9002850C2 /* PseudoTerminal.cpp in Sources */,
|
||||
456F67661AD46CE9002850C2 /* StringExtractor.cpp in Sources */,
|
||||
456F67671AD46CE9002850C2 /* DNBArch.cpp in Sources */,
|
||||
456F67681AD46CE9002850C2 /* HasAVX.s in Sources */,
|
||||
23AC04D01D2F58AF0072351D /* LogFilterRegex.cpp in Sources */,
|
||||
456F67691AD46CE9002850C2 /* DNBArchImplARM64.cpp in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
|
@ -708,8 +600,6 @@
|
|||
"LLDB_COMPRESSION_CFLAGS[sdk=macosx10.11]" = "-DHAVE_LIBCOMPRESSION=1";
|
||||
LLDB_COMPRESSION_LDFLAGS = "";
|
||||
"LLDB_COMPRESSION_LDFLAGS[sdk=macosx10.11]" = "-weak-lcompression";
|
||||
LLDB_OS_LOG_CFLAGS = "-DLLDB_USE_OS_LOG=$(LLDB_USE_OS_LOG)";
|
||||
LLDB_USE_OS_LOG = 0;
|
||||
LLDB_ZLIB_CFLAGS = "-DHAVE_LIBZ=1";
|
||||
LLDB_ZLIB_LDFLAGS = "-lz";
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.10;
|
||||
|
@ -752,8 +642,6 @@
|
|||
"LLDB_COMPRESSION_CFLAGS[sdk=macosx10.11]" = "-DHAVE_LIBCOMPRESSION=1";
|
||||
LLDB_COMPRESSION_LDFLAGS = "";
|
||||
"LLDB_COMPRESSION_LDFLAGS[sdk=macosx10.11]" = "-weak-lcompression";
|
||||
LLDB_OS_LOG_CFLAGS = "-DLLDB_USE_OS_LOG=$(LLDB_USE_OS_LOG)";
|
||||
LLDB_USE_OS_LOG = 0;
|
||||
LLDB_ZLIB_CFLAGS = "-DHAVE_LIBZ=1";
|
||||
LLDB_ZLIB_LDFLAGS = "-lz";
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.10;
|
||||
|
@ -794,8 +682,6 @@
|
|||
"LLDB_COMPRESSION_CFLAGS[sdk=macosx10.11]" = "-DHAVE_LIBCOMPRESSION=1";
|
||||
LLDB_COMPRESSION_LDFLAGS = "";
|
||||
"LLDB_COMPRESSION_LDFLAGS[sdk=macosx10.11]" = "-weak-lcompression";
|
||||
LLDB_OS_LOG_CFLAGS = "-DLLDB_USE_OS_LOG=$(LLDB_USE_OS_LOG)";
|
||||
LLDB_USE_OS_LOG = 1;
|
||||
LLDB_ZLIB_CFLAGS = "-DHAVE_LIBZ=1";
|
||||
LLDB_ZLIB_LDFLAGS = "-lz";
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.10;
|
||||
|
@ -857,7 +743,6 @@
|
|||
"-DDT_VARIANT_$(DT_VARIANT)",
|
||||
"$(LLDB_COMPRESSION_CFLAGS)",
|
||||
"$(LLDB_ZLIB_CFLAGS)",
|
||||
"$(LLDB_OS_LOG_CFLAGS)",
|
||||
);
|
||||
"OTHER_CFLAGS[sdk=iphoneos*]" = (
|
||||
"-Wparentheses",
|
||||
|
@ -867,7 +752,6 @@
|
|||
"-DOS_OBJECT_USE_OBJC=0",
|
||||
"$(LLDB_COMPRESSION_CFLAGS)",
|
||||
"$(LLDB_ZLIB_CFLAGS)",
|
||||
"$(LLDB_OS_LOG_CFLAGS)",
|
||||
);
|
||||
"OTHER_CPLUSPLUSFLAGS[sdk=iphoneos*][arch=*]" = "$(OTHER_CFLAGS)";
|
||||
OTHER_LDFLAGS = "";
|
||||
|
@ -959,7 +843,6 @@
|
|||
"-DDT_VARIANT_$(DT_VARIANT)",
|
||||
"$(LLDB_COMPRESSION_CFLAGS)",
|
||||
"$(LLDB_ZLIB_CFLAGS)",
|
||||
"$(LLDB_OS_LOG_CFLAGS)",
|
||||
);
|
||||
"OTHER_CFLAGS[sdk=iphoneos*][arch=*]" = (
|
||||
"-Wparentheses",
|
||||
|
@ -969,7 +852,6 @@
|
|||
"-DOS_OBJECT_USE_OBJC=0",
|
||||
"$(LLDB_COMPRESSION_CFLAGS)",
|
||||
"$(LLDB_ZLIB_CFLAGS)",
|
||||
"$(LLDB_OS_LOG_CFLAGS)",
|
||||
);
|
||||
"OTHER_CPLUSPLUSFLAGS[sdk=iphoneos*][arch=*]" = "$(OTHER_CFLAGS)";
|
||||
OTHER_LDFLAGS = "";
|
||||
|
@ -1060,7 +942,6 @@
|
|||
"-DDT_VARIANT_$(DT_VARIANT)",
|
||||
"$(LLDB_COMPRESSION_CFLAGS)",
|
||||
"$(LLDB_ZLIB_CFLAGS)",
|
||||
"$(LLDB_OS_LOG_CFLAGS)",
|
||||
);
|
||||
"OTHER_CFLAGS[sdk=iphoneos*][arch=*]" = (
|
||||
"-Wparentheses",
|
||||
|
@ -1070,7 +951,6 @@
|
|||
"-DOS_OBJECT_USE_OBJC=0",
|
||||
"$(LLDB_COMPRESSION_CFLAGS)",
|
||||
"$(LLDB_ZLIB_CFLAGS)",
|
||||
"$(LLDB_OS_LOG_CFLAGS)",
|
||||
);
|
||||
"OTHER_CPLUSPLUSFLAGS[sdk=iphoneos*][arch=*]" = "$(OTHER_CFLAGS)";
|
||||
OTHER_LDFLAGS = "";
|
||||
|
@ -1170,7 +1050,6 @@
|
|||
"-Wparentheses",
|
||||
"-DOS_OBJECT_USE_OBJC=0",
|
||||
"-DDEBUGSERVER_PROGRAM_SYMBOL=debugserver_nonui",
|
||||
"$(LLDB_OS_LOG_CFLAGS)",
|
||||
);
|
||||
"OTHER_CPLUSPLUSFLAGS[sdk=iphoneos*][arch=*]" = "$(OTHER_CFLAGS)";
|
||||
OTHER_LDFLAGS = "";
|
||||
|
@ -1240,7 +1119,6 @@
|
|||
"-Wparentheses",
|
||||
"-DOS_OBJECT_USE_OBJC=0",
|
||||
"-DDEBUGSERVER_PROGRAM_SYMBOL=debugserver_nonui",
|
||||
"$(LLDB_OS_LOG_CFLAGS)",
|
||||
);
|
||||
"OTHER_CPLUSPLUSFLAGS[sdk=iphoneos*][arch=*]" = "$(OTHER_CFLAGS)";
|
||||
OTHER_LDFLAGS = "";
|
||||
|
@ -1306,13 +1184,11 @@
|
|||
"$(LLDB_COMPRESSION_CFLAGS)",
|
||||
"$(LLDB_ZLIB_CFLAGS)",
|
||||
"-DDEBUGSERVER_PROGRAM_SYMBOL=debugserver_nonui",
|
||||
"$(LLDB_OS_LOG_CFLAGS)",
|
||||
);
|
||||
"OTHER_CFLAGS[sdk=iphoneos*][arch=*]" = (
|
||||
"-Wparentheses",
|
||||
"-DOS_OBJECT_USE_OBJC=0",
|
||||
"-DDEBUGSERVER_PROGRAM_SYMBOL=debugserver_nonui",
|
||||
"$(LLDB_OS_LOG_CFLAGS)",
|
||||
);
|
||||
"OTHER_CPLUSPLUSFLAGS[sdk=iphoneos*][arch=*]" = "$(OTHER_CFLAGS)";
|
||||
OTHER_LDFLAGS = "";
|
||||
|
@ -1379,15 +1255,12 @@
|
|||
"-Wparentheses",
|
||||
"$(LLDB_ENERGY_CFLAGS)",
|
||||
"-DDEBUGSERVER_PROGRAM_SYMBOL=debugserver_nonui",
|
||||
"$(LLDB_OS_LOG_CFLAGS)",
|
||||
);
|
||||
"OTHER_CFLAGS[sdk=iphoneos*]" = (
|
||||
"-Wparentheses",
|
||||
"-DOS_OBJECT_USE_OBJC=0",
|
||||
"-DDEBUGSERVER_PROGRAM_SYMBOL=debugserver_nonui",
|
||||
"$(LLDB_OS_LOG_CFLAGS)",
|
||||
);
|
||||
OTHER_CPLUSPLUSFLAGS = "$(OTHER_CFLAGS)";
|
||||
"OTHER_CPLUSPLUSFLAGS[sdk=iphoneos*][arch=*]" = "$(OTHER_CFLAGS)";
|
||||
"OTHER_LDFLAGS[sdk=iphoneos*][arch=*]" = (
|
||||
"-framework",
|
||||
|
@ -1439,8 +1312,6 @@
|
|||
GCC_WARN_UNINITIALIZED_AUTOS = YES;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
LLDB_OS_LOG_CFLAGS = "-DLLDB_USE_OS_LOG=$(LLDB_USE_OS_LOG)";
|
||||
LLDB_USE_OS_LOG = 0;
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.10;
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
SDKROOT = macosx.internal;
|
||||
|
@ -1503,7 +1374,6 @@
|
|||
"-DDT_VARIANT_$(DT_VARIANT)",
|
||||
"$(LLDB_COMPRESSION_CFLAGS)",
|
||||
"$(LLDB_ZLIB_CFLAGS)",
|
||||
"$(LLDB_OS_LOG_CFLAGS)",
|
||||
);
|
||||
"OTHER_CFLAGS[sdk=iphoneos*][arch=*]" = (
|
||||
"-Wparentheses",
|
||||
|
@ -1513,7 +1383,6 @@
|
|||
"-DOS_OBJECT_USE_OBJC=0",
|
||||
"$(LLDB_COMPRESSION_CFLAGS)",
|
||||
"$(LLDB_ZLIB_CFLAGS)",
|
||||
"$(LLDB_OS_LOG_CFLAGS)",
|
||||
);
|
||||
"OTHER_CPLUSPLUSFLAGS[sdk=iphoneos*][arch=*]" = "$(OTHER_CFLAGS)";
|
||||
"OTHER_LDFLAGS[sdk=iphoneos*][arch=*]" = (
|
||||
|
@ -1582,8 +1451,6 @@
|
|||
GCC_WARN_UNINITIALIZED_AUTOS = YES;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
LLDB_OS_LOG_CFLAGS = "-DLLDB_USE_OS_LOG=$(LLDB_USE_OS_LOG)";
|
||||
LLDB_USE_OS_LOG = 0;
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.10;
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
SDKROOT = macosx.internal;
|
||||
|
@ -1645,7 +1512,6 @@
|
|||
"$(LLDB_ENERGY_CFLAGS)",
|
||||
"$(LLDB_COMPRESSION_CFLAGS)",
|
||||
"$(LLDB_ZLIB_CFLAGS)",
|
||||
"$(LLDB_OS_LOG_CFLAGS)",
|
||||
);
|
||||
"OTHER_CFLAGS[sdk=iphoneos*][arch=*]" = (
|
||||
"-Wparentheses",
|
||||
|
@ -1655,7 +1521,6 @@
|
|||
"-DOS_OBJECT_USE_OBJC=0",
|
||||
"$(LLDB_COMPRESSION_CFLAGS)",
|
||||
"$(LLDB_ZLIB_CFLAGS)",
|
||||
"$(LLDB_OS_LOG_CFLAGS)",
|
||||
);
|
||||
"OTHER_CPLUSPLUSFLAGS[sdk=iphoneos*][arch=*]" = "$(OTHER_CFLAGS)";
|
||||
"OTHER_LDFLAGS[sdk=iphoneos*][arch=*]" = (
|
||||
|
@ -1730,13 +1595,11 @@
|
|||
"-Wparentheses",
|
||||
"$(LLDB_ENERGY_CFLAGS)",
|
||||
"-DDEBUGSERVER_PROGRAM_SYMBOL=debugserver_nonui",
|
||||
"$(LLDB_OS_LOG_CFLAGS)",
|
||||
);
|
||||
"OTHER_CFLAGS[sdk=iphoneos*][arch=*]" = (
|
||||
"-Wparentheses",
|
||||
"-DOS_OBJECT_USE_OBJC=0",
|
||||
"-DDEBUGSERVER_PROGRAM_SYMBOL=debugserver_nonui",
|
||||
"$(LLDB_OS_LOG_CFLAGS)",
|
||||
);
|
||||
"OTHER_CPLUSPLUSFLAGS[sdk=iphoneos*][arch=*]" = "$(OTHER_CFLAGS)";
|
||||
"OTHER_LDFLAGS[sdk=iphoneos*][arch=*]" = (
|
||||
|
@ -1806,8 +1669,6 @@
|
|||
GCC_WARN_UNINITIALIZED_AUTOS = YES;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
LLDB_OS_LOG_CFLAGS = "-DLLDB_USE_OS_LOG=$(LLDB_USE_OS_LOG)";
|
||||
LLDB_USE_OS_LOG = 0;
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.10;
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
SDKROOT = macosx.internal;
|
||||
|
@ -1860,7 +1721,6 @@
|
|||
"-DDT_VARIANT_$(DT_VARIANT)",
|
||||
"$(LLDB_COMPRESSION_CFLAGS)",
|
||||
"$(LLDB_ZLIB_CFLAGS)",
|
||||
"$(LLDB_OS_LOG_CFLAGS)",
|
||||
);
|
||||
"OTHER_CFLAGS[sdk=iphoneos*][arch=*]" = (
|
||||
"-Wparentheses",
|
||||
|
@ -1870,7 +1730,6 @@
|
|||
"-DOS_OBJECT_USE_OBJC=0",
|
||||
"$(LLDB_COMPRESSION_CFLAGS)",
|
||||
"$(LLDB_ZLIB_CFLAGS)",
|
||||
"$(LLDB_OS_LOG_CFLAGS)",
|
||||
);
|
||||
"OTHER_CPLUSPLUSFLAGS[sdk=iphoneos*][arch=*]" = "$(OTHER_CFLAGS)";
|
||||
OTHER_LDFLAGS = "";
|
||||
|
@ -1939,8 +1798,6 @@
|
|||
GCC_WARN_UNINITIALIZED_AUTOS = YES;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
LLDB_OS_LOG_CFLAGS = "-DLLDB_USE_OS_LOG=$(LLDB_USE_OS_LOG)";
|
||||
LLDB_USE_OS_LOG = 0;
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.10;
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
SDKROOT = macosx.internal;
|
||||
|
@ -1994,7 +1851,6 @@
|
|||
"-DDT_VARIANT_$(DT_VARIANT)",
|
||||
"$(LLDB_COMPRESSION_CFLAGS)",
|
||||
"$(LLDB_ZLIB_CFLAGS)",
|
||||
"$(LLDB_OS_LOG_CFLAGS)",
|
||||
);
|
||||
"OTHER_CFLAGS[sdk=iphoneos*][arch=*]" = (
|
||||
"-Wparentheses",
|
||||
|
@ -2004,7 +1860,6 @@
|
|||
"-DOS_OBJECT_USE_OBJC=0",
|
||||
"$(LLDB_COMPRESSION_CFLAGS)",
|
||||
"$(LLDB_ZLIB_CFLAGS)",
|
||||
"$(LLDB_OS_LOG_CFLAGS)",
|
||||
);
|
||||
"OTHER_CPLUSPLUSFLAGS[sdk=iphoneos*][arch=*]" = "$(OTHER_CFLAGS)";
|
||||
"OTHER_LDFLAGS[sdk=iphoneos*][arch=*]" = (
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
include_directories(${CMAKE_CURRENT_BINARY_DIR}/..)
|
||||
include_directories(${LLDB_SOURCE_DIR}/source)
|
||||
include_directories(MacOSX/DarwinLog)
|
||||
|
||||
if (CMAKE_SYSTEM_NAME MATCHES "Darwin")
|
||||
include_directories(MacOSX)
|
||||
|
@ -43,11 +42,6 @@ add_library(lldbDebugserverCommon
|
|||
DNBLog.cpp
|
||||
DNBRegisterInfo.cpp
|
||||
DNBThreadResumeActions.cpp
|
||||
JSON.cpp
|
||||
# JSON reader depends on the following LLDB-common files
|
||||
${LLDB_SOURCE_DIR}/source/Host/common/StringConvert.cpp
|
||||
${LLDB_SOURCE_DIR}/source/Utility/StringExtractor.cpp
|
||||
# end JSON reader dependencies
|
||||
libdebugserver.cpp
|
||||
PseudoTerminal.cpp
|
||||
PThreadEvent.cpp
|
||||
|
|
|
@ -41,7 +41,6 @@
|
|||
#endif
|
||||
#endif
|
||||
|
||||
#include "MacOSX/DarwinLog/DarwinLogCollector.h"
|
||||
#include "MacOSX/MachProcess.h"
|
||||
#include "MacOSX/MachTask.h"
|
||||
#include "MacOSX/Genealogy.h"
|
||||
|
@ -1869,12 +1868,6 @@ DNBProcessGetAvailableProfileData (nub_process_t pid, char *buf, nub_size_t buf_
|
|||
return 0;
|
||||
}
|
||||
|
||||
DarwinLogEventVector
|
||||
DNBProcessGetAvailableDarwinLogEvents(nub_process_t pid)
|
||||
{
|
||||
return DarwinLogCollector::GetEventsForProcess(pid);
|
||||
}
|
||||
|
||||
nub_size_t
|
||||
DNBProcessGetStopCount (nub_process_t pid)
|
||||
{
|
||||
|
|
|
@ -14,7 +14,6 @@
|
|||
#ifndef __DNB_h__
|
||||
#define __DNB_h__
|
||||
|
||||
#include "MacOSX/DarwinLog/DarwinLogEvent.h"
|
||||
#include "MacOSX/Genealogy.h"
|
||||
#include "MacOSX/ThreadInfo.h"
|
||||
#include "JSONGenerator.h"
|
||||
|
@ -82,8 +81,6 @@ nub_bool_t DNBProcessMemoryDeallocate (nub_process_t pid, nub_addr_t addr)
|
|||
int DNBProcessMemoryRegionInfo (nub_process_t pid, nub_addr_t addr, DNBRegionInfo *region_info) DNB_EXPORT;
|
||||
std::string DNBProcessGetProfileData (nub_process_t pid, DNBProfileDataScanType scanType) DNB_EXPORT;
|
||||
nub_bool_t DNBProcessSetEnableAsyncProfiling (nub_process_t pid, nub_bool_t enable, uint64_t interval_usec, DNBProfileDataScanType scan_type) DNB_EXPORT;
|
||||
DarwinLogEventVector DNBProcessGetAvailableDarwinLogEvents(nub_process_t pid);
|
||||
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// Process status
|
||||
|
|
|
@ -142,7 +142,6 @@ enum
|
|||
#define LOG_WATCHPOINTS (1u << 11)
|
||||
#define LOG_STEP (1u << 12)
|
||||
#define LOG_TASK (1u << 13)
|
||||
#define LOG_DARWIN_LOG (1u << 14)
|
||||
#define LOG_LO_USER (1u << 16)
|
||||
#define LOG_HI_USER (1u << 31)
|
||||
#define LOG_ALL 0xFFFFFFFFu
|
||||
|
|
|
@ -1,746 +0,0 @@
|
|||
//===--------------------- JSON.cpp -----------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "JSON.h"
|
||||
|
||||
// C includes
|
||||
#include <assert.h>
|
||||
#include <limits.h>
|
||||
|
||||
// C++ includes
|
||||
#include <iomanip>
|
||||
#include <sstream>
|
||||
#include "lldb/Host/StringConvert.h"
|
||||
|
||||
using namespace lldb_private;
|
||||
|
||||
std::string
|
||||
JSONString::json_string_quote_metachars (const std::string &s)
|
||||
{
|
||||
if (s.find('"') == std::string::npos)
|
||||
return s;
|
||||
|
||||
std::string output;
|
||||
const size_t s_size = s.size();
|
||||
const char *s_chars = s.c_str();
|
||||
for (size_t i = 0; i < s_size; i++)
|
||||
{
|
||||
unsigned char ch = *(s_chars + i);
|
||||
if (ch == '"')
|
||||
{
|
||||
output.push_back ('\\');
|
||||
}
|
||||
output.push_back (ch);
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
JSONString::JSONString () :
|
||||
JSONValue(JSONValue::Kind::String),
|
||||
m_data()
|
||||
{
|
||||
}
|
||||
|
||||
JSONString::JSONString (const char* s) :
|
||||
JSONValue(JSONValue::Kind::String),
|
||||
m_data(s ? s : "")
|
||||
{
|
||||
}
|
||||
|
||||
JSONString::JSONString (const std::string& s) :
|
||||
JSONValue(JSONValue::Kind::String),
|
||||
m_data(s)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
JSONString::Write (std::ostream& s)
|
||||
{
|
||||
s << "\"" << json_string_quote_metachars(m_data).c_str() <<"\"";
|
||||
}
|
||||
|
||||
uint64_t
|
||||
JSONNumber::GetAsUnsigned() const
|
||||
{
|
||||
switch (m_data_type)
|
||||
{
|
||||
case DataType::Unsigned:
|
||||
return m_data.m_unsigned;
|
||||
case DataType::Signed:
|
||||
return (uint64_t)m_data.m_signed;
|
||||
case DataType::Double:
|
||||
return (uint64_t)m_data.m_double;
|
||||
}
|
||||
assert("Unhandled data type");
|
||||
}
|
||||
|
||||
int64_t
|
||||
JSONNumber::GetAsSigned() const
|
||||
{
|
||||
switch (m_data_type)
|
||||
{
|
||||
case DataType::Unsigned:
|
||||
return (int64_t)m_data.m_unsigned;
|
||||
case DataType::Signed:
|
||||
return m_data.m_signed;
|
||||
case DataType::Double:
|
||||
return (int64_t)m_data.m_double;
|
||||
}
|
||||
assert("Unhandled data type");
|
||||
}
|
||||
|
||||
double
|
||||
JSONNumber::GetAsDouble() const
|
||||
{
|
||||
switch (m_data_type)
|
||||
{
|
||||
case DataType::Unsigned:
|
||||
return (double)m_data.m_unsigned;
|
||||
case DataType::Signed:
|
||||
return (double)m_data.m_signed;
|
||||
case DataType::Double:
|
||||
return m_data.m_double;
|
||||
}
|
||||
assert("Unhandled data type");
|
||||
}
|
||||
|
||||
void
|
||||
JSONNumber::Write (std::ostream& s)
|
||||
{
|
||||
switch (m_data_type)
|
||||
{
|
||||
case DataType::Unsigned:
|
||||
s << m_data.m_unsigned;
|
||||
break;
|
||||
case DataType::Signed:
|
||||
s << m_data.m_signed;
|
||||
break;
|
||||
case DataType::Double:
|
||||
// Set max precision to emulate %g.
|
||||
s << std::setprecision(std::numeric_limits<double>::digits10 + 1);
|
||||
s << m_data.m_double;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
JSONTrue::JSONTrue () :
|
||||
JSONValue(JSONValue::Kind::True)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
JSONTrue::Write(std::ostream& s)
|
||||
{
|
||||
s << "true";
|
||||
}
|
||||
|
||||
JSONFalse::JSONFalse () :
|
||||
JSONValue(JSONValue::Kind::False)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
JSONFalse::Write(std::ostream& s)
|
||||
{
|
||||
s << "false";
|
||||
}
|
||||
|
||||
JSONNull::JSONNull () :
|
||||
JSONValue(JSONValue::Kind::Null)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
JSONNull::Write(std::ostream& s)
|
||||
{
|
||||
s << "null";
|
||||
}
|
||||
|
||||
JSONObject::JSONObject () :
|
||||
JSONValue(JSONValue::Kind::Object)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
JSONObject::Write (std::ostream& s)
|
||||
{
|
||||
bool first = true;
|
||||
s << '{';
|
||||
auto iter = m_elements.begin(), end = m_elements.end();
|
||||
for (;iter != end; iter++)
|
||||
{
|
||||
if (first)
|
||||
first = false;
|
||||
else
|
||||
s << ',';
|
||||
JSONString key(iter->first);
|
||||
JSONValue::SP value(iter->second);
|
||||
key.Write(s);
|
||||
s << ':';
|
||||
value->Write(s);
|
||||
}
|
||||
s << '}';
|
||||
}
|
||||
|
||||
bool
|
||||
JSONObject::SetObject (const std::string& key,
|
||||
JSONValue::SP value)
|
||||
{
|
||||
if (key.empty() || nullptr == value.get())
|
||||
return false;
|
||||
m_elements[key] = value;
|
||||
return true;
|
||||
}
|
||||
|
||||
JSONValue::SP
|
||||
JSONObject::GetObject (const std::string& key) const
|
||||
{
|
||||
auto iter = m_elements.find(key), end = m_elements.end();
|
||||
if (iter == end)
|
||||
return JSONValue::SP();
|
||||
return iter->second;
|
||||
}
|
||||
|
||||
bool
|
||||
JSONObject::GetObjectAsBool (const std::string& key, bool& value) const
|
||||
{
|
||||
auto value_sp = GetObject(key);
|
||||
if (!value_sp)
|
||||
{
|
||||
// The given key doesn't exist, so we have no value.
|
||||
return false;
|
||||
}
|
||||
|
||||
if (JSONTrue::classof(value_sp.get()))
|
||||
{
|
||||
// We have the value, and it is true.
|
||||
value = true;
|
||||
return true;
|
||||
}
|
||||
else if (JSONFalse::classof(value_sp.get()))
|
||||
{
|
||||
// We have the value, and it is false.
|
||||
value = false;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// We don't have a valid bool value for the given key.
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
JSONObject::GetObjectAsString (const std::string& key, std::string& value) const
|
||||
{
|
||||
auto value_sp = GetObject(key);
|
||||
if (!value_sp)
|
||||
{
|
||||
// The given key doesn't exist, so we have no value.
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!JSONString::classof(value_sp.get()))
|
||||
return false;
|
||||
|
||||
value = static_cast<JSONString*>(value_sp.get())->GetData();
|
||||
return true;
|
||||
}
|
||||
|
||||
JSONArray::JSONArray () :
|
||||
JSONValue(JSONValue::Kind::Array)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
JSONArray::Write (std::ostream& s)
|
||||
{
|
||||
bool first = true;
|
||||
s << '[';
|
||||
auto iter = m_elements.begin(), end = m_elements.end();
|
||||
for (;iter != end; iter++)
|
||||
{
|
||||
if (first)
|
||||
first = false;
|
||||
else
|
||||
s << ',';
|
||||
(*iter)->Write(s);
|
||||
}
|
||||
s << ']';
|
||||
}
|
||||
|
||||
bool
|
||||
JSONArray::SetObject (Index i,
|
||||
JSONValue::SP value)
|
||||
{
|
||||
if (value.get() == nullptr)
|
||||
return false;
|
||||
if (i < m_elements.size())
|
||||
{
|
||||
m_elements[i] = value;
|
||||
return true;
|
||||
}
|
||||
if (i == m_elements.size())
|
||||
{
|
||||
m_elements.push_back(value);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
JSONArray::AppendObject (JSONValue::SP value)
|
||||
{
|
||||
if (value.get() == nullptr)
|
||||
return false;
|
||||
m_elements.push_back(value);
|
||||
return true;
|
||||
}
|
||||
|
||||
JSONValue::SP
|
||||
JSONArray::GetObject (Index i)
|
||||
{
|
||||
if (i < m_elements.size())
|
||||
return m_elements[i];
|
||||
return JSONValue::SP();
|
||||
}
|
||||
|
||||
JSONArray::Size
|
||||
JSONArray::GetNumElements ()
|
||||
{
|
||||
return m_elements.size();
|
||||
}
|
||||
|
||||
|
||||
JSONParser::JSONParser (const char *cstr) :
|
||||
StringExtractor(cstr)
|
||||
{
|
||||
}
|
||||
|
||||
JSONParser::Token
|
||||
JSONParser::GetToken (std::string &value)
|
||||
{
|
||||
std::ostringstream error;
|
||||
|
||||
value.clear();
|
||||
SkipSpaces ();
|
||||
const uint64_t start_index = m_index;
|
||||
const char ch = GetChar();
|
||||
switch (ch)
|
||||
{
|
||||
case '{': return Token::ObjectStart;
|
||||
case '}': return Token::ObjectEnd;
|
||||
case '[': return Token::ArrayStart;
|
||||
case ']': return Token::ArrayEnd;
|
||||
case ',': return Token::Comma;
|
||||
case ':': return Token::Colon;
|
||||
case '\0': return Token::EndOfFile;
|
||||
case 't':
|
||||
if (GetChar() == 'r')
|
||||
if (GetChar() == 'u')
|
||||
if (GetChar() == 'e')
|
||||
return Token::True;
|
||||
break;
|
||||
|
||||
case 'f':
|
||||
if (GetChar() == 'a')
|
||||
if (GetChar() == 'l')
|
||||
if (GetChar() == 's')
|
||||
if (GetChar() == 'e')
|
||||
return Token::False;
|
||||
break;
|
||||
|
||||
case 'n':
|
||||
if (GetChar() == 'u')
|
||||
if (GetChar() == 'l')
|
||||
if (GetChar() == 'l')
|
||||
return Token::Null;
|
||||
break;
|
||||
|
||||
case '"':
|
||||
{
|
||||
while (1)
|
||||
{
|
||||
bool was_escaped = false;
|
||||
int escaped_ch = GetEscapedChar(was_escaped);
|
||||
if (escaped_ch == -1)
|
||||
{
|
||||
error << "error: an error occurred getting a character from offset " <<start_index;
|
||||
value = std::move(error.str());
|
||||
return Token::Error;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
const bool is_end_quote = escaped_ch == '"';
|
||||
const bool is_null = escaped_ch == 0;
|
||||
if (was_escaped || (!is_end_quote && !is_null))
|
||||
{
|
||||
if (CHAR_MIN <= escaped_ch && escaped_ch <= CHAR_MAX)
|
||||
{
|
||||
value.append(1, (char)escaped_ch);
|
||||
}
|
||||
else
|
||||
{
|
||||
error << "error: wide character support is needed for unicode character 0x" << std::setprecision(4) << std::hex << escaped_ch;
|
||||
error << " at offset " << start_index;
|
||||
value = std::move(error.str());
|
||||
return Token::Error;
|
||||
}
|
||||
}
|
||||
else if (is_end_quote)
|
||||
{
|
||||
return Token::String;
|
||||
}
|
||||
else if (is_null)
|
||||
{
|
||||
value = "error: missing end quote for string";
|
||||
return Token::Error;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case '-':
|
||||
case '0':
|
||||
case '1':
|
||||
case '2':
|
||||
case '3':
|
||||
case '4':
|
||||
case '5':
|
||||
case '6':
|
||||
case '7':
|
||||
case '8':
|
||||
case '9':
|
||||
{
|
||||
bool done = false;
|
||||
bool got_decimal_point = false;
|
||||
uint64_t exp_index = 0;
|
||||
bool got_int_digits = (ch >= '0') && (ch <= '9');
|
||||
bool got_frac_digits = false;
|
||||
bool got_exp_digits = false;
|
||||
while (!done)
|
||||
{
|
||||
const char next_ch = PeekChar();
|
||||
switch (next_ch)
|
||||
{
|
||||
case '0':
|
||||
case '1':
|
||||
case '2':
|
||||
case '3':
|
||||
case '4':
|
||||
case '5':
|
||||
case '6':
|
||||
case '7':
|
||||
case '8':
|
||||
case '9':
|
||||
if (exp_index != 0)
|
||||
{
|
||||
got_exp_digits = true;
|
||||
}
|
||||
else if (got_decimal_point)
|
||||
{
|
||||
got_frac_digits = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
got_int_digits = true;
|
||||
}
|
||||
++m_index; // Skip this character
|
||||
break;
|
||||
|
||||
case '.':
|
||||
if (got_decimal_point)
|
||||
{
|
||||
error << "error: extra decimal point found at offset " << start_index;
|
||||
value = std::move(error.str());
|
||||
return Token::Error;
|
||||
}
|
||||
else
|
||||
{
|
||||
got_decimal_point = true;
|
||||
++m_index; // Skip this character
|
||||
}
|
||||
break;
|
||||
|
||||
case 'e':
|
||||
case 'E':
|
||||
if (exp_index != 0)
|
||||
{
|
||||
error << "error: extra exponent character found at offset " << start_index;
|
||||
value = std::move(error.str());
|
||||
return Token::Error;
|
||||
}
|
||||
else
|
||||
{
|
||||
exp_index = m_index;
|
||||
++m_index; // Skip this character
|
||||
}
|
||||
break;
|
||||
|
||||
case '+':
|
||||
case '-':
|
||||
// The '+' and '-' can only come after an exponent character...
|
||||
if (exp_index == m_index - 1)
|
||||
{
|
||||
++m_index; // Skip the exponent sign character
|
||||
}
|
||||
else
|
||||
{
|
||||
error << "error: unexpected " << next_ch << " character at offset " << start_index;
|
||||
value = std::move(error.str());
|
||||
return Token::Error;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
done = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (m_index > start_index)
|
||||
{
|
||||
value = m_packet.substr(start_index, m_index - start_index);
|
||||
if (got_decimal_point)
|
||||
{
|
||||
if (exp_index != 0)
|
||||
{
|
||||
// We have an exponent, make sure we got exponent digits
|
||||
if (got_exp_digits)
|
||||
{
|
||||
return Token::Float;
|
||||
}
|
||||
else
|
||||
{
|
||||
error << "error: got exponent character but no exponent digits at offset in float value \"" << value.c_str() << "\"";
|
||||
value = std::move(error.str());
|
||||
return Token::Error;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// No exponent, but we need at least one decimal after the decimal point
|
||||
if (got_frac_digits)
|
||||
{
|
||||
return Token::Float;
|
||||
}
|
||||
else
|
||||
{
|
||||
error << "error: no digits after decimal point \"" << value.c_str() << "\"";
|
||||
value = std::move(error.str());
|
||||
return Token::Error;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// No decimal point
|
||||
if (got_int_digits)
|
||||
{
|
||||
// We need at least some integer digits to make an integer
|
||||
return Token::Integer;
|
||||
}
|
||||
else
|
||||
{
|
||||
error << "error: no digits negate sign \"" << value.c_str() << "\"";
|
||||
value = std::move(error.str());
|
||||
return Token::Error;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
error << "error: invalid number found at offset " << start_index;
|
||||
value = std::move(error.str());
|
||||
return Token::Error;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
error << "error: failed to parse token at offset " << start_index << " (around character '" << ch << "')";
|
||||
value = std::move(error.str());
|
||||
return Token::Error;
|
||||
}
|
||||
|
||||
int
|
||||
JSONParser::GetEscapedChar(bool &was_escaped)
|
||||
{
|
||||
was_escaped = false;
|
||||
const char ch = GetChar();
|
||||
if (ch == '\\')
|
||||
{
|
||||
was_escaped = true;
|
||||
const char ch2 = GetChar();
|
||||
switch (ch2)
|
||||
{
|
||||
case '"':
|
||||
case '\\':
|
||||
case '/':
|
||||
default:
|
||||
break;
|
||||
|
||||
case 'b': return '\b';
|
||||
case 'f': return '\f';
|
||||
case 'n': return '\n';
|
||||
case 'r': return '\r';
|
||||
case 't': return '\t';
|
||||
case 'u':
|
||||
{
|
||||
const int hi_byte = DecodeHexU8();
|
||||
const int lo_byte = DecodeHexU8();
|
||||
if (hi_byte >=0 && lo_byte >= 0)
|
||||
return hi_byte << 8 | lo_byte;
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return ch2;
|
||||
}
|
||||
return ch;
|
||||
}
|
||||
|
||||
JSONValue::SP
|
||||
JSONParser::ParseJSONObject ()
|
||||
{
|
||||
// The "JSONParser::Token::ObjectStart" token should have already been consumed
|
||||
// by the time this function is called
|
||||
std::unique_ptr<JSONObject> dict_up(new JSONObject());
|
||||
|
||||
std::string value;
|
||||
std::string key;
|
||||
while (1)
|
||||
{
|
||||
JSONParser::Token token = GetToken(value);
|
||||
|
||||
if (token == JSONParser::Token::String)
|
||||
{
|
||||
key.swap(value);
|
||||
token = GetToken(value);
|
||||
if (token == JSONParser::Token::Colon)
|
||||
{
|
||||
JSONValue::SP value_sp = ParseJSONValue();
|
||||
if (value_sp)
|
||||
dict_up->SetObject(key, value_sp);
|
||||
else
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (token == JSONParser::Token::ObjectEnd)
|
||||
{
|
||||
return JSONValue::SP(dict_up.release());
|
||||
}
|
||||
else if (token == JSONParser::Token::Comma)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
return JSONValue::SP();
|
||||
}
|
||||
|
||||
JSONValue::SP
|
||||
JSONParser::ParseJSONArray ()
|
||||
{
|
||||
// The "JSONParser::Token::ObjectStart" token should have already been consumed
|
||||
// by the time this function is called
|
||||
std::unique_ptr<JSONArray> array_up(new JSONArray());
|
||||
|
||||
std::string value;
|
||||
std::string key;
|
||||
while (1)
|
||||
{
|
||||
JSONValue::SP value_sp = ParseJSONValue();
|
||||
if (value_sp)
|
||||
array_up->AppendObject(value_sp);
|
||||
else
|
||||
break;
|
||||
|
||||
JSONParser::Token token = GetToken(value);
|
||||
if (token == JSONParser::Token::Comma)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
else if (token == JSONParser::Token::ArrayEnd)
|
||||
{
|
||||
return JSONValue::SP(array_up.release());
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
return JSONValue::SP();
|
||||
}
|
||||
|
||||
JSONValue::SP
|
||||
JSONParser::ParseJSONValue ()
|
||||
{
|
||||
std::string value;
|
||||
const JSONParser::Token token = GetToken(value);
|
||||
switch (token)
|
||||
{
|
||||
case JSONParser::Token::ObjectStart:
|
||||
return ParseJSONObject();
|
||||
|
||||
case JSONParser::Token::ArrayStart:
|
||||
return ParseJSONArray();
|
||||
|
||||
case JSONParser::Token::Integer:
|
||||
{
|
||||
if (value.front() == '-')
|
||||
{
|
||||
bool success = false;
|
||||
int64_t sval = StringConvert::ToSInt64(value.c_str(), 0, 0, &success);
|
||||
if (success)
|
||||
return JSONValue::SP(new JSONNumber(sval));
|
||||
}
|
||||
else
|
||||
{
|
||||
bool success = false;
|
||||
uint64_t uval = StringConvert::ToUInt64(value.c_str(), 0, 0, &success);
|
||||
if (success)
|
||||
return JSONValue::SP(new JSONNumber(uval));
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case JSONParser::Token::Float:
|
||||
{
|
||||
bool success = false;
|
||||
double val = StringConvert::ToDouble(value.c_str(), 0.0, &success);
|
||||
if (success)
|
||||
return JSONValue::SP(new JSONNumber(val));
|
||||
}
|
||||
break;
|
||||
|
||||
case JSONParser::Token::String:
|
||||
return JSONValue::SP(new JSONString(value));
|
||||
|
||||
case JSONParser::Token::True:
|
||||
return JSONValue::SP(new JSONTrue());
|
||||
|
||||
case JSONParser::Token::False:
|
||||
return JSONValue::SP(new JSONFalse());
|
||||
|
||||
case JSONParser::Token::Null:
|
||||
return JSONValue::SP(new JSONNull());
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return JSONValue::SP();
|
||||
|
||||
}
|
|
@ -1,382 +0,0 @@
|
|||
//===---------------------JSON.h --------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef utility_JSON_h_
|
||||
#define utility_JSON_h_
|
||||
|
||||
// This cross-project usage is fine as StringExtractor.h is entirely
|
||||
// self-contained.
|
||||
#include "lldb/Utility/StringExtractor.h"
|
||||
|
||||
// C includes
|
||||
#include <inttypes.h>
|
||||
#include <stdint.h>
|
||||
|
||||
// C++ includes
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <ostream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
class JSONValue
|
||||
{
|
||||
public:
|
||||
virtual void
|
||||
Write (std::ostream& s) = 0;
|
||||
|
||||
typedef std::shared_ptr<JSONValue> SP;
|
||||
|
||||
enum class Kind
|
||||
{
|
||||
String,
|
||||
Number,
|
||||
True,
|
||||
False,
|
||||
Null,
|
||||
Object,
|
||||
Array
|
||||
};
|
||||
|
||||
JSONValue (Kind k) :
|
||||
m_kind(k)
|
||||
{}
|
||||
|
||||
Kind
|
||||
GetKind() const
|
||||
{
|
||||
return m_kind;
|
||||
}
|
||||
|
||||
virtual
|
||||
~JSONValue () = default;
|
||||
|
||||
private:
|
||||
const Kind m_kind;
|
||||
};
|
||||
|
||||
class JSONString : public JSONValue
|
||||
{
|
||||
public:
|
||||
JSONString ();
|
||||
JSONString (const char* s);
|
||||
JSONString (const std::string& s);
|
||||
|
||||
JSONString (const JSONString& s) = delete;
|
||||
JSONString&
|
||||
operator = (const JSONString& s) = delete;
|
||||
|
||||
void
|
||||
Write(std::ostream& s) override;
|
||||
|
||||
typedef std::shared_ptr<JSONString> SP;
|
||||
|
||||
std::string
|
||||
GetData () { return m_data; }
|
||||
|
||||
static bool classof(const JSONValue *V)
|
||||
{
|
||||
return V->GetKind() == JSONValue::Kind::String;
|
||||
}
|
||||
|
||||
~JSONString() override = default;
|
||||
|
||||
private:
|
||||
|
||||
static std::string
|
||||
json_string_quote_metachars (const std::string&);
|
||||
|
||||
std::string m_data;
|
||||
};
|
||||
|
||||
class JSONNumber : public JSONValue
|
||||
{
|
||||
public:
|
||||
typedef std::shared_ptr<JSONNumber> SP;
|
||||
|
||||
// We cretae a constructor for all integer and floating point type with using templates and
|
||||
// SFINAE to avoid having ambiguous overloads because of the implicit type promotion. If we
|
||||
// would have constructors only with int64_t, uint64_t and double types then constructing a
|
||||
// JSONNumber from an int32_t (or any other similar type) would fail to compile.
|
||||
|
||||
template <typename T,
|
||||
typename std::enable_if<std::is_integral<T>::value &&
|
||||
std::is_unsigned<T>::value>::type* = nullptr>
|
||||
explicit JSONNumber (T u) :
|
||||
JSONValue(JSONValue::Kind::Number),
|
||||
m_data_type(DataType::Unsigned)
|
||||
{
|
||||
m_data.m_unsigned = u;
|
||||
}
|
||||
|
||||
template <typename T,
|
||||
typename std::enable_if<std::is_integral<T>::value &&
|
||||
std::is_signed<T>::value>::type* = nullptr>
|
||||
explicit JSONNumber (T s) :
|
||||
JSONValue(JSONValue::Kind::Number),
|
||||
m_data_type(DataType::Signed)
|
||||
{
|
||||
m_data.m_signed = s;
|
||||
}
|
||||
|
||||
template <typename T,
|
||||
typename std::enable_if<std::is_floating_point<T>::value>::type* = nullptr>
|
||||
explicit JSONNumber (T d) :
|
||||
JSONValue(JSONValue::Kind::Number),
|
||||
m_data_type(DataType::Double)
|
||||
{
|
||||
m_data.m_double = d;
|
||||
}
|
||||
|
||||
~JSONNumber() override = default;
|
||||
|
||||
JSONNumber (const JSONNumber& s) = delete;
|
||||
JSONNumber&
|
||||
operator = (const JSONNumber& s) = delete;
|
||||
|
||||
void
|
||||
Write(std::ostream& s) override;
|
||||
|
||||
uint64_t
|
||||
GetAsUnsigned() const;
|
||||
|
||||
int64_t
|
||||
GetAsSigned() const;
|
||||
|
||||
double
|
||||
GetAsDouble() const;
|
||||
|
||||
static bool classof(const JSONValue *V)
|
||||
{
|
||||
return V->GetKind() == JSONValue::Kind::Number;
|
||||
}
|
||||
|
||||
private:
|
||||
enum class DataType : uint8_t
|
||||
{
|
||||
Unsigned,
|
||||
Signed,
|
||||
Double
|
||||
} m_data_type;
|
||||
|
||||
union
|
||||
{
|
||||
uint64_t m_unsigned;
|
||||
int64_t m_signed;
|
||||
double m_double;
|
||||
} m_data;
|
||||
};
|
||||
|
||||
class JSONTrue : public JSONValue
|
||||
{
|
||||
public:
|
||||
JSONTrue ();
|
||||
|
||||
JSONTrue (const JSONTrue& s) = delete;
|
||||
JSONTrue&
|
||||
operator = (const JSONTrue& s) = delete;
|
||||
|
||||
void
|
||||
Write(std::ostream& s) override;
|
||||
|
||||
typedef std::shared_ptr<JSONTrue> SP;
|
||||
|
||||
static bool classof(const JSONValue *V)
|
||||
{
|
||||
return V->GetKind() == JSONValue::Kind::True;
|
||||
}
|
||||
|
||||
~JSONTrue() override = default;
|
||||
};
|
||||
|
||||
class JSONFalse : public JSONValue
|
||||
{
|
||||
public:
|
||||
JSONFalse ();
|
||||
|
||||
JSONFalse (const JSONFalse& s) = delete;
|
||||
JSONFalse&
|
||||
operator = (const JSONFalse& s) = delete;
|
||||
|
||||
void
|
||||
Write(std::ostream& s) override;
|
||||
|
||||
typedef std::shared_ptr<JSONFalse> SP;
|
||||
|
||||
static bool classof(const JSONValue *V)
|
||||
{
|
||||
return V->GetKind() == JSONValue::Kind::False;
|
||||
}
|
||||
|
||||
~JSONFalse() override = default;
|
||||
};
|
||||
|
||||
class JSONNull : public JSONValue
|
||||
{
|
||||
public:
|
||||
JSONNull ();
|
||||
|
||||
JSONNull (const JSONNull& s) = delete;
|
||||
JSONNull&
|
||||
operator = (const JSONNull& s) = delete;
|
||||
|
||||
void
|
||||
Write(std::ostream& s) override;
|
||||
|
||||
typedef std::shared_ptr<JSONNull> SP;
|
||||
|
||||
static bool classof(const JSONValue *V)
|
||||
{
|
||||
return V->GetKind() == JSONValue::Kind::Null;
|
||||
}
|
||||
|
||||
~JSONNull() override = default;
|
||||
};
|
||||
|
||||
class JSONObject : public JSONValue
|
||||
{
|
||||
public:
|
||||
JSONObject ();
|
||||
|
||||
JSONObject (const JSONObject& s) = delete;
|
||||
JSONObject&
|
||||
operator = (const JSONObject& s) = delete;
|
||||
|
||||
void
|
||||
Write(std::ostream& s) override;
|
||||
|
||||
typedef std::shared_ptr<JSONObject> SP;
|
||||
|
||||
static bool classof(const JSONValue *V)
|
||||
{
|
||||
return V->GetKind() == JSONValue::Kind::Object;
|
||||
}
|
||||
|
||||
bool
|
||||
SetObject (const std::string& key,
|
||||
JSONValue::SP value);
|
||||
|
||||
JSONValue::SP
|
||||
GetObject (const std::string& key) const;
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
/// Return keyed value as bool
|
||||
///
|
||||
/// @param[in] key
|
||||
/// The value of the key to lookup
|
||||
///
|
||||
/// @param[out] value
|
||||
/// The value of the key as a bool. Undefined if the key doesn't
|
||||
/// exist or if the key is not either true or false.
|
||||
///
|
||||
/// @return
|
||||
/// true if the key existed as was a bool value; false otherwise.
|
||||
/// Note the return value is *not* the value of the bool, use
|
||||
/// \b value for that.
|
||||
// -------------------------------------------------------------------------
|
||||
bool
|
||||
GetObjectAsBool (const std::string& key, bool& value) const;
|
||||
|
||||
bool
|
||||
GetObjectAsString (const std::string& key, std::string& value) const;
|
||||
|
||||
~JSONObject() override = default;
|
||||
|
||||
private:
|
||||
typedef std::map<std::string, JSONValue::SP> Map;
|
||||
typedef Map::iterator Iterator;
|
||||
Map m_elements;
|
||||
};
|
||||
|
||||
class JSONArray : public JSONValue
|
||||
{
|
||||
public:
|
||||
JSONArray ();
|
||||
|
||||
JSONArray (const JSONArray& s) = delete;
|
||||
JSONArray&
|
||||
operator = (const JSONArray& s) = delete;
|
||||
|
||||
void
|
||||
Write(std::ostream& s) override;
|
||||
|
||||
typedef std::shared_ptr<JSONArray> SP;
|
||||
|
||||
static bool classof(const JSONValue *V)
|
||||
{
|
||||
return V->GetKind() == JSONValue::Kind::Array;
|
||||
}
|
||||
|
||||
private:
|
||||
typedef std::vector<JSONValue::SP> Vector;
|
||||
typedef Vector::iterator Iterator;
|
||||
typedef Vector::size_type Index;
|
||||
typedef Vector::size_type Size;
|
||||
|
||||
public:
|
||||
bool
|
||||
SetObject (Index i,
|
||||
JSONValue::SP value);
|
||||
|
||||
bool
|
||||
AppendObject (JSONValue::SP value);
|
||||
|
||||
JSONValue::SP
|
||||
GetObject (Index i);
|
||||
|
||||
Size
|
||||
GetNumElements ();
|
||||
|
||||
~JSONArray() override = default;
|
||||
|
||||
Vector m_elements;
|
||||
};
|
||||
|
||||
class JSONParser : public StringExtractor
|
||||
{
|
||||
public:
|
||||
enum Token
|
||||
{
|
||||
Invalid,
|
||||
Error,
|
||||
ObjectStart,
|
||||
ObjectEnd,
|
||||
ArrayStart,
|
||||
ArrayEnd,
|
||||
Comma,
|
||||
Colon,
|
||||
String,
|
||||
Integer,
|
||||
Float,
|
||||
True,
|
||||
False,
|
||||
Null,
|
||||
EndOfFile
|
||||
};
|
||||
|
||||
JSONParser (const char *cstr);
|
||||
|
||||
int
|
||||
GetEscapedChar (bool &was_escaped);
|
||||
|
||||
Token
|
||||
GetToken (std::string &value);
|
||||
|
||||
JSONValue::SP
|
||||
ParseJSONValue ();
|
||||
|
||||
protected:
|
||||
JSONValue::SP
|
||||
ParseJSONObject ();
|
||||
|
||||
JSONValue::SP
|
||||
ParseJSONArray ();
|
||||
};
|
||||
|
||||
#endif // utility_JSON_h_
|
|
@ -3,7 +3,6 @@
|
|||
add_subdirectory(i386)
|
||||
#add_subdirectory(ppc)
|
||||
add_subdirectory(x86_64)
|
||||
add_subdirectory(DarwinLog)
|
||||
|
||||
include_directories(..)
|
||||
|
||||
|
@ -33,7 +32,6 @@ set(DEBUGSERVER_USED_LIBS
|
|||
lldbUtility
|
||||
lldbDebugserverMacOSX_I386
|
||||
lldbDebugserverMacOSX_X86_64
|
||||
lldbDebugserverMacOSX_DarwinLog
|
||||
)
|
||||
|
||||
add_lldb_executable(debugserver
|
||||
|
@ -48,7 +46,6 @@ add_lldb_executable(debugserver
|
|||
MachThreadList.cpp
|
||||
MachVMMemory.cpp
|
||||
MachVMRegion.cpp
|
||||
OsLogger.cpp
|
||||
${generated_mach_interfaces}
|
||||
${DEBUGSERVER_VERS_GENERATED_FILE}
|
||||
)
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue