4 #define WIN32_LEAN_AND_MEAN
12 return IsDebuggerPresent();
16 std::string callstack;
18 int noofaddresses = CaptureStackBackTrace(0, 199, addresses,
nullptr);
21 for(
int idx = 0; idx < noofaddresses; ++idx) {
22 char local[
sizeof(IMAGEHLP_SYMBOL64) + 992];
23 IMAGEHLP_SYMBOL64* symbol =
reinterpret_cast<IMAGEHLP_SYMBOL64*
>(local);
24 DWORD64 realaddr =
reinterpret_cast<DWORD64
>(addresses[idx]) - 1;
29 memset(local, 0,
sizeof(local));
31 symbol->SizeOfStruct =
sizeof(IMAGEHLP_SYMBOL64);
32 symbol->MaxNameLength =
sizeof(local) -
sizeof(IMAGEHLP_SYMBOL64);
34 if(SymGetSymFromAddr64(GetCurrentProcess(), realaddr, &symdisp, symbol) || (!GetLastError() && symbol->Name[0])) {
39 UnDecorateSymbolName(symbol->Name, symname,
sizeof(symname), UNDNAME_COMPLETE);
41 memset(&line, 0,
sizeof(line));
42 line.SizeOfStruct =
sizeof(line);
44 if(SymGetLineFromAddr64(GetCurrentProcess(), realaddr, &linedisp, &line)) {
45 sprintf(buffer,
"%p - %s (%s:%d)\n",
reinterpret_cast<void*
>(realaddr), symname, line.FileName, line.LineNumber);
48 sprintf(buffer,
"%p - %s\n",
reinterpret_cast<void*
>(realaddr), symname);
52 sprintf(buffer,
"%p - (Unknown)\n",
reinterpret_cast<void*
>(realaddr));
59#elif defined(__linux__)
69 int fd = open(
"/proc/self/status", O_RDONLY);
72 ssize_t bytesread = read(fd, buf,
sizeof(buf) - 1);
79 constexpr char tracerPidString[] =
"TracerPid:";
80 const char* ptr = strstr(buf, tracerPidString);
83 ptr +=
sizeof(tracerPidString) - 1;
85 for (
const char* end = buf + bytesread; ptr <= end; ++ptr) {
87 return ::isdigit(*ptr) != 0 && *ptr !=
'0';
96struct BacktraceState {
101_Unwind_Reason_Code unwindCallback(
struct _Unwind_Context* context,
void* arg)
103 BacktraceState* state =
static_cast<BacktraceState*
>(arg);
104 uintptr_t pc = _Unwind_GetIP(context);
107 if (state->current == state->end) {
108 return _URC_END_OF_STACK;
110 *state->current++ =
reinterpret_cast<void*
>(pc);
112 return _URC_NO_REASON;
116 std::string callstack;
117 void* addresses[200];
118 BacktraceState state = {addresses, addresses + 200};
120 _Unwind_Backtrace(&unwindCallback, &state);
122 for (
int idx = 0, addrCount =
static_cast<int>(state.current - addresses); idx < addrCount; ++idx) {
124 char hexAddr[21] = {
'0',
'x',
'0',
'0',
'0',
'0',
'0',
'0',
'0',
'0',
'0',
'0',
'0',
'0',
'0',
'0',
'0',
'0',
':',
' ', 0 };
125 uint64_t addrValue =
reinterpret_cast<uint64_t
>(addresses[idx]);
127 for (
int idx = 18; addrValue; addrValue >>= 4) {
128 hexAddr[--idx] =
"0123456789ABCDEF"[addrValue & 0x0F];
131 callstack += hexAddr;
133 if (dladdr(addresses[idx], &info)) {
134 if (info.dli_sname) {
136 char* demangled = abi::__cxa_demangle(info.dli_sname,
nullptr,
nullptr, &status);
140 callstack += demangled;
145 callstack += info.dli_sname;
148 else if (info.dli_fname) {
149 callstack += info.dli_fname;
157#elif defined(__APPLE__)
162#include <sys/types.h>
163#include <sys/sysctl.h>
166 int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_PID, getpid()};
167 struct kinfo_proc info = {};
168 size_t size =
sizeof(info);
169 int junk = sysctl(mib,
sizeof(mib) /
sizeof(*mib), &info, &size,
nullptr, 0);
172 return info.kp_proc.p_flag & P_TRACED;
176 return "Sorry, callstack retrieval not implemented for Apple platforms.";
COGSFOUNDATION_API bool isBeingDebugged()
Return true if the application is running under a debugger.
COGSFOUNDATION_API std::string getCallstack()
Returns the current callstack as a string.