X-Git-Url: https://git.saurik.com/apple/security.git/blobdiff_plain/bac41a7b9a0a9254fa30f8bb6e6038ab71a483e2..a66d0d4aa363c2f8ee16aee8810732ae89bc0608:/cdsa/cdsa_utilities/debugging.cpp?ds=sidebyside diff --git a/cdsa/cdsa_utilities/debugging.cpp b/cdsa/cdsa_utilities/debugging.cpp index a1941e3e..40085f6a 100644 --- a/cdsa/cdsa_utilities/debugging.cpp +++ b/cdsa/cdsa_utilities/debugging.cpp @@ -22,16 +22,29 @@ #include #include #include +#include #define SYSLOG_NAMES // compile syslog name tables #include +#if !defined(USE_CXXABI) +#define USE_CXXABI 0 // only available in gcc3 >v1100 +#endif + +#if USE_CXXABI +# include // for name demangling +#endif //USE_CXXABI + + namespace Security { namespace Debug { -#if !defined(NDEBUG) +#if defined(NDEBUG) + +void Scope::operator () (const char *, ...) { } +#else // NDEBUG // // Main debug functions (global and in-scope) @@ -112,7 +125,7 @@ void dumpData(const void *ptr, size_t size) } else { dump("0x"); for (const char *p = addr; p < end; p++) - dump("%2.2x", *p); + dump("%2.2x", static_cast(*p)); } #endif //NDEBUG_STUBS } @@ -127,16 +140,40 @@ void dumpData(const char *title, const void *ptr, size_t size) } +// +// Turn a C++ typeid into a nice type name. +// This uses the C++ ABI where available. +// +string makeTypeName(const type_info &type) +{ +#if USE_CXXABI + int status; + char *cname = abi::__cxa_demangle(type.name(), NULL, NULL, &status); + string name = cname; // save the value + ::free(cname); // yes, really (ABI rule) + return name; +#else + return type.name(); // can't demangle; just return internal name +#endif +} + + // // Target initialization // #if !defined(NDEBUG_STUBS) -Target::Target() : showScope(false), showThread(false), showPid(false), sink(NULL) +Target::Target() + : showScope(false), showThread(false), showPid(false), + sink(NULL) { // put into singleton slot if first if (singleton == NULL) singleton = this; + + // insert terminate handler + if (!previousTerminator) // first time we do this + previousTerminator = set_terminate(terminator); } Target::~Target() @@ -188,7 +225,12 @@ bool Target::debugging(const char *scope) // void Target::dump(const char *format, va_list args) { - sink->dump(format, args); + char buffer[messageConstructionSize]; // building the message here + vsnprintf(buffer, sizeof(buffer), format, args); + for (char *p = buffer; *p; p++) + if (!isprint(*p) && !isspace(*p) || *p == '\r') + *p = '?'; + sink->dump(buffer); } bool Target::dump(const char *scope) @@ -196,6 +238,7 @@ bool Target::dump(const char *scope) return dumpSelector(scope); } + // // Selector objects. // @@ -363,13 +406,27 @@ Target &Target::get() Target::Sink::~Sink() { } -void Target::Sink::dump(const char *, va_list) +void Target::Sink::dump(const char *) { } void Target::Sink::configure(const char *) { } +// +// The terminate handler installed when a Target is created +// +terminate_handler Target::previousTerminator; + +void Target::terminator() +{ + debug("exception", "uncaught exception terminates program"); + previousTerminator(); + debug("exception", "prior termination handler failed to abort; forcing abort"); + abort(); +} + + // // File sinks (write to file via stdio) // @@ -388,12 +445,12 @@ void FileSink::put(const char *buffer, unsigned int) putc('\n', file); } -void FileSink::dump(const char *format, va_list args) +void FileSink::dump(const char *text) { StLock locker(lock, false); if (lockIO) locker.lock(); - vfprintf(file, format, args); + fputs(text, file); } void FileSink::configure(const char *options) @@ -415,10 +472,10 @@ void SyslogSink::put(const char *buffer, unsigned int) syslog(priority, "%s", buffer); } -void SyslogSink::dump(const char *format, va_list args) +void SyslogSink::dump(const char *text) { // add to dump buffer - vsnprintf(dumpPtr, dumpBuffer + dumpBufferSize - dumpPtr, format, args); + snprintf(dumpPtr, dumpBuffer + dumpBufferSize - dumpPtr, "%s", text); // take off full lines and submit char *p = dumpBase;