Imported Upstream version 6.10.0.49

Former-commit-id: 1d6753294b2993e1fbf92de9366bb9544db4189b
This commit is contained in:
Xamarin Public Jenkins (auto-signing)
2020-01-16 16:38:04 +00:00
parent d94e79959b
commit 468663ddbb
48518 changed files with 2789335 additions and 61176 deletions

View File

@ -0,0 +1,14 @@
//===-- ActivityStore.cpp ---------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "ActivityStore.h"
ActivityStore::ActivityStore() {}
ActivityStore::~ActivityStore() {}

View File

@ -0,0 +1,30 @@
//===-- ActivityStore.h -----------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef ActivityStore_h
#define ActivityStore_h
#include <string>
#include "ActivityStreamSPI.h"
class ActivityStore {
public:
virtual ~ActivityStore();
virtual const char *GetActivityForID(os_activity_id_t activity_id) const = 0;
virtual std::string
GetActivityChainForID(os_activity_id_t activity_id) const = 0;
protected:
ActivityStore();
};
#endif /* ActivityStore_h */

View File

@ -0,0 +1,191 @@
//===-- ActivityStreamAPI.h -------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef ActivityStreamSPI_h
#define ActivityStreamSPI_h
#include <sys/time.h>
#include <xpc/xpc.h>
#define OS_ACTIVITY_MAX_CALLSTACK 32
// Enums
enum {
OS_ACTIVITY_STREAM_PROCESS_ONLY = 0x00000001,
OS_ACTIVITY_STREAM_SKIP_DECODE = 0x00000002,
OS_ACTIVITY_STREAM_PAYLOAD = 0x00000004,
OS_ACTIVITY_STREAM_HISTORICAL = 0x00000008,
OS_ACTIVITY_STREAM_CALLSTACK = 0x00000010,
OS_ACTIVITY_STREAM_DEBUG = 0x00000020,
OS_ACTIVITY_STREAM_BUFFERED = 0x00000040,
OS_ACTIVITY_STREAM_NO_SENSITIVE = 0x00000080,
OS_ACTIVITY_STREAM_INFO = 0x00000100,
OS_ACTIVITY_STREAM_PROMISCUOUS = 0x00000200,
OS_ACTIVITY_STREAM_PRECISE_TIMESTAMPS = 0x00000200
};
typedef uint32_t os_activity_stream_flag_t;
enum {
OS_ACTIVITY_STREAM_TYPE_ACTIVITY_CREATE = 0x0201,
OS_ACTIVITY_STREAM_TYPE_ACTIVITY_TRANSITION = 0x0202,
OS_ACTIVITY_STREAM_TYPE_ACTIVITY_USERACTION = 0x0203,
OS_ACTIVITY_STREAM_TYPE_TRACE_MESSAGE = 0x0300,
OS_ACTIVITY_STREAM_TYPE_LOG_MESSAGE = 0x0400,
OS_ACTIVITY_STREAM_TYPE_LEGACY_LOG_MESSAGE = 0x0480,
OS_ACTIVITY_STREAM_TYPE_SIGNPOST_BEGIN = 0x0601,
OS_ACTIVITY_STREAM_TYPE_SIGNPOST_END = 0x0602,
OS_ACTIVITY_STREAM_TYPE_SIGNPOST_EVENT = 0x0603,
OS_ACTIVITY_STREAM_TYPE_STATEDUMP_EVENT = 0x0A00,
};
typedef uint32_t os_activity_stream_type_t;
enum {
OS_ACTIVITY_STREAM_EVENT_STARTED = 1,
OS_ACTIVITY_STREAM_EVENT_STOPPED = 2,
OS_ACTIVITY_STREAM_EVENT_FAILED = 3,
OS_ACTIVITY_STREAM_EVENT_CHUNK_STARTED = 4,
OS_ACTIVITY_STREAM_EVENT_CHUNK_FINISHED = 5,
};
typedef uint32_t os_activity_stream_event_t;
// Types
typedef uint64_t os_activity_id_t;
typedef struct os_activity_stream_s *os_activity_stream_t;
typedef struct os_activity_stream_entry_s *os_activity_stream_entry_t;
#define OS_ACTIVITY_STREAM_COMMON() \
uint64_t trace_id; \
uint64_t timestamp; \
uint64_t thread; \
const uint8_t *image_uuid; \
const char *image_path; \
struct timeval tv_gmt; \
struct timezone tz; \
uint32_t offset
typedef struct os_activity_stream_common_s {
OS_ACTIVITY_STREAM_COMMON();
} * os_activity_stream_common_t;
struct os_activity_create_s {
OS_ACTIVITY_STREAM_COMMON();
const char *name;
os_activity_id_t creator_aid;
uint64_t unique_pid;
};
struct os_activity_transition_s {
OS_ACTIVITY_STREAM_COMMON();
os_activity_id_t transition_id;
};
typedef struct os_log_message_s {
OS_ACTIVITY_STREAM_COMMON();
const char *format;
const uint8_t *buffer;
size_t buffer_sz;
const uint8_t *privdata;
size_t privdata_sz;
const char *subsystem;
const char *category;
uint32_t oversize_id;
uint8_t ttl;
bool persisted;
} * os_log_message_t;
typedef struct os_trace_message_v2_s {
OS_ACTIVITY_STREAM_COMMON();
const char *format;
const void *buffer;
size_t bufferLen;
xpc_object_t __unsafe_unretained payload;
} * os_trace_message_v2_t;
typedef struct os_activity_useraction_s {
OS_ACTIVITY_STREAM_COMMON();
const char *action;
bool persisted;
} * os_activity_useraction_t;
typedef struct os_signpost_s {
OS_ACTIVITY_STREAM_COMMON();
const char *format;
const uint8_t *buffer;
size_t buffer_sz;
const uint8_t *privdata;
size_t privdata_sz;
const char *subsystem;
const char *category;
uint64_t duration_nsec;
uint32_t callstack_depth;
uint64_t callstack[OS_ACTIVITY_MAX_CALLSTACK];
} * os_signpost_t;
typedef struct os_activity_statedump_s {
OS_ACTIVITY_STREAM_COMMON();
char *message;
size_t message_size;
char image_path_buffer[PATH_MAX];
} * os_activity_statedump_t;
struct os_activity_stream_entry_s {
os_activity_stream_type_t type;
// information about the process streaming the data
pid_t pid;
uint64_t proc_id;
const uint8_t *proc_imageuuid;
const char *proc_imagepath;
// the activity associated with this streamed event
os_activity_id_t activity_id;
os_activity_id_t parent_id;
union {
struct os_activity_stream_common_s common;
struct os_activity_create_s activity_create;
struct os_activity_transition_s activity_transition;
struct os_log_message_s log_message;
struct os_trace_message_v2_s trace_message;
struct os_activity_useraction_s useraction;
struct os_signpost_s signpost;
struct os_activity_statedump_s statedump;
};
};
// Blocks
typedef bool (^os_activity_stream_block_t)(os_activity_stream_entry_t entry,
int error);
typedef void (^os_activity_stream_event_block_t)(
os_activity_stream_t stream, os_activity_stream_event_t event);
// SPI entry point prototypes
typedef os_activity_stream_t (*os_activity_stream_for_pid_t)(
pid_t pid, os_activity_stream_flag_t flags,
os_activity_stream_block_t stream_block);
typedef void (*os_activity_stream_resume_t)(os_activity_stream_t stream);
typedef void (*os_activity_stream_cancel_t)(os_activity_stream_t stream);
typedef char *(*os_log_copy_formatted_message_t)(os_log_message_t log_message);
typedef void (*os_activity_stream_set_event_handler_t)(
os_activity_stream_t stream, os_activity_stream_event_block_t block);
#endif /* ActivityStreamSPI_h */

