]>
git.saurik.com Git - apple/libc.git/blob - gen/backtrace.c
2aaee08f3d4b8473ddb610f8a8abac5fcdf99799
2 * Copyright (c) 2007, 2008 Apple Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
21 * @APPLE_LICENSE_HEADER_END@
24 #include <mach/vm_types.h>
33 #include "stack_logging.h"
36 int backtrace(void** buffer
, int size
) {
37 extern void _thread_stack_pcs(vm_address_t
*buffer
, unsigned max
, unsigned *nb
, unsigned skip
);
38 unsigned int num_frames
;
39 _thread_stack_pcs((vm_address_t
*)buffer
, size
, &num_frames
, 1);
40 while (num_frames
>= 1 && buffer
[num_frames
-1] == NULL
) num_frames
-= 1;
45 #define _BACKTRACE_FORMAT "%-4d%-35s 0x%016lx %s + %lu"
46 #define _BACKTRACE_FORMAT_SIZE 82
48 #define _BACKTRACE_FORMAT "%-4d%-35s 0x%08lx %s + %lu"
49 #define _BACKTRACE_FORMAT_SIZE 65
53 static int _backtrace_snprintf(char* buf
, size_t size
, int frame
, const void* addr
, const Dl_info
* info
) {
55 const char* image
= "???";
56 const char* symbol
= symbuf
;
58 if (info
->dli_fname
) {
59 image
= strrchr(info
->dli_fname
, '/') + 1;
60 if (image
== NULL
) image
= info
->dli_fname
;
63 if (info
->dli_sname
) {
64 symbol
= info
->dli_sname
;
66 snprintf(symbuf
, sizeof(symbuf
), "0x%lx", (uintptr_t)info
->dli_saddr
);
69 return snprintf(buf
, size
,
75 (uintptr_t)addr
- (uintptr_t)info
->dli_saddr
) + 1;
78 char** backtrace_symbols(void* const* buffer
, int size
) {
84 Dl_info
* info
= calloc(size
, sizeof (Dl_info
));
86 if (info
== NULL
) return NULL
;
88 // Compute the total size for the block that is returned.
89 // The block will contain size number of pointers to the
90 // symbol descriptions.
92 total_bytes
= sizeof(char*) * size
;
94 // Plus each symbol description
95 for (i
= 0 ; i
< size
; ++i
) {
96 dladdr(buffer
[i
], &info
[i
]);
97 total_bytes
+= _BACKTRACE_FORMAT_SIZE
+ 1;
98 if (info
[i
].dli_sname
) total_bytes
+= strlen(info
[i
].dli_sname
);
101 result
= (char**)malloc(total_bytes
);
102 if (result
== NULL
) {
107 // Fill in the array of pointers and append the strings for
108 // each symbol description.
111 strs
= ((intptr_t)result
) + sizeof(char*) * size
;
113 for (i
= 0; i
< size
; ++i
) {
114 ptrs
[i
] = (char*)strs
;
115 strs
+= _backtrace_snprintf((char*)strs
, total_bytes
, i
, buffer
[i
], &info
[i
]);
123 void backtrace_symbols_fd(void* const* buffer
, int size
, int fd
) {
129 iov
[0].iov_base
= buf
;
131 iov
[1].iov_base
= "\n";
134 for (i
= 0; i
< size
; ++i
) {
135 memset(&info
, 0, sizeof(info
));
136 dladdr(buffer
[i
], &info
);
138 iov
[0].iov_len
= _backtrace_snprintf(buf
, sizeof(buf
), i
, buffer
[i
], &info
);