[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Libunwind-devel] problem with ms_abi on x86-64
From: |
ariel . burton |
Subject: |
[Libunwind-devel] problem with ms_abi on x86-64 |
Date: |
Tue, 24 May 2011 11:18:28 -0400 |
User-agent: |
nail 11.25 7/29/05 |
Summary
=======
libunwind is not correctly unwinding through frames for
functions annotated with the __attribute__((ms_abi)).
Platform
========
observed on x86-64, linux, and gcc
How to reproduce
================
build a standard, vanilla, instance of libunwind 0.99
compile and link the program given below
ensure that libunwind will be found at runtime
note the difference in the backtraces shown
this is an example:
x86-64-linux-fedora14-x8664% ./t_repro
calling f
0: 0x400852
1: 0x40090a
2: 0x40096d
3: 0x400966
4: 0x400966
5: 0x400966
6: 0x400966
7: 0x400966
8: 0x400966
9: 0x400a78
10: 0x315a61ee5d
11: 0x400769
calling f_ms_abi
0: 0x400852
1: 0x40090a
2: 0x4009dc
Comments
========
f and f_ms_abi are identical with the exception that f_ms_abi
is annoted with __attribute__((ms_abi)). This causes the compiler
to emit code to save registers not otherwise saved. The DWARF
thus also contains directives for these registers. Runnning
the program with the UNW_DEBUG_LEVEL environment variable
set to 1 generates debug output which includes the following:
>run_cfi_program: Invalid register number 32 in DW_cfa_OFFSET
Program which reproduces the problem
====================================
#include <stdio.h>
#define UNW_LOCAL_ONLY
#include <libunwind-x86_64.h>
int
backtrace ( void **pcs, int vector_length )
{
int ret_val = 0;
unw_context_t context;
unw_cursor_t cursor;
unw_word_t this_pc;
ret_val = ( unw_getcontext ( &context ) ||
unw_init_local ( &cursor, &context ) );
if ( 0 == ret_val )
{
do {
unw_get_reg ( &cursor, UNW_REG_IP, &this_pc );
pcs [ ret_val ] = (void *) this_pc;
ret_val++;
} while ( (ret_val < vector_length) && (unw_step ( &cursor ) > 0) );
}
return ret_val;
} /* backtrace */
void
do_backtrace (void)
{
void *pcs [ 64 ];
int max_pcs = sizeof ( pcs ) / sizeof ( pcs [ 0 ] );
int num_pcs = backtrace ( pcs, max_pcs );
int i;
for ( i = 0; i < num_pcs; i ++ )
printf ( " %2d: %p\n", i, pcs [ i ] );
} /* do_backtrace */
void
f ( int arg )
{
if ( arg > 0 )
{
f ( arg - 1 );
}
else
{
do_backtrace ();
}
} /* f */
int
__attribute__((ms_abi))
f_ms_abi ( int arg )
{
if ( arg > 0 )
{
f_ms_abi ( arg - 1 );
}
else
{
do_backtrace ();
}
} /* f_ms_abi */
int
main ( int argc, char *argv [] )
{
setvbuf ( stdout, 0, _IONBF, 0 );
printf ( "calling f\n" );
f ( 6 );
printf ( "calling f_ms_abi\n" );
f_ms_abi ( 6 );
return 0;
} /* main */
- [Libunwind-devel] problem with ms_abi on x86-64,
ariel . burton <=