View File

@ -0,0 +1,15 @@
# Due to sources including headers like:
# #include "MacOSX/i386/DNBArchImplI386.h"
# we must include the grandparent directory...
include_directories(${LLDB_SOURCE_DIR}/tools/debugserver/source)
add_library(lldbDebugserverDarwin_DarwinLog
ActivityStore.cpp
DarwinLogCollector.cpp
LogFilter.cpp
LogFilterChain.cpp
LogFilterExactMatch.cpp
LogFilterRegex.cpp
LogMessage.cpp
LogMessageOsLog.cpp
)

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,114 @@
//===-- DarwinLogCollector.h ------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef DarwinLogCollector_h
#define DarwinLogCollector_h
#include <sys/types.h>
#include <memory>
#include <mutex>
#include <unordered_map>
#include "ActivityStore.h"
#include "ActivityStreamSPI.h"
#include "DNBDefs.h"
#include "DarwinLogEvent.h"
#include "DarwinLogInterfaces.h"
#include "JSON.h"
class DarwinLogCollector;
typedef std::shared_ptr<DarwinLogCollector> DarwinLogCollectorSP;
class DarwinLogCollector
: public std::enable_shared_from_this<DarwinLogCollector>,
public ActivityStore {
public:
//------------------------------------------------------------------
/// Return whether the os_log and activity tracing SPI is available.
///
/// @return \b true if the activity stream support is available,
/// \b false otherwise.
//------------------------------------------------------------------
static bool IsSupported();
//------------------------------------------------------------------
/// Return a log function suitable for DNBLog to use as the internal
/// logging function.
///
/// @return a DNBLog-style logging function if IsSupported() returns
/// true; otherwise, returns nullptr.
//------------------------------------------------------------------
static DNBCallbackLog GetLogFunction();
static bool StartCollectingForProcess(nub_process_t pid,
const JSONObject &config);
static bool CancelStreamForProcess(nub_process_t pid);
static DarwinLogEventVector GetEventsForProcess(nub_process_t pid);
~DarwinLogCollector();
pid_t GetProcessID() const { return m_pid; }
//------------------------------------------------------------------
// ActivityStore API
//------------------------------------------------------------------
const char *GetActivityForID(os_activity_id_t activity_id) const override;
std::string
GetActivityChainForID(os_activity_id_t activity_id) const override;
private:
DarwinLogCollector() = delete;
DarwinLogCollector(const DarwinLogCollector &) = delete;
DarwinLogCollector &operator=(const DarwinLogCollector &) = delete;
explicit DarwinLogCollector(nub_process_t pid,
const LogFilterChainSP &filter_chain_sp);
void SignalDataAvailable();
void SetActivityStream(os_activity_stream_t activity_stream);
bool HandleStreamEntry(os_activity_stream_entry_t entry, int error);
DarwinLogEventVector RemoveEvents();
void CancelActivityStream();
void GetActivityChainForID_internal(os_activity_id_t activity_id,
std::string &result, size_t depth) const;
struct ActivityInfo {
ActivityInfo(const char *name, os_activity_id_t activity_id,
os_activity_id_t parent_activity_id)
: m_name(name), m_id(activity_id), m_parent_id(parent_activity_id) {}
const std::string m_name;
const os_activity_id_t m_id;
const os_activity_id_t m_parent_id;
};
using ActivityMap = std::unordered_map<os_activity_id_t, ActivityInfo>;
const nub_process_t m_pid;
os_activity_stream_t m_activity_stream;
DarwinLogEventVector m_events;
std::mutex m_events_mutex;
LogFilterChainSP m_filter_chain_sp;
/// Mutex to protect activity info (activity name and parent structures)
mutable std::mutex m_activity_info_mutex;
/// Map of activity id to ActivityInfo
ActivityMap m_activity_map;
};
#endif /* LogStreamCollector_h */

