Chromium Code Reviews| 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 |