Limit the number of crash reports to enqueue at once
BUG=5357
Change-Id: Ib21086cdd34c938def885d625a165ba2fa0879a4
Review URL: http://codereview.chromium.org/3209003
diff --git a/crash_reporter/crash_collector.cc b/crash_reporter/crash_collector.cc
index 492f2e8..0194fc4 100644
--- a/crash_reporter/crash_collector.cc
+++ b/crash_reporter/crash_collector.cc
@@ -4,6 +4,7 @@
#include "crash-reporter/crash_collector.h"
+#include <dirent.h>
#include <pwd.h> // For struct passwd.
#include <sys/types.h> // for mode_t.
@@ -25,6 +26,9 @@
static const uid_t kRootOwner = 0;
static const uid_t kRootGroup = 0;
+// Maximum of 8 crash reports per directory.
+const int CrashCollector::kMaxCrashDirectorySize = 8;
+
CrashCollector::CrashCollector() : forced_crash_directory_(NULL) {
}
@@ -146,5 +150,46 @@
return false;
}
+ if (!CheckHasCapacity(*crash_directory)) {
+ return false;
+ }
+
return true;
}
+
+// Return true if the given crash directory has not already reached
+// maximum capacity.
+bool CrashCollector::CheckHasCapacity(const FilePath &crash_directory) {
+ DIR* dir = opendir(crash_directory.value().c_str());
+ if (!dir) {
+ return false;
+ }
+ struct dirent ent_buf;
+ struct dirent* ent;
+ int count_non_core = 0;
+ int count_core = 0;
+ bool full = false;
+ while (readdir_r(dir, &ent_buf, &ent) == 0 && ent != NULL) {
+ if ((strcmp(ent->d_name, ".") == 0) ||
+ (strcmp(ent->d_name, "..") == 0))
+ continue;
+
+ if (strcmp(ent->d_name + strlen(ent->d_name) - 5, ".core") == 0) {
+ ++count_core;
+ } else {
+ ++count_non_core;
+ }
+
+ if (count_core >= kMaxCrashDirectorySize ||
+ count_non_core >= kMaxCrashDirectorySize) {
+ logger_->LogWarning(
+ "Crash directory %s already full with %d pending reports",
+ crash_directory.value().c_str(),
+ kMaxCrashDirectorySize);
+ full = true;
+ break;
+ }
+ }
+ closedir(dir);
+ return !full;
+}