View File

@ -0,0 +1,27 @@
//===-- DarwinLogEvent.h ----------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef DarwinLogEvent_h
#define DarwinLogEvent_h
#include <memory>
#include <vector>
#include "JSONGenerator.h"
// =============================================================================
/// Each discrete unit of information is described as an event, such as
/// the emission of a single log message.
// =============================================================================
using DarwinLogEvent = JSONGenerator::Dictionary;
using DarwinLogEventSP = std::shared_ptr<DarwinLogEvent>;
using DarwinLogEventVector = std::vector<DarwinLogEventSP>;
#endif

View File

@ -0,0 +1,25 @@
//===-- DarwinLogInterfaces.h -----------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef DarwinLogInterfaces_h
#define DarwinLogInterfaces_h
#include <memory>
class ActivityStore;
class LogFilter;
using LogFilterSP = std::shared_ptr<LogFilter>;
class LogFilterChain;
using LogFilterChainSP = std::shared_ptr<LogFilterChain>;
class LogMessage;
#endif /* DarwinLogInterfaces_h */

View File

@ -0,0 +1,22 @@
//===-- DarwinLogTypes.h ----------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef DarwinLogTypes_h
#define DarwinLogTypes_h
enum FilterTarget {
eFilterTargetInvalid,
eFilterTargetActivity,
eFilterTargetActivityChain,
eFilterTargetCategory,
eFilterTargetMessage,
eFilterTargetSubsystem
};
#endif /* DarwinLogTypes_h */

