OLD | NEW |
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2008 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_util.h" | 5 #include "base/debug_util.h" |
6 | 6 |
7 #include <unistd.h> | 7 #include <fcntl.h> |
| 8 #include <sys/stat.h> |
8 #include <sys/sysctl.h> | 9 #include <sys/sysctl.h> |
9 #include <sys/types.h> | 10 #include <sys/types.h> |
10 #include <sys/stat.h> | 11 #include <unistd.h> |
11 #include <fcntl.h> | |
12 | 12 |
| 13 #include "base/basictypes.h" |
13 #include "base/logging.h" | 14 #include "base/logging.h" |
14 #include "base/string_piece.h" | 15 #include "base/string_piece.h" |
15 | 16 |
| 17 // static |
16 bool DebugUtil::SpawnDebuggerOnProcess(unsigned /* process_id */) { | 18 bool DebugUtil::SpawnDebuggerOnProcess(unsigned /* process_id */) { |
17 NOTIMPLEMENTED(); | 19 NOTIMPLEMENTED(); |
18 return false; | 20 return false; |
19 } | 21 } |
20 | 22 |
21 #if defined(OS_MACOSX) | 23 #if defined(OS_MACOSX) |
| 24 |
| 25 // Based on Apple's recommended method as described in |
22 // http://developer.apple.com/qa/qa2004/qa1361.html | 26 // http://developer.apple.com/qa/qa2004/qa1361.html |
| 27 // static |
23 bool DebugUtil::BeingDebugged() { | 28 bool DebugUtil::BeingDebugged() { |
24 NOTIMPLEMENTED(); | 29 // Initialize mib, which tells sysctl what info we want. In this case, |
25 return false; | 30 // we're looking for information about a specific process ID. |
| 31 int mib[] = { |
| 32 CTL_KERN, |
| 33 KERN_PROC, |
| 34 KERN_PROC_PID, |
| 35 getpid() |
| 36 }; |
| 37 |
| 38 // Caution: struct kinfo_proc is marked __APPLE_API_UNSTABLE. The source and |
| 39 // binary interfaces may change. |
| 40 struct kinfo_proc info; |
| 41 size_t info_size = sizeof(info); |
| 42 |
| 43 int sysctl_result = sysctl(mib, arraysize(mib), &info, &info_size, NULL, 0); |
| 44 DCHECK(sysctl_result == 0); |
| 45 if (sysctl_result != 0) |
| 46 return false; |
| 47 |
| 48 // This process is being debugged if the P_TRACED flag is set. |
| 49 return (info.kp_proc.p_flag & P_TRACED) != 0; |
26 } | 50 } |
27 | 51 |
28 #elif defined(OS_LINUX) | 52 #elif defined(OS_LINUX) |
| 53 |
29 // We can look in /proc/self/status for TracerPid. We are likely used in crash | 54 // We can look in /proc/self/status for TracerPid. We are likely used in crash |
30 // handling, so we are careful not to use the heap or have side effects. | 55 // handling, so we are careful not to use the heap or have side effects. |
31 // Another option that is common is to try to ptrace yourself, but then we | 56 // Another option that is common is to try to ptrace yourself, but then we |
32 // can't detach without forking(), and that's not so great. | 57 // can't detach without forking(), and that's not so great. |
| 58 // static |
33 bool DebugUtil::BeingDebugged() { | 59 bool DebugUtil::BeingDebugged() { |
34 int status_fd = open("/proc/self/status", O_RDONLY); | 60 int status_fd = open("/proc/self/status", O_RDONLY); |
35 if (status_fd == -1) | 61 if (status_fd == -1) |
36 return false; | 62 return false; |
37 | 63 |
38 // We assume our line will be in the first 1024 characters and that we can | 64 // We assume our line will be in the first 1024 characters and that we can |
39 // read this much all at once. In practice this will generally be true. | 65 // read this much all at once. In practice this will generally be true. |
40 // This simplifies and speeds up things considerably. | 66 // This simplifies and speeds up things considerably. |
41 char buf[1024]; | 67 char buf[1024]; |
42 | 68 |
43 ssize_t num_read = read(status_fd, buf, sizeof(buf)); | 69 ssize_t num_read = read(status_fd, buf, sizeof(buf)); |
44 close(status_fd); | 70 close(status_fd); |
45 | 71 |
46 if (num_read <= 0) | 72 if (num_read <= 0) |
47 return false; | 73 return false; |
48 | 74 |
49 StringPiece status(buf, num_read); | 75 StringPiece status(buf, num_read); |
50 StringPiece tracer("TracerPid:\t"); | 76 StringPiece tracer("TracerPid:\t"); |
51 | 77 |
52 StringPiece::size_type pid_index = status.find(tracer); | 78 StringPiece::size_type pid_index = status.find(tracer); |
53 if (pid_index == StringPiece::npos) | 79 if (pid_index == StringPiece::npos) |
54 return false; | 80 return false; |
55 | 81 |
56 // Our pid is 0 without a debugger, assume this for any pid starting with 0. | 82 // Our pid is 0 without a debugger, assume this for any pid starting with 0. |
57 pid_index += tracer.size(); | 83 pid_index += tracer.size(); |
58 return pid_index < status.size() && status[pid_index] != '0'; | 84 return pid_index < status.size() && status[pid_index] != '0'; |
59 } | 85 } |
60 #endif | 86 |
| 87 #endif // OS_LINUX |
61 | 88 |
62 // static | 89 // static |
63 void DebugUtil::BreakDebugger() { | 90 void DebugUtil::BreakDebugger() { |
64 asm ("int3"); | 91 asm ("int3"); |
65 } | 92 } |
66 | |
OLD | NEW |