]>
git.saurik.com Git - apple/xnu.git/blob - libkern/gen/OSDebug.cpp
cf974524119d990ee68168e586b4a7d3d5f6b24f
2 * Copyright (c) 2005 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_OSREFERENCE_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. The rights granted to you under the
10 * License may not be used to create, or enable the creation or
11 * redistribution of, unlawful or unlicensed copies of an Apple operating
12 * system, or to circumvent, violate, or enable the circumvention or
13 * violation of, any terms of an Apple operating system software license
16 * Please obtain a copy of the License at
17 * http://www.opensource.apple.com/apsl/ and read it before using this
20 * The Original Code and all software distributed under the License are
21 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
22 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
23 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
24 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
25 * Please see the License for the specific language governing rights and
26 * limitations under the License.
28 * @APPLE_LICENSE_OSREFERENCE_HEADER_END@
31 // NOTE: This file is only c++ so I can get static initialisers going
32 #include <libkern/OSDebug.h>
34 #include <sys/cdefs.h>
37 #include <mach/mach_types.h>
38 #include <mach/kmod.h>
39 #include <kern/lock.h>
41 #include <libkern/libkern.h> // From bsd's libkern directory
44 // From osmfk/kern/thread.h but considered to be private
45 extern vm_offset_t
min_valid_stack_address(void);
46 extern vm_offset_t
max_valid_stack_address(void);
49 extern void kmod_dump_log(vm_offset_t
*addr
, unsigned int cnt
);
52 static mutex_t
*sOSReportLock
= mutex_alloc(0);
54 /* Report a message with a 4 entry backtrace - very slow */
56 OSReportWithBacktrace(const char *str
, ...)
60 const unsigned cnt
= sizeof(bt
) / sizeof(bt
[0]);
63 // Ignore the our and our callers stackframes, skipping frames 0 & 1
64 (void) OSBacktrace(bt
, cnt
);
67 vsnprintf(buf
, sizeof(buf
), str
, listp
);
70 mutex_lock(sOSReportLock
);
72 printf("%s\nBacktrace %p %p %p %p %p %p %p\n",
73 buf
, bt
[2], bt
[3], bt
[4], bt
[5], bt
[6], bt
[7], bt
[8]);
74 kmod_dump_log((vm_offset_t
*) &bt
[2], cnt
- 2);
76 mutex_unlock(sOSReportLock
);
79 static vm_offset_t minstackaddr
= min_valid_stack_address();
80 static vm_offset_t maxstackaddr
= max_valid_stack_address();
82 unsigned OSBacktrace(void **bt
, unsigned maxAddrs
)
87 vm_offset_t stackptr
, stackptr_prev
;
88 const vm_offset_t
* const mem
= (vm_offset_t
*) 0;
91 __asm__
volatile("mflr %0" : "=r" (stackptr
));
92 bt
[i
++] = (void *) stackptr
;
94 __asm__
volatile("mr %0,r1" : "=r" (stackptr
));
95 for ( ; i
< maxAddrs
; i
++) {
96 // Validate we have a reasonable stackptr
97 if ( !(minstackaddr
<= stackptr
&& stackptr
< maxstackaddr
)
101 stackptr_prev
= stackptr
;
102 stackptr
= mem
[stackptr_prev
>> 2];
103 if ((stackptr_prev
^ stackptr
) > 8 * 1024) // Sanity check
106 vm_offset_t addr
= mem
[(stackptr
>> 2) + 2];
107 if ((addr
& 3) || (addr
< 0x8000)) // More sanity checks
109 bt
[i
] = (void *) addr
;
113 for ( ; i
< maxAddrs
; i
++)
115 #elif 0 && __i386__ // Note that this should be ported for i386
116 // This function is not safe, we should get this code ported appropriately
118 for (frame
= 16; frame
< maxAddrs
; frame
++)
119 bt
[frame
] = __builtin_return_address(frame
);
124 case 15+1: bt
[15] = __builtin_return_address(15);
125 case 14+1: bt
[14] = __builtin_return_address(14);
126 case 13+1: bt
[13] = __builtin_return_address(13);
127 case 12+1: bt
[12] = __builtin_return_address(12);
128 case 11+1: bt
[11] = __builtin_return_address(11);
129 case 10+1: bt
[10] = __builtin_return_address(10);
130 case 9+1: bt
[ 9] = __builtin_return_address( 9);
131 case 8+1: bt
[ 8] = __builtin_return_address( 8);
132 case 7+1: bt
[ 7] = __builtin_return_address( 7);
133 case 6+1: bt
[ 6] = __builtin_return_address( 6);
134 case 5+1: bt
[ 5] = __builtin_return_address( 5);
135 case 4+1: bt
[ 4] = __builtin_return_address( 4);
136 case 3+1: bt
[ 3] = __builtin_return_address( 3);
137 case 2+1: bt
[ 2] = __builtin_return_address( 2);
138 case 1+1: bt
[ 1] = __builtin_return_address( 1);
139 case 0+1: bt
[ 0] = __builtin_return_address( 0);
140 case 0: default: break;
145 // This function is not safe, we should get this code ported appropriately
147 for (frame
= 16; frame
< maxAddrs
; frame
++)
153 case 15+1: bt
[15] = __builtin_return_address(15);
154 case 14+1: bt
[14] = __builtin_return_address(14);
155 case 13+1: bt
[13] = __builtin_return_address(13);
156 case 12+1: bt
[12] = __builtin_return_address(12);
157 case 11+1: bt
[11] = __builtin_return_address(11);
158 case 10+1: bt
[10] = __builtin_return_address(10);
159 case 9+1: bt
[ 9] = __builtin_return_address( 9);
160 case 8+1: bt
[ 8] = __builtin_return_address( 8);
161 case 7+1: bt
[ 7] = __builtin_return_address( 7);
162 case 6+1: bt
[ 6] = __builtin_return_address( 6);
163 case 5+1: bt
[ 5] = __builtin_return_address( 5);
164 case 4+1: bt
[ 4] = __builtin_return_address( 4);
165 case 3+1: bt
[ 3] = __builtin_return_address( 3);
166 case 2+1: bt
[ 2] = __builtin_return_address( 2);
167 case 1+1: bt
[ 1] = __builtin_return_address( 1);
168 case 0+1: bt
[ 0] = __builtin_return_address( 0);