1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2000, 2010 Oracle and/or its affiliates.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * This file is part of OpenOffice.org.
11 * OpenOffice.org is free software: you can redistribute it and/or modify
12 * it under the terms of the GNU Lesser General Public License version 3
13 * only, as published by the Free Software Foundation.
15 * OpenOffice.org is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Lesser General Public License version 3 for more details
19 * (a copy is included in the LICENSE file that accompanied this code).
21 * You should have received a copy of the GNU Lesser General Public License
22 * version 3 along with OpenOffice.org. If not, see
23 * <http://www.openoffice.org/license.html>
24 * for a copy of the LGPLv3 License.
26 ************************************************************************/
35 #include <sys/frame.h>
36 #include "backtrace.h"
42 #define FRAME_PTR_OFFSET 1
43 #define FRAME_OFFSET 0
44 #define STACK_BIAS 0x7ff
48 #define FRAME_PTR_OFFSET 1
49 #define FRAME_OFFSET 0
54 #elif defined( INTEL )
56 #define FRAME_PTR_OFFSET 3
57 #define FRAME_OFFSET 0
62 #error Unknown Solaris target platform.
64 #endif /* defined SPARC or INTEL */
67 int backtrace( void **buffer
, int max_frames
)
74 /* flush register windows */
79 /* get stack- and framepointer */
82 fpval
= ((long*)(ctx
))[FRAME_PTR_OFFSET
];
83 fp
= (struct frame
*)((char*)(fpval
) + STACK_BIAS
);
85 for (i
= 0; (i
< FRAME_OFFSET
) && (fp
!= 0); i
++)
86 fp
= (struct frame
*)((char*)(fp
->fr_savfp
) + STACK_BIAS
);
88 /* iterate through backtrace */
89 for (i
= 0; (fp
!= 0) && (fp
->fr_savpc
!= 0) && (i
< max_frames
); i
++)
91 /* saved (prev) frame */
92 struct frame
* prev
= (struct frame
*)((char*)(fp
->fr_savfp
) + STACK_BIAS
);
95 *(buffer
++) = (void*)(fp
->fr_savpc
);
97 /* prev frame (w/ stack growing top down) */
98 fp
= (prev
> fp
) ? prev
: 0;
101 /* return number of frames stored */
105 void backtrace_symbols_fd( void **buffer
, int size
, int fd
)
107 FILE *fp
= fdopen( fd
, "w" );
113 for ( pFramePtr
= buffer
; size
> 0 && pFramePtr
&& *pFramePtr
; pFramePtr
++, size
-- )
118 if ( 0 != dladdr( *pFramePtr
, &dli
) )
120 if ( dli
.dli_fname
&& dli
.dli_fbase
)
122 offset
= (ptrdiff_t)*pFramePtr
- (ptrdiff_t)dli
.dli_fbase
;
123 fprintf( fp
, "%s+0x%x", dli
.dli_fname
, offset
);
125 if ( dli
.dli_sname
&& dli
.dli_saddr
)
127 offset
= (ptrdiff_t)*pFramePtr
- (ptrdiff_t)dli
.dli_saddr
;
128 fprintf( fp
, "(%s+0x%x)", dli
.dli_sname
, offset
);
131 fprintf( fp
, "[0x%x]\n", *pFramePtr
);
139 #endif /* defined SOLARIS */
142 #if defined FREEBSD || defined NETBSD
148 #include "backtrace.h"
150 #define FRAME_PTR_OFFSET 1
151 #define FRAME_OFFSET 0
153 int backtrace( void **buffer
, int max_frames
)
158 /* get stack- and framepointer */
160 fp
= (struct frame
*)(((size_t*)(ctx
))[FRAME_PTR_OFFSET
]);
161 for ( i
=0; (i
<FRAME_OFFSET
) && (fp
!=0); i
++)
163 /* iterate through backtrace */
164 for (i
=0; fp
&& fp
->fr_savpc
&& i
<max_frames
; i
++)
167 *(buffer
++) = (void *)fp
->fr_savpc
;
174 void backtrace_symbols_fd( void **buffer
, int size
, int fd
)
176 FILE *fp
= fdopen( fd
, "w" );
181 for ( pFramePtr
= buffer
; size
> 0 && pFramePtr
&& *pFramePtr
; pFramePtr
++, size
-- )
186 if ( 0 != dladdr( *pFramePtr
, &dli
) )
188 if ( dli
.dli_fname
&& dli
.dli_fbase
)
190 offset
= (ptrdiff_t)*pFramePtr
- (ptrdiff_t)dli
.dli_fbase
;
191 fprintf( fp
, "%s+0x%x", dli
.dli_fname
, offset
);
193 if ( dli
.dli_sname
&& dli
.dli_saddr
)
195 offset
= (ptrdiff_t)*pFramePtr
- (ptrdiff_t)dli
.dli_saddr
;
196 fprintf( fp
, "(%s+0x%x)", dli
.dli_sname
, offset
);
199 fprintf( fp
, "[0x%x]\n", *pFramePtr
);
205 #endif /* defined FREEBSD */
217 #include "backtrace.h"
221 #define FRAME_PTR_OFFSET 1
222 #define FRAME_OFFSET 0
226 #error Unknown Linux target platform.
228 #endif /* defined SPARC or INTEL */
230 typedef int ptrdiff_t;
232 int backtrace( void **buffer
, int max_frames
)
238 /* flush register windows */
242 /* get stack- and framepointer */
244 fp
= (struct frame
*)(((size_t*)(ctx
))[FRAME_PTR_OFFSET
]);
245 for ( i
=0; (i
<FRAME_OFFSET
) && (fp
!=0); i
++)
248 /* iterate through backtrace */
249 for (i
=0; fp
&& fp
->fr_savpc
&& i
<max_frames
; i
++)
252 *(buffer
++) = (void *)fp
->fr_savpc
;
259 void backtrace_symbols_fd( void **buffer
, int size
, int fd
)
261 FILE *fp
= fdopen( fd
, "w" );
267 for ( pFramePtr
= buffer
; size
> 0 && pFramePtr
&& *pFramePtr
; pFramePtr
++, size
-- )
272 if ( 0 != dladdr( *pFramePtr
, &dli
) )
274 if ( dli
.dli_fname
&& dli
.dli_fbase
)
276 offset
= (ptrdiff_t)*pFramePtr
- (ptrdiff_t)dli
.dli_fbase
;
277 fprintf( fp
, "%s+0x%x", dli
.dli_fname
, offset
);
279 if ( dli
.dli_sname
&& dli
.dli_saddr
)
281 offset
= (ptrdiff_t)*pFramePtr
- (ptrdiff_t)dli
.dli_saddr
;
282 fprintf( fp
, "(%s+0x%x)", dli
.dli_sname
, offset
);
285 fprintf( fp
, "[0x%x]\n", *pFramePtr
);
293 #endif /* defined LINUX */
295 #if defined( MACOSX )
299 #include "backtrace.h"
301 typedef unsigned ptrdiff_t;
303 /* glib backtrace is only available on MacOsX 10.5 or higher
304 so we do it on our own */
306 int backtrace( void **buffer
, int max_frames
)
308 void **frame
= (void **)__builtin_frame_address(0);
309 void **bp
= ( void **)(*frame
);
313 for ( i
= 0; bp
&& ip
&& i
< max_frames
; i
++ )
318 bp
= (void**)(bp
[0]);
325 void backtrace_symbols_fd( void **buffer
, int size
, int fd
)
327 FILE *fp
= fdopen( fd
, "w" );
333 for ( pFramePtr
= buffer
; size
> 0 && pFramePtr
&& *pFramePtr
; pFramePtr
++, size
-- )
338 if ( 0 != dladdr( *pFramePtr
, &dli
) )
340 if ( dli
.dli_fname
&& dli
.dli_fbase
)
342 offset
= (ptrdiff_t)*pFramePtr
- (ptrdiff_t)dli
.dli_fbase
;
343 fprintf( fp
, "%s+0x%x", dli
.dli_fname
, offset
);
345 if ( dli
.dli_sname
&& dli
.dli_saddr
)
347 offset
= (ptrdiff_t)*pFramePtr
- (ptrdiff_t)dli
.dli_saddr
;
348 fprintf( fp
, "(%s+0x%x)", dli
.dli_sname
, offset
);
351 fprintf( fp
, "[0x%x]\n", (unsigned int)*pFramePtr
);
359 #endif /* defined MACOSX */