65#if (defined(unix) || defined(__unix) || defined(__unix__) || defined(__APPLE__)) && !defined(__CYGWIN__)
66 const int capacity = 1024;
70 int captured = backtrace(
frames, capacity);
72 int size = captured - index;
86 for (
int i = 0; i < size; ++i)
88 auto& frame = _frames[i];
91 frame.address =
frames[index + i];
93#if defined(LIBDL_SUPPORT)
96 if (dladdr(
frames[index + i], &info) == 0)
100 if (info.dli_fname !=
nullptr)
102 const char*
module = std::strrchr(info.dli_fname, '/');
103 if (module !=
nullptr)
104 frame.module =
module + 1;
108 if (info.dli_sname !=
nullptr)
112 char* demangled = abi::__cxa_demangle(info.dli_sname,
nullptr, 0, &status);
113 if ((status == 0) && (demangled !=
nullptr))
115 frame.function = demangled;
119 frame.function = info.dli_sname;
122#if defined(LIBBFD_SUPPORT)
124 char** matching =
nullptr;
126 void* symsptr =
nullptr;
127 asymbol** syms =
nullptr;
128 unsigned int symsize;
131 const char* filename =
nullptr;
132 const char* functionname =
nullptr;
135 bfd_boolean found =
false;
138 if ((frame.address ==
nullptr) || (info.dli_fname ==
nullptr))
141 abfd = bfd_openr(info.dli_fname,
nullptr);
145 if (bfd_check_format(abfd, bfd_archive))
148 if (!bfd_check_format_matches(abfd, bfd_object, &matching))
151 if ((bfd_get_file_flags(abfd) & HAS_SYMS) == 0)
154 symcount = bfd_read_minisymbols(abfd, FALSE, &symsptr, &symsize);
156 symcount = bfd_read_minisymbols(abfd, TRUE, &symsptr, &symsize);
159 syms = (asymbol**)symsptr;
161 pc = (bfd_vma)frame.address;
162 for (asection* section = abfd->sections; section !=
nullptr; section = section->next)
167 if ((bfd_section_flags(section) & SEC_ALLOC) == 0)
170 bfd_vma vma = bfd_section_vma(section);
174 bfd_size_type secsize = bfd_section_size(section);
175 if (pc >= vma + secsize)
178 found = bfd_find_nearest_line(abfd, section, syms, pc - vma, &filename, &functionname, &line);
184 if (filename !=
nullptr)
185 frame.filename = filename;
189 if (symsptr !=
nullptr)
196#elif defined(_WIN32) || defined(_WIN64) || defined(__CYGWIN__)
197 const int capacity = 1024;
201 USHORT captured = CaptureStackBackTrace(skip + 1, capacity,
frames,
nullptr);
204 _frames.resize(captured);
211 for (
int i = 0; i < captured; ++i)
213 auto& frame = _frames[i];
216 frame.address =
frames[i];
218#if defined(DBGHELP_SUPPORT)
220 HANDLE hProcess = GetCurrentProcess();
223 IMAGEHLP_MODULE64
module;
224 ZeroMemory(&module,
sizeof(module));
225 module.SizeOfStruct = sizeof(module);
226 if (SymGetModuleInfo64(hProcess, (DWORD64)frame.address, &module))
228 const char* image = std::strrchr(module.ImageName,
'\\');
229 if (image !=
nullptr)
230 frame.module = image + 1;
234 char symbol[
sizeof(SYMBOL_INFO) + MAX_SYM_NAME];
235 ZeroMemory(&symbol,
countof(symbol));
236 PSYMBOL_INFO pSymbol = (PSYMBOL_INFO)symbol;
237 pSymbol->SizeOfStruct =
sizeof(SYMBOL_INFO);
238 pSymbol->MaxNameLen = MAX_SYM_NAME;
239 if (SymFromAddr(hProcess, (DWORD64)frame.address,
nullptr, pSymbol))
242 if (UnDecorateSymbolName(pSymbol->Name, buffer, (DWORD)
countof(buffer), UNDNAME_NAME_ONLY) > 0)
243 frame.function = buffer;
248 IMAGEHLP_LINE64 line;
249 ZeroMemory(&line,
sizeof(line));
250 line.SizeOfStruct =
sizeof(line);
251 if (SymGetLineFromAddr64(hProcess, (DWORD64)frame.address, &offset, &line))
253 if (line.FileName !=
nullptr)
254 frame.filename = line.FileName;
255 frame.line = line.LineNumber;