aboutsummaryrefslogtreecommitdiff
path: root/src/common/linux
diff options
context:
space:
mode:
Diffstat (limited to 'src/common/linux')
-rw-r--r--src/common/linux/tests/crash_generator.cc38
-rw-r--r--src/common/linux/tests/crash_generator.h22
2 files changed, 53 insertions, 7 deletions
diff --git a/src/common/linux/tests/crash_generator.cc b/src/common/linux/tests/crash_generator.cc
index 7274acf9..dff2bca2 100644
--- a/src/common/linux/tests/crash_generator.cc
+++ b/src/common/linux/tests/crash_generator.cc
@@ -55,6 +55,12 @@ struct ThreadData {
pid_t* thread_id_ptr;
};
+const char* const kProcFilesToCopy[] = {
+ "auxv", "cmdline", "environ", "maps", "status"
+};
+const size_t kNumProcFilesToCopy =
+ sizeof(kProcFilesToCopy) / sizeof(kProcFilesToCopy[0]);
+
// Core file size limit set to 1 MB, which is big enough for test purposes.
const rlim_t kCoreSizeLimit = 1024 * 1024;
@@ -95,6 +101,10 @@ std::string CrashGenerator::GetCoreFilePath() const {
return temp_dir_.path() + "/core";
}
+std::string CrashGenerator::GetDirectoryOfProcFilesCopy() const {
+ return temp_dir_.path() + "/proc";
+}
+
pid_t CrashGenerator::GetThreadId(unsigned index) const {
return reinterpret_cast<pid_t*>(shared_memory_)[index];
}
@@ -160,6 +170,15 @@ bool CrashGenerator::CreateChildCrash(
}
if (SetCoreFileSizeLimit(kCoreSizeLimit)) {
CreateThreadsInChildProcess(num_threads);
+ std::string proc_dir = GetDirectoryOfProcFilesCopy();
+ if (mkdir(proc_dir.c_str(), 0755) == -1) {
+ perror("CrashGenerator: Failed to create proc directory");
+ exit(1);
+ }
+ if (!CopyProcFiles(getpid(), proc_dir.c_str())) {
+ fprintf(stderr, "CrashGenerator: Failed to copy proc files\n");
+ exit(1);
+ }
if (kill(*GetThreadIdPointer(crash_thread), crash_signal) == -1) {
perror("CrashGenerator: Failed to kill thread by signal");
}
@@ -185,6 +204,25 @@ bool CrashGenerator::CreateChildCrash(
return true;
}
+bool CrashGenerator::CopyProcFiles(pid_t pid, const char* path) const {
+ char from_path[PATH_MAX], to_path[PATH_MAX];
+ for (size_t i = 0; i < kNumProcFilesToCopy; ++i) {
+ int num_chars = snprintf(from_path, PATH_MAX, "/proc/%d/%s",
+ pid, kProcFilesToCopy[i]);
+ if (num_chars < 0 || num_chars >= PATH_MAX)
+ return false;
+
+ num_chars = snprintf(to_path, PATH_MAX, "%s/%s",
+ path, kProcFilesToCopy[i]);
+ if (num_chars < 0 || num_chars >= PATH_MAX)
+ return false;
+
+ if (!CopyFile(from_path, to_path))
+ return false;
+ }
+ return true;
+}
+
void CrashGenerator::CreateThreadsInChildProcess(unsigned num_threads) {
*GetThreadIdPointer(0) = getpid();
diff --git a/src/common/linux/tests/crash_generator.h b/src/common/linux/tests/crash_generator.h
index 874b15cd..d05ce73d 100644
--- a/src/common/linux/tests/crash_generator.h
+++ b/src/common/linux/tests/crash_generator.h
@@ -58,13 +58,12 @@ class CrashGenerator {
// if /proc/sys/kernel/core_pattern has the default value 'core'.
bool HasDefaultCorePattern() const;
- // Sets the maximum size of core dump file (both the soft and hard limit)
- // to |limit| bytes. Returns true on success.
- bool SetCoreFileSizeLimit(rlim_t limit) const;
-
// Returns the expected path of the core dump file.
std::string GetCoreFilePath() const;
+ // Returns the directory of a copy of proc files of the child process.
+ std::string GetDirectoryOfProcFilesCopy() const;
+
// Creates a crash (and a core dump file) by creating a child process with
// |num_threads| threads, and the terminating the child process by sending
// a signal with number |crash_signal| to the |crash_thread|-th thread.
@@ -72,14 +71,23 @@ class CrashGenerator {
bool CreateChildCrash(unsigned num_threads, unsigned crash_thread,
int crash_signal, pid_t* child_pid);
- // Creates |num_threads| threads in the child process.
- void CreateThreadsInChildProcess(unsigned num_threads);
-
// Returns the thread ID of the |index|-th thread in the child process.
// This method does not validate |index|.
pid_t GetThreadId(unsigned index) const;
private:
+ // Copies the following proc files of the process with |pid| to the directory
+ // at |path|: auxv, cmdline, environ, maps, status
+ // The directory must have been created. Returns true on success.
+ bool CopyProcFiles(pid_t pid, const char* path) const;
+
+ // Creates |num_threads| threads in the child process.
+ void CreateThreadsInChildProcess(unsigned num_threads);
+
+ // Sets the maximum size of core dump file (both the soft and hard limit)
+ // to |limit| bytes. Returns true on success.
+ bool SetCoreFileSizeLimit(rlim_t limit) const;
+
// Creates a shared memory of |memory_size| bytes for communicating thread
// IDs between the parent and child process. Returns true on success.
bool MapSharedMemory(size_t memory_size);