View File

@ -0,0 +1,12 @@
//===-- LogFilter.cpp -------------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "LogFilter.h"
LogFilter::~LogFilter() {}

View File

@ -0,0 +1,30 @@
//===-- LogFilter.h ---------------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef LogFilter_h
#define LogFilter_h
#include "DarwinLogInterfaces.h"
class LogFilter {
public:
virtual ~LogFilter();
virtual bool DoesMatch(const LogMessage &message) const = 0;
bool MatchesAreAccepted() const { return m_matches_accept; }
protected:
LogFilter(bool matches_accept) : m_matches_accept(matches_accept) {}
private:
bool m_matches_accept;
};
#endif /* LogFilter_h */

View File

@ -0,0 +1,42 @@
//===-- LogFilterChain.cpp --------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "LogFilterChain.h"
#include "LogFilter.h"
LogFilterChain::LogFilterChain(bool default_accept)
: m_filters(), m_default_accept(default_accept) {}
void LogFilterChain::AppendFilter(const LogFilterSP &filter_sp) {
if (filter_sp)
m_filters.push_back(filter_sp);
}
void LogFilterChain::ClearFilterChain() { m_filters.clear(); }
bool LogFilterChain::GetDefaultAccepts() const { return m_default_accept; }
void LogFilterChain::SetDefaultAccepts(bool default_accept) {
m_default_accept = default_accept;
}
bool LogFilterChain::GetAcceptMessage(const LogMessage &message) const {
for (auto filter_sp : m_filters) {
if (filter_sp->DoesMatch(message)) {
// This message matches this filter. If the filter accepts matches,
// this message matches; otherwise, it rejects matches.
return filter_sp->MatchesAreAccepted();
}
}
// None of the filters matched. Therefore, we do whatever the
// default fall-through rule says.
return m_default_accept;
}

View File

@ -0,0 +1,38 @@
//===-- LogFilterChain.h ----------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef LogFilterChain_h
#define LogFilterChain_h
#include <vector>
#include "DarwinLogInterfaces.h"
class LogFilterChain {
public:
LogFilterChain(bool default_accept);
void AppendFilter(const LogFilterSP &filter_sp);
void ClearFilterChain();
bool GetDefaultAccepts() const;
void SetDefaultAccepts(bool default_accepts);
bool GetAcceptMessage(const LogMessage &message) const;
private:
using FilterVector = std::vector<LogFilterSP>;
FilterVector m_filters;
bool m_default_accept;
};
#endif /* LogFilterChain_hpp */

View File

@ -0,0 +1,49 @@
//===-- LogFilterExactMatch.cpp ---------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "LogFilterExactMatch.h"
#include "LogMessage.h"
LogFilterExactMatch::LogFilterExactMatch(bool match_accepts,
FilterTarget filter_target,
const std::string &match_text)
: LogFilter(match_accepts), m_filter_target(filter_target),
m_match_text(match_text) {}
bool LogFilterExactMatch::DoesMatch(const LogMessage &message) const {
switch (m_filter_target) {
case eFilterTargetActivity:
// Empty fields never match a condition.
if (!message.HasActivity())
return false;
return m_match_text == message.GetActivity();
case eFilterTargetActivityChain:
// Empty fields never match a condition.
if (!message.HasActivity())
return false;
return m_match_text == message.GetActivityChain();
case eFilterTargetCategory:
// Empty fields never match a condition.
if (!message.HasCategory())
return false;
return m_match_text == message.GetCategory();
case eFilterTargetMessage: {
const char *message_text = message.GetMessage();
return (message_text != nullptr) && (m_match_text == message_text);
}
case eFilterTargetSubsystem:
// Empty fields never match a condition.
if (!message.HasSubsystem())
return false;
return m_match_text == message.GetSubsystem();
default:
// We don't know this type.
return false;
}
}

View File

@ -0,0 +1,31 @@
//===-- LogFilterExactMatch.h -----------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef LogFilterExactMatch_h
#define LogFilterExactMatch_h
#include <string>
#include "DarwinLogInterfaces.h"
#include "DarwinLogTypes.h"
#include "LogFilter.h"
class LogFilterExactMatch : public LogFilter {
public:
LogFilterExactMatch(bool match_accepts, FilterTarget filter_target,
const std::string &match_text);
bool DoesMatch(const LogMessage &message) const override;
private:
const FilterTarget m_filter_target;
const std::string m_match_text;
};
#endif

View File

@ -0,0 +1,97 @@
//===-- LogFilterRegex.cpp --------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "LogFilterRegex.h"
#include "DNBLog.h"
#include "LogMessage.h"
//----------------------------------------------------------------------
// Enable enhanced mode if it is available. This allows for things like
// \d for digit, \s for space, and many more, but it isn't available
// everywhere.
//----------------------------------------------------------------------
#if defined(REG_ENHANCED)
#define DEFAULT_COMPILE_FLAGS (REG_ENHANCED | REG_EXTENDED)
#else
#define DEFAULT_COMPILE_FLAGS (REG_EXTENDED)
#endif
LogFilterRegex::LogFilterRegex(bool match_accepts, FilterTarget filter_target,
const std::string &regex)
: LogFilter(match_accepts), m_filter_target(filter_target),
m_regex_text(regex), m_regex(), m_is_valid(false), m_error_text() {
// Clear it.
memset(&m_regex, 0, sizeof(m_regex));
// Compile it.
if (!regex.empty()) {
auto comp_err = ::regcomp(&m_regex, regex.c_str(), DEFAULT_COMPILE_FLAGS);
m_is_valid = (comp_err == 0);
if (!m_is_valid) {
char buffer[256];
buffer[0] = '\0';
::regerror(comp_err, &m_regex, buffer, sizeof(buffer));
m_error_text = buffer;
}
}
}
LogFilterRegex::~LogFilterRegex() {
if (m_is_valid) {
// Free the regex internals.
regfree(&m_regex);
}
}
bool LogFilterRegex::DoesMatch(const LogMessage &message) const {
switch (m_filter_target) {
case eFilterTargetActivity:
// Empty fields never match a condition.
if (!message.HasActivity())
return false;
return ::regexec(&m_regex, message.GetActivity(), 0, nullptr, 0) == 0;
case eFilterTargetActivityChain:
// Empty fields never match a condition.
if (!message.HasActivity())
return false;
return ::regexec(&m_regex, message.GetActivityChain().c_str(), 0, nullptr,
0) == 0;
case eFilterTargetCategory:
// Empty fields never match a condition.
if (!message.HasCategory())
return false;
return ::regexec(&m_regex, message.GetCategory(), 0, nullptr, 0) == 0;
case eFilterTargetMessage: {
const char *message_text = message.GetMessage();
if (!message_text) {
DNBLogThreadedIf(LOG_DARWIN_LOG,
"LogFilterRegex: regex "
"\"%s\" no match due to nullptr message.",
m_regex_text.c_str());
return false;
}
bool match = ::regexec(&m_regex, message_text, 0, nullptr, 0) == 0;
DNBLogThreadedIf(LOG_DARWIN_LOG, "LogFilterRegex: regex "
"\"%s\" %s message \"%s\".",
m_regex_text.c_str(), match ? "matches" : "does not match",
message_text);
return match;
}
case eFilterTargetSubsystem:
// Empty fields never match a condition.
if (!message.HasSubsystem())
return false;
return ::regexec(&m_regex, message.GetSubsystem(), 0, nullptr, 0) == 0;
default:
// We don't know this type.
return false;
}
}

View File

@ -0,0 +1,44 @@
//===-- LogFilterRegex.h ----------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef LogFilterRegex_h
#define LogFilterRegex_h
// C includes
#include <regex.h>
// C++ includes
#include <string>
#include "DarwinLogInterfaces.h"
#include "DarwinLogTypes.h"
#include "LogFilter.h"
class LogFilterRegex : public LogFilter {
public:
LogFilterRegex(bool match_accepts, FilterTarget filter_target,
const std::string &regex);
virtual ~LogFilterRegex();
bool IsValid() const { return m_is_valid; }
const char *GetErrorAsCString() const { return m_error_text.c_str(); }
bool DoesMatch(const LogMessage &message) const override;
private:
const FilterTarget m_filter_target;
const std::string m_regex_text;
regex_t m_regex;
bool m_is_valid;
std::string m_error_text;
};
#endif /* LogFilterSubsystemRegex_hpp */

View File

@ -0,0 +1,14 @@
//===-- LogMessage.cpp ------------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "LogMessage.h"
LogMessage::LogMessage() {}
LogMessage::~LogMessage() {}

View File

@ -0,0 +1,40 @@
//===-- LogMessage.h --------------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef LogMessage_h
#define LogMessage_h
#include <string>
class LogMessage {
public:
virtual ~LogMessage();
virtual bool HasActivity() const = 0;
virtual const char *GetActivity() const = 0;
virtual std::string GetActivityChain() const = 0;
virtual bool HasCategory() const = 0;
virtual const char *GetCategory() const = 0;
virtual bool HasSubsystem() const = 0;
virtual const char *GetSubsystem() const = 0;
// This can be expensive, so once we ask for it, we'll cache the result.
virtual const char *GetMessage() const = 0;
protected:
LogMessage();
};
#endif /* LogMessage_h */

View File

@ -0,0 +1,68 @@
//===-- LogMessageOsLog.cpp -------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "LogMessageOsLog.h"
#include "ActivityStore.h"
#include "ActivityStreamSPI.h"
namespace {
static os_log_copy_formatted_message_t s_log_copy_formatted_message;
}
void LogMessageOsLog::SetFormatterFunction(
os_log_copy_formatted_message_t format_func) {
s_log_copy_formatted_message = format_func;
}
LogMessageOsLog::LogMessageOsLog(const ActivityStore &activity_store,
ActivityStreamEntry &entry)
: LogMessage(), m_activity_store(activity_store), m_entry(entry),
m_message() {}
bool LogMessageOsLog::HasActivity() const { return m_entry.activity_id != 0; }
const char *LogMessageOsLog::GetActivity() const {
return m_activity_store.GetActivityForID(m_entry.activity_id);
}
std::string LogMessageOsLog::GetActivityChain() const {
return m_activity_store.GetActivityChainForID(m_entry.activity_id);
}
bool LogMessageOsLog::HasCategory() const {
return m_entry.log_message.category && (m_entry.log_message.category[0] != 0);
}
const char *LogMessageOsLog::GetCategory() const {
return m_entry.log_message.category;
}
bool LogMessageOsLog::HasSubsystem() const {
return m_entry.log_message.subsystem &&
(m_entry.log_message.subsystem[0] != 0);
}
const char *LogMessageOsLog::GetSubsystem() const {
return m_entry.log_message.subsystem;
}
const char *LogMessageOsLog::GetMessage() const {
if (m_message.empty()) {
std::unique_ptr<char[]> formatted_message(
s_log_copy_formatted_message(&m_entry.log_message));
if (formatted_message)
m_message = formatted_message.get();
// else
// TODO log
}
// This is safe to return as we're not modifying it once we've formatted it.
return m_message.c_str();
}

Some files were not shown because too many files have changed in this diff Show More