Skip to content

Added an option to use libc backtrace function from execinfo.h#70

Merged
apolukhin merged 3 commits intoboostorg:developfrom
ivanarh:use_execinfo_backtrace
Jan 11, 2019
Merged

Added an option to use libc backtrace function from execinfo.h#70
apolukhin merged 3 commits intoboostorg:developfrom
ivanarh:use_execinfo_backtrace

Conversation

@ivanarh
Copy link
Contributor

@ivanarh ivanarh commented Jan 10, 2019

…nstead of _Unwind_Backtrace on Unix-like systems. Useful on iOS 32-bit ARM where _Unwind_Backtrace symbol is undefined.
@coveralls
Copy link

coveralls commented Jan 10, 2019

Coverage Status

Coverage increased (+0.02%) to 90.265% when pulling 839a1a1 on ivanarh:use_execinfo_backtrace into d708d17 on boostorg:develop.

@apolukhin apolukhin merged commit 158a59a into boostorg:develop Jan 11, 2019
@apolukhin
Copy link
Member

Many thanks for the PR!

I'm worried about async signal safety of backtrace() on Ios. Are there any guarantees?

@ivanarh
Copy link
Contributor Author

ivanarh commented Jan 12, 2019

I'm worried about async signal safety of backtrace() on Ios. Are there any guarantees?

It may depend on libc implementation and (or) on platform. For example, let's take a look to it's source in glibc:
https://github.com/lattera/glibc/blob/master/debug/backtrace.c
It's a simple wrapper around _Unwind_Backtrace. But it's loaded by dlopen/dlsym calls. So if backtrace() function is called for a first time from signal handler it's may be unsafe. But a workaround may be used: backtrace() should be called once before any signal handlers.

What about apple libc implementation, it's completely different:
https://opensource.apple.com/source/Libc/Libc-1272.200.26/gen/backtrace.c.auto.html
https://opensource.apple.com/source/Libc/Libc-1272.200.26/gen/thread_stack_pcs.c.auto.html
It relies on Apple ABI where an old frame pointer is saved to the stack. All it does is jumping from current frame pointer to previous in a cycle. But couple of external calls exist:

pthread_t self = pthread_self();
void *stacktop = pthread_get_stackaddr_np(self);
void *stackbot = stacktop - pthread_get_stacksize_np(self);

pthread_self is signal safe, pthread_get_stackaddr_np is not properly documented.
https://opensource.apple.com/source/libpthread/libpthread-218.60.3/src/pthread.c.auto.html
I see some explicit locks in its source code:

void *
pthread_get_stackaddr_np(pthread_t t)
{
	int ret;
	void *addr = NULL;

	if (t == NULL) {
		return (void *)(uintptr_t)ESRCH; // XXX bug?
	}
	
	// since the main thread will not get de-allocated from underneath us
	if (t == pthread_self() || t == &_thread) {
		return t->stackaddr;
	}

	_PTHREAD_LOCK(_pthread_list_lock);

So it may be unsafe. But this code isn't reached when we work with a current thread.

Therefore, signal safety of backtrace function is an arguable question.

@ivanarh ivanarh deleted the use_execinfo_backtrace branch January 12, 2019 12:23
apolukhin added a commit that referenced this pull request Jan 12, 2019
@apolukhin
Copy link
Member

Looks safe to me. Many thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants