mirror of
https://github.com/winfsp/winfsp.git
synced 2025-06-14 15:52:47 -05:00
add winfsp-tests and ext/tlib
This commit is contained in:
75
ext/tlib/callstack.c
Normal file
75
ext/tlib/callstack.c
Normal file
@ -0,0 +1,75 @@
|
||||
/**
|
||||
* @file tlib/callstack.c
|
||||
*
|
||||
* @copyright 2014-2015 Bill Zissimopoulos
|
||||
*/
|
||||
|
||||
#include <tlib/callstack.h>
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
#include <windows.h>
|
||||
#include <dbghelp.h>
|
||||
#pragma comment(lib, "dbghelp.lib")
|
||||
#elif defined(__APPLE__) || defined(__linux__)
|
||||
#include <dlfcn.h>
|
||||
#include <execinfo.h>
|
||||
#else
|
||||
#error tlib/callstack.c not implemented for this platform
|
||||
#endif
|
||||
|
||||
void tlib_callstack(size_t skip, size_t count, struct tlib_callstack_s *stack)
|
||||
{
|
||||
if (count > TLIB_MAX_SYMRET)
|
||||
count = TLIB_MAX_SYMRET;
|
||||
size_t naddrs = skip + count;
|
||||
if (naddrs > TLIB_MAX_SYMCAP)
|
||||
naddrs = TLIB_MAX_SYMCAP;
|
||||
memset((void *)stack->syms, 0, sizeof stack->syms);
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
/* SymInitialize()/SymFromAddr() are not thread-safe. Furthermore SymInitialize() should
|
||||
* not be called more than once per process.
|
||||
*/
|
||||
HANDLE hproc = GetCurrentProcess();
|
||||
static SYMBOL_INFO *syminfo = 0;
|
||||
void *addrs[TLIB_MAX_SYMCAP];
|
||||
size_t i = 0;
|
||||
if (0 == syminfo)
|
||||
{
|
||||
syminfo = (SYMBOL_INFO *)malloc(sizeof(SYMBOL_INFO) + TLIB_MAX_SYMLEN);
|
||||
if (0 == syminfo)
|
||||
return;
|
||||
SymInitialize(hproc, 0, TRUE);
|
||||
}
|
||||
memset(syminfo, 0, sizeof(SYMBOL_INFO));
|
||||
syminfo->SizeOfStruct = sizeof(SYMBOL_INFO);
|
||||
syminfo->MaxNameLen = TLIB_MAX_SYMLEN;
|
||||
naddrs = CaptureStackBackTrace(0, naddrs, addrs, 0);
|
||||
for (void **p = addrs + skip, **endp = addrs + naddrs; endp > p; p++)
|
||||
{
|
||||
DWORD64 displacement = 0;
|
||||
if (SymFromAddr(hproc, (DWORD64)*p, &displacement, syminfo))
|
||||
{
|
||||
stack->syms[i] = stack->symbuf[i];
|
||||
strncpy(stack->symbuf[i], syminfo->Name, TLIB_MAX_SYMLEN);
|
||||
stack->symbuf[i][TLIB_MAX_SYMLEN] = '\0';
|
||||
i++;
|
||||
}
|
||||
}
|
||||
#elif defined(__APPLE__) || defined(__linux__)
|
||||
void *addrs[TLIB_MAX_SYMCAP];
|
||||
naddrs = backtrace(addrs, naddrs);
|
||||
size_t i = 0;
|
||||
Dl_info syminfo;
|
||||
for (void **p = addrs + skip, **endp = addrs + naddrs; endp > p; p++)
|
||||
{
|
||||
if (dladdr(*p, &syminfo) && 0 != syminfo.dli_sname)
|
||||
{
|
||||
stack->syms[i] = stack->symbuf[i];
|
||||
strncpy(stack->symbuf[i], syminfo.dli_sname, TLIB_MAX_SYMLEN);
|
||||
stack->symbuf[i][TLIB_MAX_SYMLEN] = '\0';
|
||||
i++;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
Reference in New Issue
Block a user