| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 <execinfo.h> | 9 #include <execinfo.h> |
| 10 #include <fcntl.h> | 10 #include <fcntl.h> |
| (...skipping 26 matching lines...) Expand all Loading... |
| 37 #include "base/logging.h" | 37 #include "base/logging.h" |
| 38 #include "base/memory/scoped_ptr.h" | 38 #include "base/memory/scoped_ptr.h" |
| 39 #include "base/safe_strerror_posix.h" | 39 #include "base/safe_strerror_posix.h" |
| 40 #include "base/string_piece.h" | 40 #include "base/string_piece.h" |
| 41 #include "base/stringprintf.h" | 41 #include "base/stringprintf.h" |
| 42 | 42 |
| 43 #if defined(USE_SYMBOLIZE) | 43 #if defined(USE_SYMBOLIZE) |
| 44 #include "base/third_party/symbolize/symbolize.h" | 44 #include "base/third_party/symbolize/symbolize.h" |
| 45 #endif | 45 #endif |
| 46 | 46 |
| 47 #if defined(OS_ANDROID) |
| 48 #include <execinfo.h> |
| 49 #include "base/threading/platform_thread.h" |
| 50 #endif |
| 51 |
| 47 namespace base { | 52 namespace base { |
| 48 namespace debug { | 53 namespace debug { |
| 49 | 54 |
| 50 bool SpawnDebuggerOnProcess(unsigned /* process_id */) { | 55 bool SpawnDebuggerOnProcess(unsigned /* process_id */) { |
| 51 NOTIMPLEMENTED(); | 56 NOTIMPLEMENTED(); |
| 52 return false; | 57 return false; |
| 53 } | 58 } |
| 54 | 59 |
| 55 #if defined(OS_MACOSX) | 60 #if defined(OS_MACOSX) |
| 56 | 61 |
| (...skipping 30 matching lines...) Expand all Loading... |
| 87 being_debugged = false; | 92 being_debugged = false; |
| 88 return being_debugged; | 93 return being_debugged; |
| 89 } | 94 } |
| 90 | 95 |
| 91 // This process is being debugged if the P_TRACED flag is set. | 96 // This process is being debugged if the P_TRACED flag is set. |
| 92 is_set = true; | 97 is_set = true; |
| 93 being_debugged = (info.kp_proc.p_flag & P_TRACED) != 0; | 98 being_debugged = (info.kp_proc.p_flag & P_TRACED) != 0; |
| 94 return being_debugged; | 99 return being_debugged; |
| 95 } | 100 } |
| 96 | 101 |
| 97 #elif defined(OS_LINUX) | 102 #elif defined(OS_LINUX) || defined(OS_ANDROID) |
| 98 | 103 |
| 99 // We can look in /proc/self/status for TracerPid. We are likely used in crash | 104 // We can look in /proc/self/status for TracerPid. We are likely used in crash |
| 100 // handling, so we are careful not to use the heap or have side effects. | 105 // handling, so we are careful not to use the heap or have side effects. |
| 101 // Another option that is common is to try to ptrace yourself, but then we | 106 // Another option that is common is to try to ptrace yourself, but then we |
| 102 // can't detach without forking(), and that's not so great. | 107 // can't detach without forking(), and that's not so great. |
| 103 // static | 108 // static |
| 104 bool BeingDebugged() { | 109 bool BeingDebugged() { |
| 105 int status_fd = open("/proc/self/status", O_RDONLY); | 110 int status_fd = open("/proc/self/status", O_RDONLY); |
| 106 if (status_fd == -1) | 111 if (status_fd == -1) |
| 107 return false; | 112 return false; |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 154 // | OS | Dump on SIGTRAP | Dump on SIGABRT | | 159 // | OS | Dump on SIGTRAP | Dump on SIGABRT | |
| 155 // +-------+-----------------+-----------------+ | 160 // +-------+-----------------+-----------------+ |
| 156 // | Linux | N | Y | | 161 // | Linux | N | Y | |
| 157 // | Mac | Y | N | | 162 // | Mac | Y | N | |
| 158 // +-------+-----------------+-----------------+ | 163 // +-------+-----------------+-----------------+ |
| 159 // | 164 // |
| 160 // Thus we do the following: | 165 // Thus we do the following: |
| 161 // Linux: Debug mode, send SIGTRAP; Release mode, send SIGABRT. | 166 // Linux: Debug mode, send SIGTRAP; Release mode, send SIGABRT. |
| 162 // Mac: Always send SIGTRAP. | 167 // Mac: Always send SIGTRAP. |
| 163 | 168 |
| 164 #if defined(NDEBUG) && !defined(OS_MACOSX) | 169 #if defined(NDEBUG) && !defined(OS_MACOSX) && !defined(OS_ANDROID) |
| 165 #define DEBUG_BREAK() abort() | 170 #define DEBUG_BREAK() abort() |
| 166 #elif defined(OS_NACL) | 171 #elif defined(OS_NACL) |
| 167 // The NaCl verifier doesn't let use use int3. For now, we call abort(). We | 172 // The NaCl verifier doesn't let use use int3. For now, we call abort(). We |
| 168 // should ask for advice from some NaCl experts about the optimum thing here. | 173 // should ask for advice from some NaCl experts about the optimum thing here. |
| 169 // http://code.google.com/p/nativeclient/issues/detail?id=645 | 174 // http://code.google.com/p/nativeclient/issues/detail?id=645 |
| 170 #define DEBUG_BREAK() abort() | 175 #define DEBUG_BREAK() abort() |
| 171 #elif defined(ARCH_CPU_ARM_FAMILY) | 176 #elif defined(ARCH_CPU_ARM_FAMILY) |
| 177 #if defined(OS_ANDROID) |
| 178 // Though Android has a "helpful" process called debuggerd to catch native |
| 179 // signals on the general assumption that they are fatal errors, we've had great |
| 180 // difficulty continuing in a debugger once we stop from SIGINT triggered by |
| 181 // native code. |
| 182 // |
| 183 // Use GDB to set |go| to 1 to resume execution. |
| 184 #define DEBUG_BREAK() do { \ |
| 185 volatile int go = 0; \ |
| 186 while (!go) { base::PlatformThread::Sleep(100); } \ |
| 187 } while (0) |
| 188 #else |
| 189 // ARM && !ANDROID |
| 172 #define DEBUG_BREAK() asm("bkpt 0") | 190 #define DEBUG_BREAK() asm("bkpt 0") |
| 191 #endif |
| 173 #else | 192 #else |
| 174 #define DEBUG_BREAK() asm("int3") | 193 #define DEBUG_BREAK() asm("int3") |
| 175 #endif | 194 #endif |
| 176 | 195 |
| 177 void BreakDebugger() { | 196 void BreakDebugger() { |
| 178 DEBUG_BREAK(); | 197 DEBUG_BREAK(); |
| 179 #if defined(NDEBUG) | 198 #if defined(NDEBUG) |
| 180 _exit(1); | 199 _exit(1); |
| 181 #endif | 200 #endif |
| 182 } | 201 } |
| 183 | 202 |
| 184 } // namespace debug | 203 } // namespace debug |
| 185 } // namespace base | 204 } // namespace base |
| OLD | NEW |