mirror of
https://github.com/tobast/libunwind-eh_elf.git
synced 2025-03-30 11:22:16 +02:00
Merge with origin/master
This commit is contained in:
commit
9bb9c972e6
7 changed files with 70 additions and 19 deletions
src
tests
|
@ -422,7 +422,7 @@ put_unwind_info (struct dwarf_cursor *c, unw_proc_info_t *pi)
|
||||||
|
|
||||||
if (c->pi_is_dynamic)
|
if (c->pi_is_dynamic)
|
||||||
unwi_put_dynamic_unwind_info (c->as, pi, c->as_arg);
|
unwi_put_dynamic_unwind_info (c->as, pi, c->as_arg);
|
||||||
else if (pi->unwind_info);
|
else if (pi->unwind_info)
|
||||||
{
|
{
|
||||||
mempool_free (&dwarf_cie_info_pool, pi->unwind_info);
|
mempool_free (&dwarf_cie_info_pool, pi->unwind_info);
|
||||||
pi->unwind_info = NULL;
|
pi->unwind_info = NULL;
|
||||||
|
|
|
@ -26,7 +26,13 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||||
#include "_UPT_internal.h"
|
#include "_UPT_internal.h"
|
||||||
|
|
||||||
void
|
void
|
||||||
_UPT_destroy (void *ui)
|
_UPT_destroy (void *ptr)
|
||||||
{
|
{
|
||||||
free (ui);
|
struct UPT_info *ui = (struct UPT_info *) ptr;
|
||||||
|
if (ui->ei.image)
|
||||||
|
{
|
||||||
|
munmap(ui->ei.image, ui->ei.size);
|
||||||
|
}
|
||||||
|
|
||||||
|
free (ptr);
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,7 +24,13 @@ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||||
|
|
||||||
#include "ucontext_i.h"
|
#include "ucontext_i.h"
|
||||||
|
#if defined __linux__
|
||||||
|
#include <asm/unistd.h>
|
||||||
|
#define SIG_SETMASK 2
|
||||||
|
#define SIGSET_BYTE_SIZE (64/8)
|
||||||
|
#elif defined __FreeBSD__
|
||||||
|
#include <sys/syscall.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
/* int _Ux86_64_setcontext (const ucontext_t *ucp)
|
/* int _Ux86_64_setcontext (const ucontext_t *ucp)
|
||||||
|
|
||||||
|
@ -37,12 +43,34 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||||
|
|
||||||
_Ux86_64_setcontext:
|
_Ux86_64_setcontext:
|
||||||
|
|
||||||
/* restore fp state */
|
|
||||||
#if defined __linux__
|
#if defined __linux__
|
||||||
|
/* restore signal mask
|
||||||
|
sigprocmask(SIG_SETMASK, ucp->uc_sigmask, NULL, sizeof(sigset_t)) */
|
||||||
|
push %rdi
|
||||||
|
mov $__NR_rt_sigprocmask, %rax
|
||||||
|
lea UC_SIGMASK(%rdi), %rsi
|
||||||
|
mov $SIG_SETMASK, %rdi
|
||||||
|
xor %rdx, %rdx
|
||||||
|
mov $SIGSET_BYTE_SIZE, %r10
|
||||||
|
syscall
|
||||||
|
pop %rdi
|
||||||
|
|
||||||
|
/* restore fp state */
|
||||||
mov UC_MCONTEXT_FPREGS_PTR(%rdi),%r8
|
mov UC_MCONTEXT_FPREGS_PTR(%rdi),%r8
|
||||||
fldenv (%r8)
|
fldenv (%r8)
|
||||||
ldmxcsr FPREGS_OFFSET_MXCSR(%r8)
|
ldmxcsr FPREGS_OFFSET_MXCSR(%r8)
|
||||||
#elif defined __FreeBSD__
|
#elif defined __FreeBSD__
|
||||||
|
/* restore signal mask */
|
||||||
|
pushq %rdi
|
||||||
|
xorl %edx,%edx
|
||||||
|
movq UC_SIGMASK(%rdi),%rsi
|
||||||
|
movl $3,%edi/* SIG_SETMASK */
|
||||||
|
movl $SYS_sigprocmask,%eax
|
||||||
|
movq %rcx,%r10
|
||||||
|
sysenter
|
||||||
|
popq %rdi
|
||||||
|
|
||||||
|
/* restore fp state */
|
||||||
cmpq $UC_MCONTEXT_FPOWNED_FPU,UC_MCONTEXT_OWNEDFP(%rdi)
|
cmpq $UC_MCONTEXT_FPOWNED_FPU,UC_MCONTEXT_OWNEDFP(%rdi)
|
||||||
jne 1f
|
jne 1f
|
||||||
cmpq $UC_MCONTEXT_FPFMT_XMM,UC_MCONTEXT_FPFORMAT(%rdi)
|
cmpq $UC_MCONTEXT_FPFMT_XMM,UC_MCONTEXT_FPFORMAT(%rdi)
|
||||||
|
|
|
@ -42,6 +42,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||||
#define UC_MCONTEXT_GREGS_RIP 0xa8
|
#define UC_MCONTEXT_GREGS_RIP 0xa8
|
||||||
#define UC_MCONTEXT_FPREGS_PTR 0x1a8
|
#define UC_MCONTEXT_FPREGS_PTR 0x1a8
|
||||||
#define UC_MCONTEXT_FPREGS_MEM 0xe0
|
#define UC_MCONTEXT_FPREGS_MEM 0xe0
|
||||||
|
#define UC_SIGMASK 0x128
|
||||||
#define FPREGS_OFFSET_MXCSR 0x18
|
#define FPREGS_OFFSET_MXCSR 0x18
|
||||||
#elif defined __FreeBSD__
|
#elif defined __FreeBSD__
|
||||||
#define UC_MCONTEXT_GREGS_R8 0x38
|
#define UC_MCONTEXT_GREGS_R8 0x38
|
||||||
|
@ -76,5 +77,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||||
#define UC_MCONTEXT_FPOWNED_FPU 0x20001
|
#define UC_MCONTEXT_FPOWNED_FPU 0x20001
|
||||||
#define UC_MCONTEXT_FPFMT_XMM 0x10002
|
#define UC_MCONTEXT_FPFMT_XMM 0x10002
|
||||||
#define UC_MCONTEXT_MC_LEN_VAL 0x320
|
#define UC_MCONTEXT_MC_LEN_VAL 0x320
|
||||||
|
#define UC_SIGMASK 0x0
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -48,14 +48,17 @@ typedef RETSIGTYPE (*sighandler_t) (int);
|
||||||
int verbose;
|
int verbose;
|
||||||
int num_errors;
|
int num_errors;
|
||||||
|
|
||||||
|
/* These variables are global because they
|
||||||
|
* cause the signal stack to overflow */
|
||||||
|
char buf[512], name[256];
|
||||||
|
unw_cursor_t cursor;
|
||||||
|
ucontext_t uc;
|
||||||
|
|
||||||
static void
|
static void
|
||||||
do_backtrace (void)
|
do_backtrace (void)
|
||||||
{
|
{
|
||||||
char buf[512], name[256];
|
|
||||||
unw_word_t ip, sp, off;
|
unw_word_t ip, sp, off;
|
||||||
unw_cursor_t cursor;
|
|
||||||
unw_proc_info_t pi;
|
unw_proc_info_t pi;
|
||||||
unw_context_t uc;
|
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (verbose)
|
if (verbose)
|
||||||
|
@ -186,6 +189,12 @@ sighandler (int signal, void *siginfo, void *context)
|
||||||
#elif defined __FreeBSD__
|
#elif defined __FreeBSD__
|
||||||
printf (" @ %lx", (unsigned long) uc->uc_mcontext.mc_eip);
|
printf (" @ %lx", (unsigned long) uc->uc_mcontext.mc_eip);
|
||||||
#endif
|
#endif
|
||||||
|
#elif UNW_TARGET_X86_64
|
||||||
|
#if defined __linux__
|
||||||
|
printf (" @ %lx", (unsigned long) uc->uc_mcontext.gregs[REG_RIP]);
|
||||||
|
#elif defined __FreeBSD__
|
||||||
|
printf (" @ %lx", (unsigned long) uc->uc_mcontext.mc_rip);
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
printf ("\n");
|
printf ("\n");
|
||||||
}
|
}
|
||||||
|
|
|
@ -63,7 +63,7 @@ void
|
||||||
handler (int sig)
|
handler (int sig)
|
||||||
{
|
{
|
||||||
unw_word_t ip;
|
unw_word_t ip;
|
||||||
sigset_t mask;
|
sigset_t mask, oldmask;
|
||||||
unw_context_t uc;
|
unw_context_t uc;
|
||||||
unw_cursor_t c;
|
unw_cursor_t c;
|
||||||
char foo;
|
char foo;
|
||||||
|
@ -84,7 +84,7 @@ handler (int sig)
|
||||||
|
|
||||||
sigemptyset (&mask);
|
sigemptyset (&mask);
|
||||||
sigaddset (&mask, SIGUSR2);
|
sigaddset (&mask, SIGUSR2);
|
||||||
sigprocmask (SIG_BLOCK, &mask, NULL);
|
sigprocmask (SIG_BLOCK, &mask, &oldmask);
|
||||||
kill (getpid (), SIGUSR2); /* pend SIGUSR2 */
|
kill (getpid (), SIGUSR2); /* pend SIGUSR2 */
|
||||||
|
|
||||||
signal (SIGUSR1, SIG_IGN);
|
signal (SIGUSR1, SIG_IGN);
|
||||||
|
@ -92,6 +92,10 @@ handler (int sig)
|
||||||
|
|
||||||
if ((ret = unw_getcontext (&uc)) < 0)
|
if ((ret = unw_getcontext (&uc)) < 0)
|
||||||
panic ("unw_getcontext() failed: ret=%d\n", ret);
|
panic ("unw_getcontext() failed: ret=%d\n", ret);
|
||||||
|
#if UNW_TARGET_X86_64
|
||||||
|
/* unw_getcontext() doesn't save signal mask to avoid a syscall */
|
||||||
|
uc.uc_sigmask = oldmask;
|
||||||
|
#endif
|
||||||
if ((ret = unw_init_local (&c, &uc)) < 0)
|
if ((ret = unw_init_local (&c, &uc)) < 0)
|
||||||
panic ("unw_init_local() failed: ret=%d\n", ret);
|
panic ("unw_init_local() failed: ret=%d\n", ret);
|
||||||
|
|
||||||
|
@ -113,10 +117,7 @@ handler (int sig)
|
||||||
++got_usr2;
|
++got_usr2;
|
||||||
if (got_usr1)
|
if (got_usr1)
|
||||||
{
|
{
|
||||||
if (sigusr1_sp != &foo)
|
if (verbose)
|
||||||
panic ("Stack pointer changed from %p to %p between signals\n",
|
|
||||||
sigusr1_sp, &foo);
|
|
||||||
else if (verbose)
|
|
||||||
printf ("OK: stack still at %p\n", &foo);
|
printf ("OK: stack still at %p\n", &foo);
|
||||||
}
|
}
|
||||||
signal (SIGUSR2, SIG_IGN);
|
signal (SIGUSR2, SIG_IGN);
|
||||||
|
|
|
@ -29,6 +29,15 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||||
#include <libunwind.h>
|
#include <libunwind.h>
|
||||||
#include <execinfo.h>
|
#include <execinfo.h>
|
||||||
|
|
||||||
|
/* ITERS=1000, NTHREAD=10 caught some bugs in the past */
|
||||||
|
#ifndef ITERS
|
||||||
|
#define ITERS 100
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef NTHREAD
|
||||||
|
#define NTHREAD 2
|
||||||
|
#endif
|
||||||
|
|
||||||
int verbose;
|
int verbose;
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -1325,7 +1334,7 @@ void *
|
||||||
bar(void *p)
|
bar(void *p)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < 1000; ++i) {
|
for (i = 0; i < ITERS; ++i) {
|
||||||
foo_0 ();
|
foo_0 ();
|
||||||
foo_1 ();
|
foo_1 ();
|
||||||
foo_2 ();
|
foo_2 ();
|
||||||
|
@ -1459,10 +1468,6 @@ bar(void *p)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef NTHREAD
|
|
||||||
#define NTHREAD 10
|
|
||||||
#endif
|
|
||||||
|
|
||||||
int doit ()
|
int doit ()
|
||||||
{
|
{
|
||||||
pthread_t tid[NTHREAD];
|
pthread_t tid[NTHREAD];
|
||||||
|
|
Loading…
Add table
Reference in a new issue