зеркало из https://github.com/mozilla/gecko-dev.git
Bug 999473 - report number of open file descriptions (fd) in about:memory. r=njn
This commit is contained in:
Родитель
ca2a2308b2
Коммит
41bcb2678a
|
@ -275,6 +275,14 @@ private:
|
|||
break;
|
||||
}
|
||||
fclose(f);
|
||||
|
||||
// Report the open file descriptors for this process.
|
||||
nsPrintfCString procFdPath("/proc/%s/fd", pidStr);
|
||||
nsresult rv = CollectOpenFileReports(
|
||||
aHandleReport, aData, procFdPath, processName);
|
||||
if (NS_FAILED(rv)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
closedir(d);
|
||||
|
@ -723,6 +731,84 @@ private:
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
CollectOpenFileReports(nsIHandleReportCallback* aHandleReport,
|
||||
nsISupports* aData,
|
||||
const nsACString& aProcPath,
|
||||
const nsACString& aProcessName)
|
||||
{
|
||||
// All file descriptors opened by a process are listed under
|
||||
// /proc/<pid>/fd/<numerical_fd>. Each entry is a symlink that points to the
|
||||
// path that was opened. This can be an actual file, a socket, a pipe, an
|
||||
// anon_inode, or possibly an uncategorized device.
|
||||
const char kFilePrefix[] = "/";
|
||||
const char kSocketPrefix[] = "socket:";
|
||||
const char kPipePrefix[] = "pipe:";
|
||||
const char kAnonInodePrefix[] = "anon_inode:";
|
||||
|
||||
const nsCString procPath(aProcPath);
|
||||
DIR* d = opendir(procPath.get());
|
||||
if (!d) {
|
||||
if (NS_WARN_IF(errno != ENOENT && errno != EACCES)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
char linkPath[PATH_MAX + 1];
|
||||
struct dirent* ent;
|
||||
while ((ent = readdir(d))) {
|
||||
const char* fd = ent->d_name;
|
||||
|
||||
// Skip "." and ".." (and any other dotfiles).
|
||||
if (fd[0] == '.') {
|
||||
continue;
|
||||
}
|
||||
|
||||
nsPrintfCString fullPath("%s/%s", procPath.get(), fd);
|
||||
ssize_t linkPathSize = readlink(fullPath.get(), linkPath, PATH_MAX);
|
||||
if (linkPathSize > 0) {
|
||||
linkPath[linkPathSize] = '\0';
|
||||
|
||||
#define CHECK_PREFIX(prefix) \
|
||||
(strncmp(linkPath, prefix, sizeof(prefix) - 1) == 0)
|
||||
|
||||
const char* category = nullptr;
|
||||
const char* descriptionPrefix = nullptr;
|
||||
|
||||
if (CHECK_PREFIX(kFilePrefix)) {
|
||||
category = "files"; // No trailing slash, the file path will have one
|
||||
descriptionPrefix = "An open";
|
||||
} else if (CHECK_PREFIX(kSocketPrefix)) {
|
||||
category = "sockets/";
|
||||
descriptionPrefix = "A socket";
|
||||
} else if (CHECK_PREFIX(kPipePrefix)) {
|
||||
category = "pipes/";
|
||||
descriptionPrefix = "A pipe";
|
||||
} else if (CHECK_PREFIX(kAnonInodePrefix)) {
|
||||
category = "anon_inodes/";
|
||||
descriptionPrefix = "An anon_inode";
|
||||
} else {
|
||||
category = "";
|
||||
descriptionPrefix = "An uncategorized";
|
||||
}
|
||||
|
||||
#undef CHECK_PREFIX
|
||||
|
||||
const nsCString processName(aProcessName);
|
||||
nsPrintfCString entryPath(
|
||||
"open-fds/%s/%s%s/%s", processName.get(), category, linkPath, fd);
|
||||
nsPrintfCString entryDescription(
|
||||
"%s file descriptor opened by the process", descriptionPrefix);
|
||||
REPORT_WITH_CLEANUP(
|
||||
entryPath, UNITS_COUNT, 1, entryDescription, closedir(d));
|
||||
}
|
||||
}
|
||||
|
||||
closedir(d);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
#undef REPORT
|
||||
};
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче