update dev300-m57
[ooovba.git] / sal / osl / unx / backtrace.c
blobdef6d3192f607e76c6100a30f90a89d717ad5b96
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: backtrace.c,v $
10 * $Revision: 1.15 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
32 #ifdef SOLARIS
34 #include <dlfcn.h>
35 #include <pthread.h>
36 #include <setjmp.h>
37 #include <stdio.h>
38 #include <sys/frame.h>
39 #include "backtrace.h"
41 #if defined(SPARC)
43 #if defined IS_LP64
45 #define FRAME_PTR_OFFSET 1
46 #define FRAME_OFFSET 0
47 #define STACK_BIAS 0x7ff
49 #else
51 #define FRAME_PTR_OFFSET 1
52 #define FRAME_OFFSET 0
53 #define STACK_BIAS 0
55 #endif
57 #elif defined( INTEL )
59 #define FRAME_PTR_OFFSET 3
60 #define FRAME_OFFSET 0
61 #define STACK_BIAS 0
63 #else
65 #error Unknown Solaris target platform.
67 #endif /* defined SPARC or INTEL */
70 int backtrace( void **buffer, int max_frames )
72 jmp_buf ctx;
73 long fpval;
74 struct frame *fp;
75 int i;
77 /* flush register windows */
78 #ifdef SPARC
79 asm("ta 3");
80 #endif
82 /* get stack- and framepointer */
83 setjmp(ctx);
85 fpval = ((long*)(ctx))[FRAME_PTR_OFFSET];
86 fp = (struct frame*)((char*)(fpval) + STACK_BIAS);
88 for (i = 0; (i < FRAME_OFFSET) && (fp != 0); i++)
89 fp = (struct frame*)((char*)(fp->fr_savfp) + STACK_BIAS);
91 /* iterate through backtrace */
92 for (i = 0; (fp != 0) && (fp->fr_savpc != 0) && (i < max_frames); i++)
94 /* saved (prev) frame */
95 struct frame * prev = (struct frame*)((char*)(fp->fr_savfp) + STACK_BIAS);
97 /* store frame */
98 *(buffer++) = (void*)(fp->fr_savpc);
100 /* prev frame (w/ stack growing top down) */
101 fp = (prev > fp) ? prev : 0;
104 /* return number of frames stored */
105 return i;
108 void backtrace_symbols_fd( void **buffer, int size, int fd )
110 FILE *fp = fdopen( fd, "w" );
112 if ( fp )
114 void **pFramePtr;
116 for ( pFramePtr = buffer; size > 0 && pFramePtr && *pFramePtr; pFramePtr++, size-- )
118 Dl_info dli;
119 ptrdiff_t offset;
121 if ( 0 != dladdr( *pFramePtr, &dli ) )
123 if ( dli.dli_fname && dli.dli_fbase )
125 offset = (ptrdiff_t)*pFramePtr - (ptrdiff_t)dli.dli_fbase;
126 fprintf( fp, "%s+0x%x", dli.dli_fname, offset );
128 if ( dli.dli_sname && dli.dli_saddr )
130 offset = (ptrdiff_t)*pFramePtr - (ptrdiff_t)dli.dli_saddr;
131 fprintf( fp, "(%s+0x%x)", dli.dli_sname, offset );
134 fprintf( fp, "[0x%x]\n", *pFramePtr );
137 fflush( fp );
138 fclose( fp );
142 #endif /* defined SOLARIS */
145 #if defined FREEBSD || defined NETBSD
146 #include <dlfcn.h>
147 #include <pthread.h>
148 #include <setjmp.h>
149 #include <stddef.h>
150 #include <stdio.h>
151 #include "backtrace.h"
153 #define FRAME_PTR_OFFSET 1
154 #define FRAME_OFFSET 0
156 int backtrace( void **buffer, int max_frames )
158 struct frame *fp;
159 jmp_buf ctx;
160 int i;
161 /* get stack- and framepointer */
162 setjmp(ctx);
163 fp = (struct frame*)(((size_t*)(ctx))[FRAME_PTR_OFFSET]);
164 for ( i=0; (i<FRAME_OFFSET) && (fp!=0); i++)
165 fp = fp->fr_savfp;
166 /* iterate through backtrace */
167 for (i=0; fp && fp->fr_savpc && i<max_frames; i++)
169 /* store frame */
170 *(buffer++) = (void *)fp->fr_savpc;
171 /* next frame */
172 fp=fp->fr_savfp;
174 return i;
177 void backtrace_symbols_fd( void **buffer, int size, int fd )
179 FILE *fp = fdopen( fd, "w" );
181 if ( fp )
183 void **pFramePtr;
184 for ( pFramePtr = buffer; size > 0 && pFramePtr && *pFramePtr; pFramePtr++, size-- )
186 Dl_info dli;
187 ptrdiff_t offset;
189 if ( 0 != dladdr( *pFramePtr, &dli ) )
191 if ( dli.dli_fname && dli.dli_fbase )
193 offset = (ptrdiff_t)*pFramePtr - (ptrdiff_t)dli.dli_fbase;
194 fprintf( fp, "%s+0x%x", dli.dli_fname, offset );
196 if ( dli.dli_sname && dli.dli_saddr )
198 offset = (ptrdiff_t)*pFramePtr - (ptrdiff_t)dli.dli_saddr;
199 fprintf( fp, "(%s+0x%x)", dli.dli_sname, offset );
202 fprintf( fp, "[0x%x]\n", *pFramePtr );
204 fflush( fp );
205 fclose( fp );
208 #endif /* defined FREEBSD */
210 #if defined(IRIX)
211 #include <stdio.h>
212 #include <rld_interface.h>
213 #include <exception.h>
214 #include <sys/signal.h>
215 #include <unistd.h>
217 /* Need extra libs -lexc -ldwarf -lelf */
219 int backtrace( void **buffer, int max_frames )
221 struct sigcontext context;
222 int i = 0;
224 memset(&context, 0, sizeof(struct sigcontext));
226 exc_setjmp(&context);
227 while(context.sc_pc != 1 && i < max_frames) {
228 exc_unwind(&context, 0);
229 if(context.sc_pc != 1) {
230 *(buffer++) = (void *)context.sc_pc;
231 i++;
234 return(i);
237 void backtrace_symbols_fd( void **buffer, int size, int fd )
239 FILE *fp = fdopen( fd, "w" );
240 struct sigcontext context;
241 char *name;
243 if ( fp ) {
244 while(context.sc_pc!=1) {
245 if(context.sc_pc != 1) {
246 exc_unwind_name(&context, 0, &name);
247 fprintf(fp, " 0x%012lx %.100s\n", context.sc_pc, name ? name : "<unknown function>");
248 free(name);
252 fflush( fp );
253 fclose( fp );
256 #endif /* defined IRIX */
258 #ifdef LINUX
260 #ifndef _GNU_SOURCE
261 #define _GNU_SOURCE
262 #endif
264 #include <dlfcn.h>
265 #include <pthread.h>
266 #include <setjmp.h>
267 #include <stdio.h>
268 #include "backtrace.h"
270 #if defined(SPARC)
272 #define FRAME_PTR_OFFSET 1
273 #define FRAME_OFFSET 0
275 #else
277 #error Unknown Linux target platform.
279 #endif /* defined SPARC or INTEL */
281 typedef int ptrdiff_t;
283 int backtrace( void **buffer, int max_frames )
285 struct frame *fp;
286 jmp_buf ctx;
287 int i;
289 /* flush register windows */
290 #ifdef SPARC
291 asm("ta 3");
292 #endif
293 /* get stack- and framepointer */
294 setjmp(ctx);
295 fp = (struct frame*)(((size_t*)(ctx))[FRAME_PTR_OFFSET]);
296 for ( i=0; (i<FRAME_OFFSET) && (fp!=0); i++)
297 fp = fp->fr_savfp;
299 /* iterate through backtrace */
300 for (i=0; fp && fp->fr_savpc && i<max_frames; i++)
302 /* store frame */
303 *(buffer++) = (void *)fp->fr_savpc;
304 /* next frame */
305 fp=fp->fr_savfp;
307 return i;
310 void backtrace_symbols_fd( void **buffer, int size, int fd )
312 FILE *fp = fdopen( fd, "w" );
314 if ( fp )
316 void **pFramePtr;
318 for ( pFramePtr = buffer; size > 0 && pFramePtr && *pFramePtr; pFramePtr++, size-- )
320 Dl_info dli;
321 ptrdiff_t offset;
323 if ( 0 != dladdr( *pFramePtr, &dli ) )
325 if ( dli.dli_fname && dli.dli_fbase )
327 offset = (ptrdiff_t)*pFramePtr - (ptrdiff_t)dli.dli_fbase;
328 fprintf( fp, "%s+0x%x", dli.dli_fname, offset );
330 if ( dli.dli_sname && dli.dli_saddr )
332 offset = (ptrdiff_t)*pFramePtr - (ptrdiff_t)dli.dli_saddr;
333 fprintf( fp, "(%s+0x%x)", dli.dli_sname, offset );
336 fprintf( fp, "[0x%x]\n", *pFramePtr );
339 fflush( fp );
340 fclose( fp );
344 #endif /* defined LINUX */
346 #if defined( MACOSX )
348 #include <dlfcn.h>
349 #include <stdio.h>
350 #include "backtrace.h"
352 typedef unsigned ptrdiff_t;
354 /* glib backtrace is only available on MacOsX 10.5 or higher
355 so we do it on our own */
357 int backtrace( void **buffer, int max_frames )
359 void **frame = (void **)__builtin_frame_address(0);
360 void **bp = ( void **)(*frame);
361 void *ip = frame[1];
362 int i;
364 for ( i = 0; bp && ip && i < max_frames; i++ )
366 *(buffer++) = ip;
368 ip = bp[1];
369 bp = (void**)(bp[0]);
372 return i;
376 void backtrace_symbols_fd( void **buffer, int size, int fd )
378 FILE *fp = fdopen( fd, "w" );
380 if ( fp )
382 void **pFramePtr;
384 for ( pFramePtr = buffer; size > 0 && pFramePtr && *pFramePtr; pFramePtr++, size-- )
386 Dl_info dli;
387 ptrdiff_t offset;
389 if ( 0 != dladdr( *pFramePtr, &dli ) )
391 if ( dli.dli_fname && dli.dli_fbase )
393 offset = (ptrdiff_t)*pFramePtr - (ptrdiff_t)dli.dli_fbase;
394 fprintf( fp, "%s+0x%x", dli.dli_fname, offset );
396 if ( dli.dli_sname && dli.dli_saddr )
398 offset = (ptrdiff_t)*pFramePtr - (ptrdiff_t)dli.dli_saddr;
399 fprintf( fp, "(%s+0x%x)", dli.dli_sname, offset );
402 fprintf( fp, "[0x%x]\n", (unsigned int)*pFramePtr );
405 fflush( fp );
406 fclose( fp );
410 #endif /* defined MACOSX */