OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "base/debug/debugger.h" | 5 #include "base/debug/debugger.h" |
6 #include "build/build_config.h" | 6 #include "build/build_config.h" |
7 | 7 |
8 #include <errno.h> | 8 #include <errno.h> |
9 #include <fcntl.h> | 9 #include <fcntl.h> |
10 #include <stdio.h> | 10 #include <stdio.h> |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
72 return false; | 72 return false; |
73 return true; | 73 return true; |
74 #endif | 74 #endif |
75 } | 75 } |
76 | 76 |
77 #if defined(OS_MACOSX) || defined(OS_BSD) | 77 #if defined(OS_MACOSX) || defined(OS_BSD) |
78 | 78 |
79 // Based on Apple's recommended method as described in | 79 // Based on Apple's recommended method as described in |
80 // http://developer.apple.com/qa/qa2004/qa1361.html | 80 // http://developer.apple.com/qa/qa2004/qa1361.html |
81 bool BeingDebugged() { | 81 bool BeingDebugged() { |
82 // NOTE: This code MUST be async-signal safe (it's used by in-process | |
83 // stack dumping signal handler). NO malloc or stdio is allowed here. | |
84 // While some code used below may be async-signal unsafe, note how | |
jar (doing other things)
2012/11/02 02:36:57
Please be specific (don't ask me to find the offen
Paweł Hajdan Jr.
2012/11/06 17:58:46
Done.
| |
85 // the result is cached. If this code is properly warmed-up early | |
86 // in the start-up process, it should be safe to use later. | |
87 | |
82 // If the process is sandboxed then we can't use the sysctl, so cache the | 88 // If the process is sandboxed then we can't use the sysctl, so cache the |
83 // value. | 89 // value. |
84 static bool is_set = false; | 90 static bool is_set = false; |
85 static bool being_debugged = false; | 91 static bool being_debugged = false; |
86 | 92 |
87 if (is_set) { | 93 if (is_set) |
88 return being_debugged; | 94 return being_debugged; |
89 } | |
90 | 95 |
91 // Initialize mib, which tells sysctl what info we want. In this case, | 96 // Initialize mib, which tells sysctl what info we want. In this case, |
92 // we're looking for information about a specific process ID. | 97 // we're looking for information about a specific process ID. |
93 int mib[] = { | 98 int mib[] = { |
94 CTL_KERN, | 99 CTL_KERN, |
95 KERN_PROC, | 100 KERN_PROC, |
96 KERN_PROC_PID, | 101 KERN_PROC_PID, |
97 getpid() | 102 getpid() |
98 #if defined(OS_OPENBSD) | 103 #if defined(OS_OPENBSD) |
99 , sizeof(struct kinfo_proc), | 104 , sizeof(struct kinfo_proc), |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
134 } | 139 } |
135 | 140 |
136 #elif defined(OS_LINUX) || defined(OS_ANDROID) | 141 #elif defined(OS_LINUX) || defined(OS_ANDROID) |
137 | 142 |
138 // We can look in /proc/self/status for TracerPid. We are likely used in crash | 143 // We can look in /proc/self/status for TracerPid. We are likely used in crash |
139 // handling, so we are careful not to use the heap or have side effects. | 144 // handling, so we are careful not to use the heap or have side effects. |
140 // Another option that is common is to try to ptrace yourself, but then we | 145 // Another option that is common is to try to ptrace yourself, but then we |
141 // can't detach without forking(), and that's not so great. | 146 // can't detach without forking(), and that's not so great. |
142 // static | 147 // static |
143 bool BeingDebugged() { | 148 bool BeingDebugged() { |
149 // NOTE: This code MUST be async-signal safe (it's used by in-process | |
150 // stack dumping signal handler). NO malloc or stdio is allowed here. | |
151 | |
144 int status_fd = open("/proc/self/status", O_RDONLY); | 152 int status_fd = open("/proc/self/status", O_RDONLY); |
145 if (status_fd == -1) | 153 if (status_fd == -1) |
146 return false; | 154 return false; |
147 | 155 |
148 // We assume our line will be in the first 1024 characters and that we can | 156 // We assume our line will be in the first 1024 characters and that we can |
149 // read this much all at once. In practice this will generally be true. | 157 // read this much all at once. In practice this will generally be true. |
150 // This simplifies and speeds up things considerably. | 158 // This simplifies and speeds up things considerably. |
151 char buf[1024]; | 159 char buf[1024]; |
152 | 160 |
153 ssize_t num_read = HANDLE_EINTR(read(status_fd, buf, sizeof(buf))); | 161 ssize_t num_read = HANDLE_EINTR(read(status_fd, buf, sizeof(buf))); |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
222 // ARM && !ANDROID | 230 // ARM && !ANDROID |
223 #define DEBUG_BREAK() asm("bkpt 0") | 231 #define DEBUG_BREAK() asm("bkpt 0") |
224 #endif | 232 #endif |
225 #elif defined(ARCH_CPU_MIPS_FAMILY) | 233 #elif defined(ARCH_CPU_MIPS_FAMILY) |
226 #define DEBUG_BREAK() asm("break 2") | 234 #define DEBUG_BREAK() asm("break 2") |
227 #else | 235 #else |
228 #define DEBUG_BREAK() asm("int3") | 236 #define DEBUG_BREAK() asm("int3") |
229 #endif | 237 #endif |
230 | 238 |
231 void BreakDebugger() { | 239 void BreakDebugger() { |
240 // NOTE: This code MUST be async-signal safe (it's used by in-process | |
241 // stack dumping signal handler). NO malloc or stdio is allowed here. | |
242 | |
232 DEBUG_BREAK(); | 243 DEBUG_BREAK(); |
233 #if defined(OS_ANDROID) && !defined(OFFICIAL_BUILD) | 244 #if defined(OS_ANDROID) && !defined(OFFICIAL_BUILD) |
234 // For Android development we always build release (debug builds are | 245 // For Android development we always build release (debug builds are |
235 // unmanageably large), so the unofficial build is used for debugging. It is | 246 // unmanageably large), so the unofficial build is used for debugging. It is |
236 // helpful to be able to insert BreakDebugger() statements in the source, | 247 // helpful to be able to insert BreakDebugger() statements in the source, |
237 // attach the debugger, inspect the state of the program and then resume it by | 248 // attach the debugger, inspect the state of the program and then resume it by |
238 // setting the 'go' variable above. | 249 // setting the 'go' variable above. |
239 #elif defined(NDEBUG) | 250 #elif defined(NDEBUG) |
240 // Terminate the program after signaling the debug break. | 251 // Terminate the program after signaling the debug break. |
241 _exit(1); | 252 _exit(1); |
242 #endif | 253 #endif |
243 } | 254 } |
244 | 255 |
245 } // namespace debug | 256 } // namespace debug |
246 } // namespace base | 257 } // namespace base |
OLD | NEW |