update credits
[LibreOffice.git] / sal / osl / unx / backtrace.c
blob3b50cdccccb8ab8093ee1c83b5807cee222e433f
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
21 #ifdef SOLARIS
23 #include <dlfcn.h>
24 #include <pthread.h>
25 #include <setjmp.h>
26 #include <stdio.h>
27 #include <sys/frame.h>
28 #include "backtrace.h"
30 #if defined(SPARC)
32 #if defined IS_LP64
34 #define FRAME_PTR_OFFSET 1
35 #define FRAME_OFFSET 0
36 #define STACK_BIAS 0x7ff
38 #else
40 #define FRAME_PTR_OFFSET 1
41 #define FRAME_OFFSET 0
42 #define STACK_BIAS 0
44 #endif
46 #elif defined( INTEL )
48 #define FRAME_PTR_OFFSET 3
49 #define FRAME_OFFSET 0
50 #define STACK_BIAS 0
52 #else
54 #error Unknown Solaris target platform.
56 #endif /* defined SPARC or INTEL */
59 int backtrace( void **buffer, int max_frames )
61 jmp_buf ctx;
62 long fpval;
63 struct frame *fp;
64 int i;
66 /* flush register windows */
67 #ifdef SPARC
68 asm("ta 3");
69 #endif
71 /* get stack- and framepointer */
72 setjmp(ctx);
74 fpval = ((long*)(ctx))[FRAME_PTR_OFFSET];
75 fp = (struct frame*)((char*)(fpval) + STACK_BIAS);
77 for (i = 0; (i < FRAME_OFFSET) && (fp != 0); i++)
78 fp = (struct frame*)((char*)(fp->fr_savfp) + STACK_BIAS);
80 /* iterate through backtrace */
81 for (i = 0; (fp != 0) && (fp->fr_savpc != 0) && (i < max_frames); i++)
83 /* saved (prev) frame */
84 struct frame * prev = (struct frame*)((char*)(fp->fr_savfp) + STACK_BIAS);
86 /* store frame */
87 *(buffer++) = (void*)(fp->fr_savpc);
89 /* prev frame (w/ stack growing top down) */
90 fp = (prev > fp) ? prev : 0;
93 /* return number of frames stored */
94 return i;
97 void backtrace_symbols_fd( void **buffer, int size, int fd )
99 FILE *fp = fdopen( fd, "w" );
101 if ( fp )
103 void **pFramePtr;
105 for ( pFramePtr = buffer; size > 0 && pFramePtr && *pFramePtr; pFramePtr++, size-- )
107 Dl_info dli;
108 ptrdiff_t offset;
110 if ( 0 != dladdr( *pFramePtr, &dli ) )
112 if ( dli.dli_fname && dli.dli_fbase )
114 offset = (ptrdiff_t)*pFramePtr - (ptrdiff_t)dli.dli_fbase;
115 fprintf( fp, "%s+0x%x", dli.dli_fname, offset );
117 if ( dli.dli_sname && dli.dli_saddr )
119 offset = (ptrdiff_t)*pFramePtr - (ptrdiff_t)dli.dli_saddr;
120 fprintf( fp, "(%s+0x%x)", dli.dli_sname, offset );
123 fprintf( fp, "[0x%x]\n", *pFramePtr );
126 fflush( fp );
127 fclose( fp );
131 #endif /* defined SOLARIS */
134 #if defined FREEBSD || defined NETBSD || defined OPENBSD || defined(DRAGONFLY)
135 #include <dlfcn.h>
136 #include <pthread.h>
137 #include <setjmp.h>
138 #include <stddef.h>
139 #include <stdio.h>
140 #include "backtrace.h"
142 #define FRAME_PTR_OFFSET 1
143 #define FRAME_OFFSET 0
145 int backtrace( void **buffer, int max_frames )
147 struct frame *fp;
148 jmp_buf ctx;
149 int i;
150 /* get stack- and framepointer */
151 setjmp(ctx);
152 fp = (struct frame*)(((size_t*)(ctx))[FRAME_PTR_OFFSET]);
153 for ( i=0; (i<FRAME_OFFSET) && (fp!=0); i++)
154 fp = fp->fr_savfp;
155 /* iterate through backtrace */
156 for (i=0; fp && fp->fr_savpc && i<max_frames; i++)
158 /* store frame */
159 *(buffer++) = (void *)fp->fr_savpc;
160 /* next frame */
161 fp=fp->fr_savfp;
163 return i;
166 void backtrace_symbols_fd( void **buffer, int size, int fd )
168 FILE *fp = fdopen( fd, "w" );
170 if ( fp )
172 void **pFramePtr;
173 for ( pFramePtr = buffer; size > 0 && pFramePtr && *pFramePtr; pFramePtr++, size-- )
175 Dl_info dli;
176 ptrdiff_t offset;
178 if ( 0 != dladdr( *pFramePtr, &dli ) )
180 if ( dli.dli_fname && dli.dli_fbase )
182 offset = (ptrdiff_t)*pFramePtr - (ptrdiff_t)dli.dli_fbase;
183 fprintf( fp, "%s+0x%x", dli.dli_fname, offset );
185 if ( dli.dli_sname && dli.dli_saddr )
187 offset = (ptrdiff_t)*pFramePtr - (ptrdiff_t)dli.dli_saddr;
188 fprintf( fp, "(%s+0x%x)", dli.dli_sname, offset );
191 fprintf( fp, "[0x%x]\n", *pFramePtr );
193 fflush( fp );
194 fclose( fp );
197 #endif /* defined FREEBSD */
199 #ifdef LINUX
201 #ifndef _GNU_SOURCE
202 #define _GNU_SOURCE
203 #endif
205 #endif /* defined LINUX */
207 #if defined( MACOSX )
209 #include <dlfcn.h>
210 #include <stdio.h>
211 #include "backtrace.h"
213 typedef unsigned ptrdiff_t;
215 /* glib backtrace is only available on MacOsX 10.5 or higher
216 so we do it on our own */
218 int backtrace( void **buffer, int max_frames )
220 void **frame = (void **)__builtin_frame_address(0);
221 void **bp = ( void **)(*frame);
222 void *ip = frame[1];
223 int i;
225 for ( i = 0; bp && ip && i < max_frames; i++ )
227 *(buffer++) = ip;
229 ip = bp[1];
230 bp = (void**)(bp[0]);
233 return i;
237 void backtrace_symbols_fd( void **buffer, int size, int fd )
239 FILE *fp = fdopen( fd, "w" );
241 if ( fp )
243 void **pFramePtr;
245 for ( pFramePtr = buffer; size > 0 && pFramePtr && *pFramePtr; pFramePtr++, size-- )
247 Dl_info dli;
249 if ( 0 != dladdr( *pFramePtr, &dli ) )
251 ptrdiff_t offset;
253 if ( dli.dli_fname && dli.dli_fbase )
255 offset = (ptrdiff_t)*pFramePtr - (ptrdiff_t)dli.dli_fbase;
256 fprintf( fp, "%s+0x%x", dli.dli_fname, offset );
258 if ( dli.dli_sname && dli.dli_saddr )
260 offset = (ptrdiff_t)*pFramePtr - (ptrdiff_t)dli.dli_saddr;
261 fprintf( fp, "(%s+0x%x)", dli.dli_sname, offset );
264 fprintf( fp, "[0x%x]\n", (unsigned int)*pFramePtr );
267 fflush( fp );
268 fclose( fp );
272 #endif /* defined MACOSX */
274 #if defined(AIX)
275 int backtrace( void **buffer, int max_frames )
277 return 0;
280 void backtrace_symbols_fd( void **buffer, int size, int fd )
283 #endif
285 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */