Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(493)

Side by Side Diff: trunk/src/base/linux_util.cc

Issue 275913003: Revert 270173 "Remove SCM_CREDENTIALS fallback code from breakpad" (Closed) Base URL: svn://svn.chromium.org/chrome/
Patch Set: Created 6 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « trunk/src/base/linux_util.h ('k') | trunk/src/components/breakpad/app/breakpad_linux.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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/linux_util.h" 5 #include "base/linux_util.h"
6 6
7 #include <dirent.h> 7 #include <dirent.h>
8 #include <errno.h> 8 #include <errno.h>
9 #include <fcntl.h> 9 #include <fcntl.h>
10 #include <stdlib.h> 10 #include <stdlib.h>
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
64 DCHECK_EQ(STATE_CHECK_STARTED, state_); 64 DCHECK_EQ(STATE_CHECK_STARTED, state_);
65 state_ = STATE_CHECK_FINISHED; 65 state_ = STATE_CHECK_FINISHED;
66 } 66 }
67 67
68 private: 68 private:
69 base::Lock lock_; 69 base::Lock lock_;
70 LinuxDistroState state_; 70 LinuxDistroState state_;
71 }; 71 };
72 #endif // if defined(OS_LINUX) 72 #endif // if defined(OS_LINUX)
73 73
74 // expected prefix of the target of the /proc/self/fd/%d link for a socket
75 const char kSocketLinkPrefix[] = "socket:[";
76
77 // Parse a symlink in /proc/pid/fd/$x and return the inode number of the
78 // socket.
79 // inode_out: (output) set to the inode number on success
80 // path: e.g. /proc/1234/fd/5 (must be a UNIX domain socket descriptor)
81 // log: if true, log messages about failure details
82 bool ProcPathGetInode(ino_t* inode_out, const char* path, bool log = false) {
83 DCHECK(inode_out);
84 DCHECK(path);
85
86 char buf[256];
87 const ssize_t n = readlink(path, buf, sizeof(buf) - 1);
88 if (n == -1) {
89 if (log) {
90 DLOG(WARNING) << "Failed to read the inode number for a socket from /proc"
91 "(" << errno << ")";
92 }
93 return false;
94 }
95 buf[n] = 0;
96
97 if (memcmp(kSocketLinkPrefix, buf, sizeof(kSocketLinkPrefix) - 1)) {
98 if (log) {
99 DLOG(WARNING) << "The descriptor passed from the crashing process wasn't "
100 " a UNIX domain socket.";
101 }
102 return false;
103 }
104
105 char* endptr;
106 const unsigned long long int inode_ul =
107 strtoull(buf + sizeof(kSocketLinkPrefix) - 1, &endptr, 10);
108 if (*endptr != ']')
109 return false;
110
111 if (inode_ul == ULLONG_MAX) {
112 if (log) {
113 DLOG(WARNING) << "Failed to parse a socket's inode number: the number "
114 "was too large. Please report this bug: " << buf;
115 }
116 return false;
117 }
118
119 *inode_out = inode_ul;
120 return true;
121 }
122
74 } // namespace 123 } // namespace
75 124
76 namespace base { 125 namespace base {
77 126
78 // Account for the terminating null character. 127 // Account for the terminating null character.
79 static const int kDistroSize = 128 + 1; 128 static const int kDistroSize = 128 + 1;
80 129
81 // We use this static string to hold the Linux distro info. If we 130 // We use this static string to hold the Linux distro info. If we
82 // crash, the crash handler code will send this in the crash dump. 131 // crash, the crash handler code will send this in the crash dump.
83 char g_linux_distro[kDistroSize] = 132 char g_linux_distro[kDistroSize] =
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
122 return "Unknown"; 171 return "Unknown";
123 #endif 172 #endif
124 } 173 }
125 174
126 void SetLinuxDistro(const std::string& distro) { 175 void SetLinuxDistro(const std::string& distro) {
127 std::string trimmed_distro; 176 std::string trimmed_distro;
128 base::TrimWhitespaceASCII(distro, base::TRIM_ALL, &trimmed_distro); 177 base::TrimWhitespaceASCII(distro, base::TRIM_ALL, &trimmed_distro);
129 base::strlcpy(g_linux_distro, trimmed_distro.c_str(), kDistroSize); 178 base::strlcpy(g_linux_distro, trimmed_distro.c_str(), kDistroSize);
130 } 179 }
131 180
181 bool FileDescriptorGetInode(ino_t* inode_out, int fd) {
182 DCHECK(inode_out);
183
184 struct stat buf;
185 if (fstat(fd, &buf) < 0)
186 return false;
187
188 if (!S_ISSOCK(buf.st_mode))
189 return false;
190
191 *inode_out = buf.st_ino;
192 return true;
193 }
194
195 bool FindProcessHoldingSocket(pid_t* pid_out, ino_t socket_inode) {
196 DCHECK(pid_out);
197 bool already_found = false;
198
199 DIR* proc = opendir("/proc");
200 if (!proc) {
201 DLOG(WARNING) << "Cannot open /proc";
202 return false;
203 }
204
205 std::vector<pid_t> pids;
206
207 struct dirent* dent;
208 while ((dent = readdir(proc))) {
209 char* endptr;
210 const unsigned long int pid_ul = strtoul(dent->d_name, &endptr, 10);
211 if (pid_ul == ULONG_MAX || *endptr)
212 continue;
213 pids.push_back(pid_ul);
214 }
215 closedir(proc);
216
217 for (std::vector<pid_t>::const_iterator
218 i = pids.begin(); i != pids.end(); ++i) {
219 const pid_t current_pid = *i;
220 char buf[256];
221 snprintf(buf, sizeof(buf), "/proc/%d/fd", current_pid);
222 DIR* fd = opendir(buf);
223 if (!fd)
224 continue;
225
226 while ((dent = readdir(fd))) {
227 if (snprintf(buf, sizeof(buf), "/proc/%d/fd/%s", current_pid,
228 dent->d_name) >= static_cast<int>(sizeof(buf))) {
229 continue;
230 }
231
232 ino_t fd_inode = static_cast<ino_t>(-1);
233 if (ProcPathGetInode(&fd_inode, buf)) {
234 if (fd_inode == socket_inode) {
235 if (already_found) {
236 closedir(fd);
237 return false;
238 }
239
240 already_found = true;
241 *pid_out = current_pid;
242 break;
243 }
244 }
245 }
246
247 closedir(fd);
248 }
249
250 return already_found;
251 }
252
132 pid_t FindThreadIDWithSyscall(pid_t pid, const std::string& expected_data, 253 pid_t FindThreadIDWithSyscall(pid_t pid, const std::string& expected_data,
133 bool* syscall_supported) { 254 bool* syscall_supported) {
134 char buf[256]; 255 char buf[256];
135 snprintf(buf, sizeof(buf), "/proc/%d/task", pid); 256 snprintf(buf, sizeof(buf), "/proc/%d/task", pid);
136 257
137 if (syscall_supported != NULL) 258 if (syscall_supported != NULL)
138 *syscall_supported = false; 259 *syscall_supported = false;
139 260
140 DIR* task = opendir(buf); 261 DIR* task = opendir(buf);
141 if (!task) { 262 if (!task) {
(...skipping 29 matching lines...) Expand all
171 292
172 if (0 == strncmp(expected_data.c_str(), syscall_data.get(), 293 if (0 == strncmp(expected_data.c_str(), syscall_data.get(),
173 expected_data.length())) { 294 expected_data.length())) {
174 return current_tid; 295 return current_tid;
175 } 296 }
176 } 297 }
177 return -1; 298 return -1;
178 } 299 }
179 300
180 } // namespace base 301 } // namespace base
OLDNEW
« no previous file with comments | « trunk/src/base/linux_util.h ('k') | trunk/src/components/breakpad/app/breakpad_linux.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698