X-Git-Url: https://git.saurik.com/apple/security.git/blobdiff_plain/bac41a7b9a0a9254fa30f8bb6e6038ab71a483e2..ce0ac947b4708d0bc1c7e6789b3e1f3bfc80d6e9:/cdsa/cdsa_utilities/debugging.cpp diff --git a/cdsa/cdsa_utilities/debugging.cpp b/cdsa/cdsa_utilities/debugging.cpp index a1941e3e..8a9eb254 100644 --- a/cdsa/cdsa_utilities/debugging.cpp +++ b/cdsa/cdsa_utilities/debugging.cpp @@ -22,15 +22,19 @@ #include #include #include +#include #define SYSLOG_NAMES // compile syslog name tables #include -namespace Security { -namespace Debug { +#include // for name demangling +// enable kernel tracing +#define ENABLE_SECTRACE 1 -#if !defined(NDEBUG) + +namespace Security { +namespace Debug { // @@ -38,7 +42,7 @@ namespace Debug { // void debug(const char *scope, const char *format, ...) { -#if !defined(NDEBUG_STUBS) +#if !defined(NDEBUG_CODE) va_list args; va_start(args, format); Target::get().message(scope, format, args); @@ -48,24 +52,14 @@ void debug(const char *scope, const char *format, ...) void vdebug(const char *scope, const char *format, va_list args) { -#if !defined(NDEBUG_STUBS) +#if !defined(NDEBUG_CODE) Target::get().message(scope, format, args); #endif } -void Scope::operator () (const char *format, ...) -{ -#if !defined(NDEBUG_STUBS) - va_list args; - va_start(args, format); - Target::get().message(mScope, format, args); - va_end(args); -#endif -} - bool debugging(const char *scope) { -#if !defined(NDEBUG_STUBS) +#if !defined(NDEBUG_CODE) return Target::get().debugging(scope); #else return false; @@ -73,6 +67,28 @@ bool debugging(const char *scope) } +// +// C equivalents for some basic uses +// +extern "C" { + int __security_debugging(const char *scope); + void __security_debug(const char *scope, const char *format, ...); +}; + +int __security_debugging(const char *scope) +{ return debugging(scope); } + +void __security_debug(const char *scope, const char *format, ...) +{ +#if !defined(NDEBUG_CODE) + va_list args; + va_start(args, format); + vdebug(scope, format, args); + va_end(args); +#endif +} + + // // Dump facility // @@ -87,7 +103,7 @@ bool dumping(const char *scope) void dump(const char *format, ...) { -#if !defined(NDEBUG_STUBS) +#if !defined(NDEBUG_CODE) va_list args; va_start(args, format); Target::get().dump(format, args); @@ -97,7 +113,7 @@ void dump(const char *format, ...) void dumpData(const void *ptr, size_t size) { -#if !defined(NDEBUG_STUBS) +#if !defined(NDEBUG_CODE) const char *addr = reinterpret_cast(ptr); const char *end = addr + size; bool isText = true; @@ -112,14 +128,14 @@ 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 } void dumpData(const char *title, const void *ptr, size_t size) { -#if !defined(NDEBUG_STUBS) +#if !defined(NDEBUG_CODE) dump("%s: ", title); dumpData(ptr, size); dump("\n"); @@ -127,16 +143,39 @@ 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. +// We're stripping out a few C++ prefixes; they're pretty redundant (and obvious). +// +string makeTypeName(const type_info &type) +{ + int status; + char *cname = abi::__cxa_demangle(type.name(), NULL, NULL, &status); + string name = !strncmp(cname, "Security::", 10) ? (cname + 10) : + !strncmp(cname, "std::", 5) ? (cname + 5) : + cname; + ::free(cname); // yes, really (ABI rules) + return name; +} + + // // Target initialization // -#if !defined(NDEBUG_STUBS) +#if !defined(NDEBUG_CODE) -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 +227,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 +240,7 @@ bool Target::dump(const char *scope) return dumpSelector(scope); } + // // Selector objects. // @@ -363,13 +408,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,18 +447,21 @@ 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) { - if (options == NULL || !strstr(options, "noflush")) + if (options == NULL || !strstr(options, "noflush")) { + // we mean "if the file isn't unbuffered", but what's the portable way to say that? + if (file != stderr) setlinebuf(file); + } if (options) { addDate = strstr(options, "date"); lockIO = !strstr(options, "nolock"); @@ -415,10 +477,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; @@ -445,11 +507,21 @@ void SyslogSink::configure(const char *options) { } -#endif //NDEBUG_STUBS +#endif //NDEBUG_CODE + + +// +// kernel tracing support (C version) +// +extern "C" void security_ktrace(int); -#endif // NDEBUG +void security_ktrace(int code) +{ +#if defined(ENABLE_SECTRACE) + syscall(180, code, 0, 0, 0, 0); +#endif +} } // end namespace Debug - } // end namespace Security