| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200 |
- /*
- * Copyright 2010-2019 Branimir Karadzic. All rights reserved.
- * License: https://github.com/bkaradzic/bx#license-bsd-2-clause
- */
- #include "bx_p.h"
- #include <bx/debug.h>
- #include <bx/string.h> // isPrint
- #include <bx/readerwriter.h> // WriterI
- #include <inttypes.h> // PRIx*
- #if BX_PLATFORM_EMSCRIPTEN
- #include <emscripten/emscripten.h>
- #endif
- #if BX_CRT_NONE
- # include "crt0.h"
- #elif BX_PLATFORM_ANDROID
- # include <android/log.h>
- #elif BX_PLATFORM_WINDOWS \
- || BX_PLATFORM_WINRT \
- || BX_PLATFORM_XBOXONE
- extern "C" __declspec(dllimport) void __stdcall OutputDebugStringA(const char* _str);
- #elif BX_PLATFORM_IOS || BX_PLATFORM_OSX
- # if defined(__OBJC__)
- # import <Foundation/NSObjCRuntime.h>
- # else
- # include <CoreFoundation/CFString.h>
- extern "C" void NSLog(CFStringRef _format, ...);
- # endif // defined(__OBJC__)
- #elif 0 // BX_PLATFORM_EMSCRIPTEN
- # include <emscripten.h>
- #else
- # include <stdio.h> // fputs, fflush
- #endif // BX_PLATFORM_WINDOWS
- namespace bx
- {
- void debugBreak()
- {
- #if BX_COMPILER_MSVC
- __debugbreak();
- #elif BX_CPU_ARM
- __builtin_trap();
- // asm("bkpt 0");
- #elif BX_CPU_X86 && (BX_COMPILER_GCC || BX_COMPILER_CLANG)
- // NaCl doesn't like int 3:
- // NativeClient: NaCl module load failed: Validation failure. File violates Native Client safety rules.
- __asm__ ("int $3");
- #elif BX_PLATFORM_EMSCRIPTEN
- emscripten_log(EM_LOG_CONSOLE | EM_LOG_ERROR | EM_LOG_C_STACK | EM_LOG_JS_STACK | EM_LOG_DEMANGLE, "debugBreak!");
- // Doing emscripten_debugger() disables asm.js validation due to an emscripten bug
- //emscripten_debugger();
- EM_ASM({ debugger; });
- #else // cross platform implementation
- int* int3 = (int*)3L;
- *int3 = 3;
- #endif // BX
- }
- void debugOutput(const char* _out)
- {
- #if BX_CRT_NONE
- crt0::debugOutput(_out);
- #elif BX_PLATFORM_ANDROID
- # ifndef BX_ANDROID_LOG_TAG
- # define BX_ANDROID_LOG_TAG ""
- # endif // BX_ANDROID_LOG_TAG
- __android_log_write(ANDROID_LOG_DEBUG, BX_ANDROID_LOG_TAG, _out);
- #elif BX_PLATFORM_WINDOWS \
- || BX_PLATFORM_WINRT \
- || BX_PLATFORM_XBOXONE
- OutputDebugStringA(_out);
- #elif BX_PLATFORM_IOS \
- || BX_PLATFORM_OSX
- # if defined(__OBJC__)
- NSLog(@"%s", _out);
- # else
- NSLog(__CFStringMakeConstantString("%s"), _out);
- # endif // defined(__OBJC__)
- #elif 0 // BX_PLATFORM_EMSCRIPTEN
- emscripten_log(EM_LOG_CONSOLE, "%s", _out);
- #else
- fputs(_out, stdout);
- fflush(stdout);
- #endif // BX_PLATFORM_
- }
- void debugOutput(const StringView& _str)
- {
- #if BX_CRT_NONE
- crt0::debugOutput(_str);
- #else
- const char* data = _str.getPtr();
- int32_t size = _str.getLength();
- char temp[4096];
- while (0 != size)
- {
- uint32_t len = uint32_min(sizeof(temp)-1, size);
- memCopy(temp, data, len);
- temp[len] = '\0';
- data += len;
- size -= len;
- debugOutput(temp);
- }
- #endif // BX_CRT_NONE
- }
- void debugPrintfVargs(const char* _format, va_list _argList)
- {
- char temp[8192];
- char* out = temp;
- int32_t len = vsnprintf(out, sizeof(temp), _format, _argList);
- if ( (int32_t)sizeof(temp) < len)
- {
- out = (char*)alloca(len+1);
- len = vsnprintf(out, len, _format, _argList);
- }
- out[len] = '\0';
- debugOutput(out);
- }
- void debugPrintf(const char* _format, ...)
- {
- va_list argList;
- va_start(argList, _format);
- debugPrintfVargs(_format, argList);
- va_end(argList);
- }
- #define DBG_ADDRESS "%" PRIxPTR
- void debugPrintfData(const void* _data, uint32_t _size, const char* _format, ...)
- {
- #define HEX_DUMP_WIDTH 16
- #define HEX_DUMP_SPACE_WIDTH 48
- #define HEX_DUMP_FORMAT "%-" BX_STRINGIZE(HEX_DUMP_SPACE_WIDTH) "." BX_STRINGIZE(HEX_DUMP_SPACE_WIDTH) "s"
- va_list argList;
- va_start(argList, _format);
- debugPrintfVargs(_format, argList);
- va_end(argList);
- debugPrintf("\ndata: " DBG_ADDRESS ", size: %d\n", _data, _size);
- if (NULL != _data)
- {
- const uint8_t* data = reinterpret_cast<const uint8_t*>(_data);
- char hex[HEX_DUMP_WIDTH*3+1];
- char ascii[HEX_DUMP_WIDTH+1];
- uint32_t hexPos = 0;
- uint32_t asciiPos = 0;
- for (uint32_t ii = 0; ii < _size; ++ii)
- {
- snprintf(&hex[hexPos], sizeof(hex)-hexPos, "%02x ", data[asciiPos]);
- hexPos += 3;
- ascii[asciiPos] = isPrint(data[asciiPos]) ? data[asciiPos] : '.';
- asciiPos++;
- if (HEX_DUMP_WIDTH == asciiPos)
- {
- ascii[asciiPos] = '\0';
- debugPrintf("\t" DBG_ADDRESS "\t" HEX_DUMP_FORMAT "\t%s\n", data, hex, ascii);
- data += asciiPos;
- hexPos = 0;
- asciiPos = 0;
- }
- }
- if (0 != asciiPos)
- {
- ascii[asciiPos] = '\0';
- debugPrintf("\t" DBG_ADDRESS "\t" HEX_DUMP_FORMAT "\t%s\n", data, hex, ascii);
- }
- }
- #undef HEX_DUMP_WIDTH
- #undef HEX_DUMP_SPACE_WIDTH
- #undef HEX_DUMP_FORMAT
- }
- class DebugWriter : public WriterI
- {
- virtual int32_t write(const void* _data, int32_t _size, Error* _err) override
- {
- BX_UNUSED(_err);
- debugOutput(StringView( (const char*)_data, _size) );
- return _size;
- }
- };
- WriterI* getDebugOut()
- {
- static DebugWriter s_debugOut;
- return &s_debugOut;
- }
- } // namespace bx
|