From 74ab41ae3003af5d3e33489ca817312fe205c7da Mon Sep 17 00:00:00 2001 From: dgotwisner Date: Mon, 31 Mar 2014 11:16:25 +0200 Subject: [PATCH] Add code to save various /proc files to a file when we crash (with core generation). Tied to 2 configuration variables. --- SelfDetect.cpp | 7 ++++++- UnixSignal.cpp | 24 ++++++++++++++++++++++++ UnixSignal.h | 3 +++ 3 files changed, 33 insertions(+), 1 deletion(-) diff --git a/SelfDetect.cpp b/SelfDetect.cpp index 30f398e..9e0e1c5 100644 --- a/SelfDetect.cpp +++ b/SelfDetect.cpp @@ -35,9 +35,12 @@ #include "SelfDetect.h" #include "Logger.h" #include "Exit.h" +#include "Configuration.h" //SelfDetect gSelf; +extern ConfigurationTable gConfig; + static void e(void) { gSelf.Exit(-999); @@ -73,11 +76,13 @@ void SelfDetect::RegisterProgram(const char *argv0) if (fp == NULL) { LOG(ERR) << "*** Unable to create " << buf << ": " << strerror(errno); - Exit::exit(Exit::CREATEFILE); + Exit::exit(Exit::CREATEFILE); } fprintf(fp, "%d\n", getpid()); fclose(fp); atexit(e); + gSigVec.CoreName(gConfig.getStr("Core.File"), gConfig.getBool("Core.Pid")); + gSigVec.TarName(gConfig.getStr("Core.TarFile"), gConfig.getBool("Core.SaveFiles")); // Now, register for all signals to do the cleanup for (int i = 1; i < UnixSignal::C_NSIG; i++) diff --git a/UnixSignal.cpp b/UnixSignal.cpp index ddd6546..e533ef7 100644 --- a/UnixSignal.cpp +++ b/UnixSignal.cpp @@ -66,6 +66,30 @@ void UnixSignal::Handler(int sig) else snprintf(buf, sizeof(buf)-1, "%s", mCoreFile.c_str()); WriteCoreDump(buf); + + // and save the files if needed + if (mSaveFiles) + { + char buf[BUFSIZ]; + std::string s; + std::string p; + sprintf(buf, "%d", getpid()); + p = buf; + s = "rm -rf /tmp/staging." ; s += p; s += "/ ; "; + s += "mkdir /tmp/staging." ; s += p; s += "/ ; "; + s += "cp --parents /etc/issue /tmp/staging." ; s += p; s += "/ ; "; + s += "cp --parents /proc/cpuinfo /proc/interrupts /proc/iomem /proc/ioports /proc/diskstats /proc/loadavg /proc/locks /proc/meminfo /proc/softirqs /proc/stat /proc/uptime /proc/version /proc/version_signature /proc/vmstat /tmp/staging." ; s += p; s += "/ ; "; + + s += "for i in cmdline cpuset environ io limits maps net/tcp net/udp net/tcp6 net/udp6 net/unix net/netstat sched schedstat smaps stat statm status ; "; + s += "do cp --parents /proc/" ; s += p; s += "/$i /tmp/staging." ; s += p; s += "/ ; "; + s += "cp --parents /proc/"; s += p; s += "/task/*/stat* /tmp/staging."; s += p; s += "/ ; "; + s += "done ; "; + s += "tar --create --verbose --file=- --directory=/proc/"; s += p; s += " fd | ( cd /tmp/staging."; s += p; s += "/proc/"; s += p; s += "/ ; tar xpvf - ) ; "; + s += "tar --create --verbose --file=- --directory=/tmp/staging."; s += p; s += "/ . | gzip > "; s += mTarFile; s += " ; "; + s += "rm -rf /tmp/staging." ; s += p; + printf("Running '%s'\n", s.c_str()); + system(s.c_str()); + } } break; default: diff --git a/UnixSignal.h b/UnixSignal.h index 558b2b4..cb50c17 100644 --- a/UnixSignal.h +++ b/UnixSignal.h @@ -33,6 +33,8 @@ private: Mutex mLock[C_NSIG]; bool mAddPid; // if true file is file.pid std::string mCoreFile; // name of file to save to + bool mSaveFiles; // if true, save /proc related files in a compressed tarball + std::string mTarFile; // tarball for proc files public: UnixSignal(void); ~UnixSignal(void); @@ -41,6 +43,7 @@ public: void Handler(int sig); // main signal handler, iterates through mListHandlers void Dump(void); // debug dump of list inline void CoreName(const std::string &coreFile, bool addPid) { mCoreFile = coreFile; mAddPid = addPid; } + inline void TarName(const std::string &tarFile, bool saveFiles) { mTarFile = tarFile; mSaveFiles = saveFiles; } }; extern UnixSignal gSigVec;