1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * Copyright 2000, 2010 Oracle and/or its affiliates.
8 * OpenOffice.org - a multi-platform office productivity suite
10 * This file is part of OpenOffice.org.
12 * OpenOffice.org is free software: you can redistribute it and/or modify
13 * it under the terms of the GNU Lesser General Public License version 3
14 * only, as published by the Free Software Foundation.
16 * OpenOffice.org is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Lesser General Public License version 3 for more details
20 * (a copy is included in the LICENSE file that accompanied this code).
22 * You should have received a copy of the GNU Lesser General Public License
23 * version 3 along with OpenOffice.org. If not, see
24 * <http://www.openoffice.org/license.html>
25 * for a copy of the LGPLv3 License.
27 ************************************************************************/
36 #include <sys/frame.h>
37 #include "backtrace.h"
43 #define FRAME_PTR_OFFSET 1
44 #define FRAME_OFFSET 0
45 #define STACK_BIAS 0x7ff
49 #define FRAME_PTR_OFFSET 1
50 #define FRAME_OFFSET 0
55 #elif defined( INTEL )
57 #define FRAME_PTR_OFFSET 3
58 #define FRAME_OFFSET 0
63 #error Unknown Solaris target platform.
65 #endif /* defined SPARC or INTEL */
68 int backtrace( void **buffer
, int max_frames
)
75 /* flush register windows */
80 /* get stack- and framepointer */
83 fpval
= ((long*)(ctx
))[FRAME_PTR_OFFSET
];
84 fp
= (struct frame
*)((char*)(fpval
) + STACK_BIAS
);
86 for (i
= 0; (i
< FRAME_OFFSET
) && (fp
!= 0); i
++)
87 fp
= (struct frame
*)((char*)(fp
->fr_savfp
) + STACK_BIAS
);
89 /* iterate through backtrace */
90 for (i
= 0; (fp
!= 0) && (fp
->fr_savpc
!= 0) && (i
< max_frames
); i
++)
92 /* saved (prev) frame */
93 struct frame
* prev
= (struct frame
*)((char*)(fp
->fr_savfp
) + STACK_BIAS
);
96 *(buffer
++) = (void*)(fp
->fr_savpc
);
98 /* prev frame (w/ stack growing top down) */
99 fp
= (prev
> fp
) ? prev
: 0;
102 /* return number of frames stored */
106 void backtrace_symbols_fd( void **buffer
, int size
, int fd
)
108 FILE *fp
= fdopen( fd
, "w" );
114 for ( pFramePtr
= buffer
; size
> 0 && pFramePtr
&& *pFramePtr
; pFramePtr
++, size
-- )
119 if ( 0 != dladdr( *pFramePtr
, &dli
) )
121 if ( dli
.dli_fname
&& dli
.dli_fbase
)
123 offset
= (ptrdiff_t)*pFramePtr
- (ptrdiff_t)dli
.dli_fbase
;
124 fprintf( fp
, "%s+0x%x", dli
.dli_fname
, offset
);
126 if ( dli
.dli_sname
&& dli
.dli_saddr
)
128 offset
= (ptrdiff_t)*pFramePtr
- (ptrdiff_t)dli
.dli_saddr
;
129 fprintf( fp
, "(%s+0x%x)", dli
.dli_sname
, offset
);
132 fprintf( fp
, "[0x%x]\n", *pFramePtr
);
140 #endif /* defined SOLARIS */
143 #if defined FREEBSD || defined NETBSD || defined OPENBSD || defined(DRAGONFLY)
149 #include "backtrace.h"
151 #define FRAME_PTR_OFFSET 1
152 #define FRAME_OFFSET 0
154 int backtrace( void **buffer
, int max_frames
)
159 /* get stack- and framepointer */
161 fp
= (struct frame
*)(((size_t*)(ctx
))[FRAME_PTR_OFFSET
]);
162 for ( i
=0; (i
<FRAME_OFFSET
) && (fp
!=0); i
++)
164 /* iterate through backtrace */
165 for (i
=0; fp
&& fp
->fr_savpc
&& i
<max_frames
; i
++)
168 *(buffer
++) = (void *)fp
->fr_savpc
;
175 void backtrace_symbols_fd( void **buffer
, int size
, int fd
)
177 FILE *fp
= fdopen( fd
, "w" );
182 for ( pFramePtr
= buffer
; size
> 0 && pFramePtr
&& *pFramePtr
; pFramePtr
++, size
-- )
187 if ( 0 != dladdr( *pFramePtr
, &dli
) )
189 if ( dli
.dli_fname
&& dli
.dli_fbase
)
191 offset
= (ptrdiff_t)*pFramePtr
- (ptrdiff_t)dli
.dli_fbase
;
192 fprintf( fp
, "%s+0x%x", dli
.dli_fname
, offset
);
194 if ( dli
.dli_sname
&& dli
.dli_saddr
)
196 offset
= (ptrdiff_t)*pFramePtr
- (ptrdiff_t)dli
.dli_saddr
;
197 fprintf( fp
, "(%s+0x%x)", dli
.dli_sname
, offset
);
200 fprintf( fp
, "[0x%x]\n", *pFramePtr
);
206 #endif /* defined FREEBSD */
214 #endif /* defined LINUX */
216 #if defined( MACOSX )
220 #include "backtrace.h"
222 typedef unsigned ptrdiff_t;
224 /* glib backtrace is only available on MacOsX 10.5 or higher
225 so we do it on our own */
227 int backtrace( void **buffer
, int max_frames
)
229 void **frame
= (void **)__builtin_frame_address(0);
230 void **bp
= ( void **)(*frame
);
234 for ( i
= 0; bp
&& ip
&& i
< max_frames
; i
++ )
239 bp
= (void**)(bp
[0]);
246 void backtrace_symbols_fd( void **buffer
, int size
, int fd
)
248 FILE *fp
= fdopen( fd
, "w" );
254 for ( pFramePtr
= buffer
; size
> 0 && pFramePtr
&& *pFramePtr
; pFramePtr
++, size
-- )
258 if ( 0 != dladdr( *pFramePtr
, &dli
) )
262 if ( dli
.dli_fname
&& dli
.dli_fbase
)
264 offset
= (ptrdiff_t)*pFramePtr
- (ptrdiff_t)dli
.dli_fbase
;
265 fprintf( fp
, "%s+0x%x", dli
.dli_fname
, offset
);
267 if ( dli
.dli_sname
&& dli
.dli_saddr
)
269 offset
= (ptrdiff_t)*pFramePtr
- (ptrdiff_t)dli
.dli_saddr
;
270 fprintf( fp
, "(%s+0x%x)", dli
.dli_sname
, offset
);
273 fprintf( fp
, "[0x%x]\n", (unsigned int)*pFramePtr
);
281 #endif /* defined MACOSX */
284 int backtrace( void **buffer
, int max_frames
)
289 void backtrace_symbols_fd( void **buffer
, int size
, int fd
)
294 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */