Devel-cst

 view release on metacpan or  search on metacpan

lib/Devel/cst.xs  view on Meta::CPAN

	/* Skip signal handler itself */
	backtrace_symbols_fd(buffer + 2, len - 2, 2);

	raise(signo);
}

static void* volatile altstack_ptr = NULL;

static void stack_destroy() {
	stack_t altstack;
	altstack.ss_sp = NULL;
	altstack.ss_size = 0;
	altstack.ss_flags = SS_DISABLE;
	sigaltstack(&altstack, NULL);
	free(altstack_ptr);
}

static void set_signalstack() {
	size_t stacksize = 2 * SIGSTKSZ;
	altstack_ptr = calloc(stacksize, 1);
	stack_t altstack;
	altstack.ss_sp = altstack_ptr;
	altstack.ss_size = stacksize;
	altstack.ss_flags = 0;
	sigaltstack(&altstack, NULL);
	atexit(stack_destroy);
}

static const int signals_normal[] = { SIGILL, SIGFPE, SIGTRAP, SIGABRT, SIGQUIT, SIGBUS };

static void set_handlers() {
	struct sigaction action;
	int i;
	action.sa_sigaction = handler;
	action.sa_flags     = SA_RESETHAND | SA_NODEFER | SA_SIGINFO;
	sigemptyset(&action.sa_mask);
	for (i = 0; i < sizeof signals_normal / sizeof *signals_normal; i++)
		sigaction(signals_normal[i], &action, NULL);
	action.sa_flags |= SA_ONSTACK;
	sigaction(SIGSEGV, &action, NULL);
}

MODULE = Devel::cst        				PACKAGE = Devel::cst

BOOT:
	/* preload libgcc_s by getting a stacktrace early */
	void** buffer = alloca(sizeof(void*) * 20);
	size_t len = backtrace(buffer, 20);

void import(SV* package, size_t depth = 20)
	CODE:
	if (!altstack_ptr) {
		set_signalstack();
		stack_depth = depth;
		set_handlers();
	}

MODULE = Devel::cst        				PACKAGE = Devel::CStacktrace

void stacktrace(size_t depth)
	PPCODE:
	void** buffer;
	Newx(buffer, depth, void*);
	size_t len = backtrace(buffer, depth);
	char** values = backtrace_symbols(buffer, len);
	int i;
	for (i = 0; i < len; i++)
		mXPUSHp(values[i], strlen(values[i]));
	free(values);



( run in 0.511 second using v1.01-cache-2.11-cpan-5511b514fd6 )