From 20825945e91651cccb080ee94286a33cd82d3ee4 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Mon, 18 Apr 2011 22:41:41 +0200 Subject: abrt-hook-ccpp: add saving of environ, disable saving of smaps. closes #91 Signed-off-by: Denys Vlasenko --- src/daemon/abrt-server.c | 4 +-- src/hooks/abrt-hook-ccpp.c | 35 ++++++++++++++-------- src/include/abrt_crash_data.h | 1 + src/include/abrtlib.h | 2 ++ src/lib/get_cmdline.c | 69 +++++++++++++++++++++++++++++++------------ 5 files changed, 78 insertions(+), 33 deletions(-) diff --git a/src/daemon/abrt-server.c b/src/daemon/abrt-server.c index c9da64d6..4626d5de 100644 --- a/src/daemon/abrt-server.c +++ b/src/daemon/abrt-server.c @@ -126,8 +126,8 @@ static void create_debug_dump() dd_save_text(dd, FILENAME_REASON, reason); /* Obtain and save the command line. */ - char *cmdline = get_cmdline(pid); // never NULL - dd_save_text(dd, FILENAME_CMDLINE, cmdline); + char *cmdline = get_cmdline(pid); + dd_save_text(dd, FILENAME_CMDLINE, cmdline ? : ""); free(cmdline); /* Store id of the user whose application crashed. */ diff --git a/src/hooks/abrt-hook-ccpp.c b/src/hooks/abrt-hook-ccpp.c index dfccee74..d13851f3 100644 --- a/src/hooks/abrt-hook-ccpp.c +++ b/src/hooks/abrt-hook-ccpp.c @@ -514,28 +514,39 @@ int main(int argc, char** argv) dd_create_basic_files(dd, uid); char source_filename[sizeof("/proc/%lu/smaps") + sizeof(long)*3]; - int base_name = sprintf(source_filename, "/proc/%lu/smaps", (long)pid); - base_name -= strlen("smaps"); + int source_base_ofs = sprintf(source_filename, "/proc/%lu/smaps", (long)pid); + source_base_ofs -= strlen("smaps"); char *dest_filename = concat_path_file(dd->dd_dirname, FILENAME_SMAPS); + char *dest_base = strrchr(dest_filename, '/') + 1; + + // Disabled for now: /proc/PID/smaps tends to be BIG, + // and not much more informative than /proc/PID/maps: + //copy_file(source_filename, dest_filename, 0640); + //chown(dest_filename, dd->dd_uid, dd->dd_gid); + + strcpy(source_filename + source_base_ofs, "maps"); + strcpy(dest_base, FILENAME_MAPS); copy_file(source_filename, dest_filename, 0640); chown(dest_filename, dd->dd_uid, dd->dd_gid); - strcpy(source_filename + base_name, "maps"); - strcpy(strrchr(dest_filename, '/') + 1, FILENAME_MAPS); - copy_file(source_filename, dest_filename, 0640); - chown(dest_filename, dd->dd_uid, dd->dd_gid); - free(dest_filename); - char *cmdline = get_cmdline(pid); /* never NULL */ - char *reason = xasprintf("Process %s was killed by signal %s (SIG%s)", - executable, signal_str, signame ? signame : signal_str); + free(dest_filename); dd_save_text(dd, FILENAME_ANALYZER, "CCpp"); dd_save_text(dd, FILENAME_EXECUTABLE, executable); - dd_save_text(dd, FILENAME_CMDLINE, cmdline); + + char *reason = xasprintf("Process %s was killed by signal %s (SIG%s)", + executable, signal_str, signame ? signame : signal_str); dd_save_text(dd, FILENAME_REASON, reason); - free(cmdline); free(reason); + char *cmdline = get_cmdline(pid); + dd_save_text(dd, FILENAME_CMDLINE, cmdline ? : ""); + free(cmdline); + + char *environ = get_environ(pid); + dd_save_text(dd, FILENAME_ENVIRON, environ ? : ""); + free(environ); + if (src_fd_binary > 0) { strcpy(path + path_len, "/"FILENAME_BINARY); diff --git a/src/include/abrt_crash_data.h b/src/include/abrt_crash_data.h index 52ae50ca..237a3d01 100644 --- a/src/include/abrt_crash_data.h +++ b/src/include/abrt_crash_data.h @@ -38,6 +38,7 @@ #define FILENAME_BACKTRACE "backtrace" #define FILENAME_MAPS "maps" #define FILENAME_SMAPS "smaps" +#define FILENAME_ENVIRON "environ" #define FILENAME_DUPHASH "global_uuid" /* name is compat, to be renamed to "duphash" */ // Name of the function where the application crashed. // Optional. diff --git a/src/include/abrtlib.h b/src/include/abrtlib.h index e14b742f..e0014593 100644 --- a/src/include/abrtlib.h +++ b/src/include/abrtlib.h @@ -224,6 +224,8 @@ char* hex2bin(char *dst, const char *str, int count); */ #define get_cmdline abrt_get_cmdline char* get_cmdline(pid_t pid); +#define get_environ abrt_get_environ +char* get_environ(pid_t pid); /* Returns 1 if abrtd daemon is running, 0 otherwise. */ #define daemon_is_ok abrt_daemon_is_ok diff --git a/src/lib/get_cmdline.c b/src/lib/get_cmdline.c index 9855eb3c..b3d73f17 100644 --- a/src/lib/get_cmdline.c +++ b/src/lib/get_cmdline.c @@ -21,7 +21,6 @@ static char *append_escaped(char *start, const char *s) { char hex_char_buf[] = "\\x00"; - *start++ = ' '; char *dst = start; const unsigned char *p = (unsigned char *)s; @@ -72,34 +71,66 @@ static char *append_escaped(char *start, const char *s) } } -// taken from kernel -#define COMMAND_LINE_SIZE 2048 -char* get_cmdline(pid_t pid) +static char* get_escaped(const char *path, char separator) { - char path[sizeof("/proc/%lu/cmdline") + sizeof(long)*3]; - char cmdline[COMMAND_LINE_SIZE]; - char escaped_cmdline[COMMAND_LINE_SIZE*4 + 4]; + unsigned total_esc_len = 0; + char *escaped = NULL; - escaped_cmdline[1] = '\0'; - sprintf(path, "/proc/%lu/cmdline", (long)pid); int fd = open(path, O_RDONLY); if (fd >= 0) { - int len = read(fd, cmdline, sizeof(cmdline) - 1); - close(fd); - - if (len > 0) + while (1) { - cmdline[len] = '\0'; - char *src = cmdline; - char *dst = escaped_cmdline; - while ((src - cmdline) < len) + /* read and escape one block */ + char buffer[4 * 1024 + 1]; + int len = read(fd, buffer, sizeof(buffer) - 1); + if (len <= 0) + break; + buffer[len] = '\0'; + escaped = xrealloc(escaped, total_esc_len + (len+1) * 4); + char *src = buffer; + char *dst = escaped + total_esc_len; + while (1) { - dst = append_escaped(dst, src); + /* escape till next '\0' char */ + char *d = append_escaped(dst, src); + total_esc_len += (d - dst); + dst = d; src += strlen(src) + 1; + if ((src - buffer) >= len) + break; + *dst++ = separator; } + *dst = '\0'; } + close(fd); } - return xstrdup(escaped_cmdline + 1); /* +1 skips extraneous leading space */ + return escaped; +} + +char* get_cmdline(pid_t pid) +{ + char path[sizeof("/proc/%lu/cmdline") + sizeof(long)*3]; + sprintf(path, "/proc/%lu/cmdline", (long)pid); + return get_escaped(path, ' '); +} + +char* get_environ(pid_t pid) +{ + char path[sizeof("/proc/%lu/environ") + sizeof(long)*3]; + sprintf(path, "/proc/%lu/environ", (long)pid); + char *e = get_escaped(path, '\n'); + /* Append last '\n' if needed */ + if (e && e[0]) + { + unsigned len = strlen(e); + if (e[len-1] != '\n') + { + e = xrealloc(e, len + 2); + e[len] = '\n'; + e[len+1] = '\0'; + } + } + return e; } -- cgit