Bump for 3.6-28
[LibreOffice.git] / sal / osl / unx / backtrace.c
blob01ff18f3713b9f88d46a45ab59448344e493e604
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 ************************************************************************/
30 #ifdef SOLARIS
32 #include <dlfcn.h>
33 #include <pthread.h>
34 #include <setjmp.h>
35 #include <stdio.h>
36 #include <sys/frame.h>
37 #include "backtrace.h"
39 #if defined(SPARC)
41 #if defined IS_LP64
43 #define FRAME_PTR_OFFSET 1
44 #define FRAME_OFFSET 0
45 #define STACK_BIAS 0x7ff
47 #else
49 #define FRAME_PTR_OFFSET 1
50 #define FRAME_OFFSET 0
51 #define STACK_BIAS 0
53 #endif
55 #elif defined( INTEL )
57 #define FRAME_PTR_OFFSET 3
58 #define FRAME_OFFSET 0
59 #define STACK_BIAS 0
61 #else
63 #error Unknown Solaris target platform.
65 #endif /* defined SPARC or INTEL */
68 int backtrace( void **buffer, int max_frames )
70 jmp_buf ctx;
71 long fpval;
72 struct frame *fp;
73 int i;
75 /* flush register windows */
76 #ifdef SPARC
77 asm("ta 3");
78 #endif
80 /* get stack- and framepointer */
81 setjmp(ctx);
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);
95 /* store frame */
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 */
103 return i;
106 void backtrace_symbols_fd( void **buffer, int size, int fd )
108 FILE *fp = fdopen( fd, "w" );
110 if ( fp )
112 void **pFramePtr;
114 for ( pFramePtr = buffer; size > 0 && pFramePtr && *pFramePtr; pFramePtr++, size-- )
116 Dl_info dli;
117 ptrdiff_t offset;
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 );
135 fflush( fp );
136 fclose( fp );
140 #endif /* defined SOLARIS */
143 #if defined FREEBSD || defined NETBSD || defined OPENBSD || defined(DRAGONFLY)
144 #include <dlfcn.h>
145 #include <pthread.h>
146 #include <setjmp.h>
147 #include <stddef.h>
148 #include <stdio.h>
149 #include "backtrace.h"
151 #define FRAME_PTR_OFFSET 1
152 #define FRAME_OFFSET 0
154 int backtrace( void **buffer, int max_frames )
156 struct frame *fp;
157 jmp_buf ctx;
158 int i;
159 /* get stack- and framepointer */
160 setjmp(ctx);
161 fp = (struct frame*)(((size_t*)(ctx))[FRAME_PTR_OFFSET]);
162 for ( i=0; (i<FRAME_OFFSET) && (fp!=0); i++)
163 fp = fp->fr_savfp;
164 /* iterate through backtrace */
165 for (i=0; fp && fp->fr_savpc && i<max_frames; i++)
167 /* store frame */
168 *(buffer++) = (void *)fp->fr_savpc;
169 /* next frame */
170 fp=fp->fr_savfp;
172 return i;
175 void backtrace_symbols_fd( void **buffer, int size, int fd )
177 FILE *fp = fdopen( fd, "w" );
179 if ( fp )
181 void **pFramePtr;
182 for ( pFramePtr = buffer; size > 0 && pFramePtr && *pFramePtr; pFramePtr++, size-- )
184 Dl_info dli;
185 ptrdiff_t offset;
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 );
202 fflush( fp );
203 fclose( fp );
206 #endif /* defined FREEBSD */
208 #ifdef LINUX
210 #ifndef _GNU_SOURCE
211 #define _GNU_SOURCE
212 #endif
214 #endif /* defined LINUX */
216 #if defined( MACOSX )
218 #include <dlfcn.h>
219 #include <stdio.h>
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);
231 void *ip = frame[1];
232 int i;
234 for ( i = 0; bp && ip && i < max_frames; i++ )
236 *(buffer++) = ip;
238 ip = bp[1];
239 bp = (void**)(bp[0]);
242 return i;
246 void backtrace_symbols_fd( void **buffer, int size, int fd )
248 FILE *fp = fdopen( fd, "w" );
250 if ( fp )
252 void **pFramePtr;
254 for ( pFramePtr = buffer; size > 0 && pFramePtr && *pFramePtr; pFramePtr++, size-- )
256 Dl_info dli;
258 if ( 0 != dladdr( *pFramePtr, &dli ) )
260 ptrdiff_t offset;
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 );
276 fflush( fp );
277 fclose( fp );
281 #endif /* defined MACOSX */
283 #if defined(AIX)
284 int backtrace( void **buffer, int max_frames )
286 return 0;
289 void backtrace_symbols_fd( void **buffer, int size, int fd )
292 #endif
294 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */