OLD | NEW |
1 // Copyright (c) 2009, Google Inc. | 1 // Copyright (c) 2009, Google Inc. |
2 // All rights reserved. | 2 // All rights reserved. |
3 // | 3 // |
4 // Redistribution and use in source and binary forms, with or without | 4 // Redistribution and use in source and binary forms, with or without |
5 // modification, are permitted provided that the following conditions are | 5 // modification, are permitted provided that the following conditions are |
6 // met: | 6 // met: |
7 // | 7 // |
8 // * Redistributions of source code must retain the above copyright | 8 // * Redistributions of source code must retain the above copyright |
9 // notice, this list of conditions and the following disclaimer. | 9 // notice, this list of conditions and the following disclaimer. |
10 // * Redistributions in binary form must reproduce the above | 10 // * Redistributions in binary form must reproduce the above |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
68 if (sys_ptrace(PTRACE_ATTACH, pid, NULL, NULL) != 0 && | 68 if (sys_ptrace(PTRACE_ATTACH, pid, NULL, NULL) != 0 && |
69 errno != 0) { | 69 errno != 0) { |
70 return false; | 70 return false; |
71 } | 71 } |
72 while (sys_waitpid(pid, NULL, __WALL) < 0) { | 72 while (sys_waitpid(pid, NULL, __WALL) < 0) { |
73 if (errno != EINTR) { | 73 if (errno != EINTR) { |
74 sys_ptrace(PTRACE_DETACH, pid, NULL, NULL); | 74 sys_ptrace(PTRACE_DETACH, pid, NULL, NULL); |
75 return false; | 75 return false; |
76 } | 76 } |
77 } | 77 } |
| 78 #if defined(__i386) || defined(__x86_64) |
| 79 // On x86, the stack pointer is NULL or -1, when executing trusted code in |
| 80 // the seccomp sandbox. Not only does this cause difficulties down the line |
| 81 // when trying to dump the thread's stack, it also results in the minidumps |
| 82 // containing information about the trusted threads. This information is |
| 83 // generally completely meaningless and just pollutes the minidumps. |
| 84 // We thus test the stack pointer and exclude any threads that are part of |
| 85 // the seccomp sandbox's trusted code. |
| 86 user_regs_struct regs; |
| 87 if (sys_ptrace(PTRACE_GETREGS, pid, NULL, ®s) == -1 || |
| 88 #if defined(__i386) |
| 89 !regs.esp |
| 90 #elif defined(__x86_64) |
| 91 !regs.rsp |
| 92 #endif |
| 93 ) { |
| 94 sys_ptrace(PTRACE_DETACH, pid, NULL, NULL); |
| 95 return false; |
| 96 } |
| 97 #endif |
78 return true; | 98 return true; |
79 } | 99 } |
80 | 100 |
81 // Resume a thread by detaching from it. | 101 // Resume a thread by detaching from it. |
82 static bool ResumeThread(pid_t pid) { | 102 static bool ResumeThread(pid_t pid) { |
83 return sys_ptrace(PTRACE_DETACH, pid, NULL, NULL) >= 0; | 103 return sys_ptrace(PTRACE_DETACH, pid, NULL, NULL) >= 0; |
84 } | 104 } |
85 | 105 |
86 inline static bool IsMappedFileOpenUnsafe( | 106 inline static bool IsMappedFileOpenUnsafe( |
87 const google_breakpad::MappingInfo* mapping) { | 107 const google_breakpad::MappingInfo* mapping) { |
(...skipping 16 matching lines...) Expand all Loading... |
104 } | 124 } |
105 | 125 |
106 bool LinuxDumper::Init() { | 126 bool LinuxDumper::Init() { |
107 return EnumerateThreads(&threads_) && | 127 return EnumerateThreads(&threads_) && |
108 EnumerateMappings(&mappings_); | 128 EnumerateMappings(&mappings_); |
109 } | 129 } |
110 | 130 |
111 bool LinuxDumper::ThreadsSuspend() { | 131 bool LinuxDumper::ThreadsSuspend() { |
112 if (threads_suspended_) | 132 if (threads_suspended_) |
113 return true; | 133 return true; |
114 bool good = true; | 134 for (size_t i = 0; i < threads_.size(); ++i) { |
115 for (size_t i = 0; i < threads_.size(); ++i) | 135 if (!SuspendThread(threads_[i])) { |
116 good &= SuspendThread(threads_[i]); | 136 // If the thread either disappeared before we could attach to it, or if |
| 137 // it was part of the seccomp sandbox's trusted code, it is OK to |
| 138 // silently drop it from the minidump. |
| 139 memmove(&threads_[i], &threads_[i+1], |
| 140 (threads_.size() - i - 1) * sizeof(threads_[i])); |
| 141 threads_.resize(threads_.size() - 1); |
| 142 --i; |
| 143 } |
| 144 } |
117 threads_suspended_ = true; | 145 threads_suspended_ = true; |
118 return good; | 146 return threads_.size() > 0; |
119 } | 147 } |
120 | 148 |
121 bool LinuxDumper::ThreadsResume() { | 149 bool LinuxDumper::ThreadsResume() { |
122 if (!threads_suspended_) | 150 if (!threads_suspended_) |
123 return false; | 151 return false; |
124 bool good = true; | 152 bool good = true; |
125 for (size_t i = 0; i < threads_.size(); ++i) | 153 for (size_t i = 0; i < threads_.size(); ++i) |
126 good &= ResumeThread(threads_[i]); | 154 good &= ResumeThread(threads_[i]); |
127 threads_suspended_ = false; | 155 threads_suspended_ = false; |
128 return good; | 156 return good; |
(...skipping 324 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
453 for (size_t i = 0; i < mappings_.size(); ++i) { | 481 for (size_t i = 0; i < mappings_.size(); ++i) { |
454 const uintptr_t start = static_cast<uintptr_t>(mappings_[i]->start_addr); | 482 const uintptr_t start = static_cast<uintptr_t>(mappings_[i]->start_addr); |
455 if (addr >= start && addr - start < mappings_[i]->size) | 483 if (addr >= start && addr - start < mappings_[i]->size) |
456 return mappings_[i]; | 484 return mappings_[i]; |
457 } | 485 } |
458 | 486 |
459 return NULL; | 487 return NULL; |
460 } | 488 } |
461 | 489 |
462 } // namespace google_breakpad | 490 } // namespace google_breakpad |
OLD | NEW |