summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2010-06-07 12:39:54 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2010-06-07 12:39:54 +0200
commitcd471cebbcd9a61f21196a915b9b44e68d84aed9 (patch)
tree2aab91b6fdeeed217d80b6ead950df0f78357ebc
parent5003d2f46021bc9e63563ee2243e669e6f6ad0fd (diff)
downloadabrt-cd471cebbcd9a61f21196a915b9b44e68d84aed9.tar.gz
abrt-cd471cebbcd9a61f21196a915b9b44e68d84aed9.tar.xz
abrt-cd471cebbcd9a61f21196a915b9b44e68d84aed9.zip
ccpp hook: add SaveBinaryImage option which saves of the crashed binary
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r--inc/CrashTypes.h1
-rw-r--r--lib/Plugins/CCpp.conf4
-rw-r--r--src/Hooks/abrt-hook-ccpp.cpp30
-rw-r--r--src/Hooks/abrt-hook-python.cpp2
-rw-r--r--src/Hooks/hooklib.cpp13
-rw-r--r--src/Hooks/hooklib.h2
6 files changed, 45 insertions, 7 deletions
diff --git a/inc/CrashTypes.h b/inc/CrashTypes.h
index 0581fc5f..8b9fda93 100644
--- a/inc/CrashTypes.h
+++ b/inc/CrashTypes.h
@@ -25,6 +25,7 @@
// filled by a hook:
#define FILENAME_ANALYZER "analyzer"
#define FILENAME_EXECUTABLE "executable"
+#define FILENAME_BINARY "binary"
#define FILENAME_CMDLINE "cmdline"
#define FILENAME_REASON "reason"
#define FILENAME_COREDUMP "coredump"
diff --git a/lib/Plugins/CCpp.conf b/lib/Plugins/CCpp.conf
index 30e1550c..a18d56a3 100644
--- a/lib/Plugins/CCpp.conf
+++ b/lib/Plugins/CCpp.conf
@@ -5,6 +5,10 @@ Enabled = yes
# in crashed process' current dir, set to "yes"
MakeCompatCore = yes
+# Do you want a copy of crashed binary be saved?
+# (useful, for example, when _deleted binary_ segfaults)
+SaveBinaryImage = no
+
# Generate backtrace
Backtrace = yes
diff --git a/src/Hooks/abrt-hook-ccpp.cpp b/src/Hooks/abrt-hook-ccpp.cpp
index d50f3cb3..2cf74ef6 100644
--- a/src/Hooks/abrt-hook-ccpp.cpp
+++ b/src/Hooks/abrt-hook-ccpp.cpp
@@ -132,11 +132,12 @@ static off_t copyfd_sparse(int src_fd, int dst_fd1, int dst_fd2, off_t size2)
return total;
}
-static char* get_executable(pid_t pid)
+static char* get_executable(pid_t pid, int *fd_p)
{
char buf[sizeof("/proc/%lu/exe") + sizeof(long)*3];
sprintf(buf, "/proc/%lu/exe", (long)pid);
+ *fd_p = open(buf, O_RDONLY); /* might fail and return -1, it's ok */
char *executable = malloc_readlink(buf);
/* find and cut off " (deleted)" from the path */
char *deleted = executable + strlen(executable) - strlen(" (deleted)");
@@ -270,7 +271,8 @@ int main(int argc, char** argv)
error_msg_and_die("pid '%s' or limit '%s' is bogus", argv[2], argv[5]);
}
- char* executable = get_executable(pid);
+ int src_fd_binary;
+ char* executable = get_executable(pid, &src_fd_binary);
if (executable == NULL)
{
error_msg_and_die("can't read /proc/%lu/exe link", (long)pid);
@@ -286,7 +288,13 @@ int main(int argc, char** argv)
/* Parse abrt.conf and plugins/CCpp.conf */
unsigned setting_MaxCrashReportsSize = 0;
bool setting_MakeCompatCore = false;
- parse_conf(CONF_DIR"/plugins/CCpp.conf", &setting_MaxCrashReportsSize, &setting_MakeCompatCore);
+ bool setting_SaveBinaryImage = false;
+ parse_conf(CONF_DIR"/plugins/CCpp.conf", &setting_MaxCrashReportsSize, &setting_MakeCompatCore, &setting_SaveBinaryImage);
+ if (!setting_SaveBinaryImage && src_fd_binary >= 0)
+ {
+ close(src_fd_binary);
+ src_fd_binary = -1;
+ }
/* Open a fd to compat coredump, if requested and is possible */
int user_core_fd = -1;
@@ -340,7 +348,7 @@ int main(int argc, char** argv)
fstat(fd, &sb); /* !paranoia. this can't fail. */
if (sb.st_size != 0 /* if it wasn't created by us just now... */
- && (unsigned)(time(NULL) - sb.st_mtime) < 20 /* and is relatively new [is 20 sec ok?] */
+ && (unsigned)(time(NULL) - sb.st_mtime) < 20 /* and is relatively new [is 20 sec ok?] */
) {
sz = read(fd, path, sizeof(path)-1); /* (ab)using path as scratch buf */
if (sz > 0)
@@ -399,6 +407,20 @@ int main(int argc, char** argv)
free(cmdline);
free(reason);
+ if (src_fd_binary > 0)
+ {
+ strcpy(path + path_len, "/"FILENAME_BINARY);
+ int dst_fd_binary = xopen3(path, O_WRONLY | O_CREAT | O_TRUNC, 0600);
+ off_t sz = copyfd_eof(src_fd_binary, dst_fd_binary, COPYFD_SPARSE);
+ if (sz < 0 || fsync(dst_fd_binary) != 0)
+ {
+ unlink(path);
+ error_msg_and_die("error saving binary image to %s", path);
+ }
+ close(dst_fd_binary);
+ close(src_fd_binary);
+ }
+
/* We need coredumps to be readable by all, because
* when abrt daemon processes coredump,
* process producing backtrace is run under the same UID
diff --git a/src/Hooks/abrt-hook-python.cpp b/src/Hooks/abrt-hook-python.cpp
index cbe1418e..5f2dc809 100644
--- a/src/Hooks/abrt-hook-python.cpp
+++ b/src/Hooks/abrt-hook-python.cpp
@@ -91,7 +91,7 @@ int main(int argc, char** argv)
error_msg_and_die("daemon is not running, python crash dump aborted");
unsigned setting_MaxCrashReportsSize = 0;
- parse_conf(NULL, &setting_MaxCrashReportsSize, NULL);
+ parse_conf(NULL, &setting_MaxCrashReportsSize, NULL, NULL);
if (setting_MaxCrashReportsSize > 0)
{
check_free_space(setting_MaxCrashReportsSize);
diff --git a/src/Hooks/hooklib.cpp b/src/Hooks/hooklib.cpp
index a722ef5f..0c00e75f 100644
--- a/src/Hooks/hooklib.cpp
+++ b/src/Hooks/hooklib.cpp
@@ -22,7 +22,7 @@
using namespace std;
-void parse_conf(const char *additional_conf, unsigned *setting_MaxCrashReportsSize, bool *setting_MakeCompatCore)
+void parse_conf(const char *additional_conf, unsigned *setting_MaxCrashReportsSize, bool *setting_MakeCompatCore, bool *setting_SaveBinaryImage)
{
FILE *fp = fopen(CONF_DIR"/abrt.conf", "r");
if (!fp)
@@ -77,6 +77,17 @@ void parse_conf(const char *additional_conf, unsigned *setting_MaxCrashReportsSi
continue;
}
#undef DIRECTIVE
+#define DIRECTIVE "SaveBinaryImage"
+ if (setting_SaveBinaryImage && strncmp(p, DIRECTIVE, sizeof(DIRECTIVE)-1) == 0)
+ {
+ p = skip_whitespace(p + sizeof(DIRECTIVE)-1);
+ if (*p != '=')
+ continue;
+ p = skip_whitespace(p + 1);
+ *setting_SaveBinaryImage = string_to_bool(p);
+ continue;
+ }
+#undef DIRECTIVE
/* add more 'if (strncmp(p, DIRECTIVE, sizeof(DIRECTIVE)-1) == 0)' here... */
}
}
diff --git a/src/Hooks/hooklib.h b/src/Hooks/hooklib.h
index 0794ff60..1651204f 100644
--- a/src/Hooks/hooklib.h
+++ b/src/Hooks/hooklib.h
@@ -16,6 +16,6 @@
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
-void parse_conf(const char *additional_conf, unsigned *setting_MaxCrashReportsSize, bool *setting_MakeCompatCore);
+void parse_conf(const char *additional_conf, unsigned *setting_MaxCrashReportsSize, bool *setting_MakeCompatCore, bool *setting_SaveBinaryImage);
void check_free_space(unsigned setting_MaxCrashReportsSize);
void trim_debug_dumps(unsigned setting_MaxCrashReportsSize, const char *exclude_path);