summaryrefslogtreecommitdiff
path: root/src/coredump.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/coredump.c')
-rw-r--r--src/coredump.c171
1 files changed, 102 insertions, 69 deletions
diff --git a/src/coredump.c b/src/coredump.c
index 76d20de..2990cc7 100644
--- a/src/coredump.c
+++ b/src/coredump.c
@@ -22,6 +22,7 @@
* Authors:
* Arjan van de Ven <arjan@linux.intel.com>
* William Douglas <william.douglas@intel.com>
+ * Tim Pepper <timothy.c.pepper@linux.intel.com>
*/
#include <unistd.h>
@@ -47,14 +48,6 @@ int sig = 0;
const char *core_folder = "/var/lib/corewatcher/";
const char *processed_folder = "/var/lib/corewatcher/processed/";
-/*
- * the application must initialize the GMutex's
- * core_status.processing_mtx, core_status.queued_mtx,
- * processing_queue_mtx and gdb_mtx
- * before calling into this file's scan_corefolders()
- * (also since that calls submit_queue() there are dependencies
- * there which need taken care of too)
- */
/* Always pick up the processing_mtx and then the
processing_queue_mtx, reverse for setting down */
/* Always pick up the gdb_mtx and then the
@@ -330,6 +323,8 @@ static struct oops *extract_core(char *fullpath, char *appfile)
int parsing_maps = 0;
struct stat stat_buf;
+ fprintf(stderr, "+ extract_core() called for %s\n", fullpath);
+
if (asprintf(&command, "LANG=C gdb --batch -f %s %s -x /etc/corewatcher/gdb.command 2> /dev/null", appfile, fullpath) == -1)
return NULL;
@@ -358,6 +353,8 @@ static struct oops *extract_core(char *fullpath, char *appfile)
h1 = strdup("Unknown");
file = popen(command, "r");
+ if (!file)
+ fprintf(stderr, "+ gdb failed for %s\n", fullpath);
while (file && !feof(file)) {
size_t size = 0;
@@ -374,6 +371,9 @@ static struct oops *extract_core(char *fullpath, char *appfile)
parsing_maps = 1;
/*continue;*/
}
+ if (strncmp(line, "No shared libraries loaded at this time.", 40) == 0) {
+ break;
+ }
if (!parsing_maps) { /* parsing backtrace */
c2 = c1;
@@ -414,6 +414,12 @@ fixup: /* gdb outputs some 0x1a's which break XML */
pclose(file);
free(command);
+ if (!h1)
+ h1 = strdup("Unknown");
+
+ if (!m1)
+ m1 = strdup(" Unknown");
+
ret = asprintf(&text,
"%s"
"backtrace: |\n"
@@ -440,52 +446,49 @@ fixup: /* gdb outputs some 0x1a's which break XML */
}
/*
- * filename is of the form core_XXXX[.blah]
- * we need to get the pid out as we want
- * output of the form XXXX[.ext]
+ * input filename has the form: core_$APP_$TIMESTAMP[.$PID]
+ * output filename has form of: $APP_$TIMESTAMP[.ext]
*/
char *get_core_filename(char *filename, char *ext)
{
- char *pid = NULL, *c = NULL, *s = NULL, *detail_filename = NULL;
+ char *name = NULL, *dotpid = NULL, *stamp = NULL, *detail_filename = NULL;
if (!filename)
return NULL;
- if (!(s = strstr(filename, "_")))
+ if (!(stamp = strstr(filename, "_")))
return NULL;
- if (!(++s))
- return NULL;
- /* causes valgrind whining because we copy from middle of a string */
- if (!(pid = strdup(s)))
+ if (!(++stamp))
return NULL;
- c = strstr(pid, ".");
+ if (!(name = strdup(stamp)))
+ return NULL;
- if (c)
- *c = '\0';
+ /* strip trailing .PID if present */
+ dotpid = strstr(name, ".");
+ if (dotpid)
+ *dotpid = '\0';
if (ext) {
- /* causes valgrind whining because we copy from middle of a string */
- if ((asprintf(&detail_filename, "%s%s.%s", processed_folder, pid, ext)) == -1) {
- free(pid);
+ if ((asprintf(&detail_filename, "%s%s.%s", processed_folder, name, ext)) == -1) {
+ free(name);
return NULL;
}
} else {
- /* causes valgrind whining because we copy from middle of a string */
- if ((asprintf(&detail_filename, "%s%s", processed_folder, pid)) == -1) {
- free(pid);
+ if ((asprintf(&detail_filename, "%s%s", processed_folder, name)) == -1) {
+ free(name);
return NULL;
}
}
+ free(name);
- free(pid);
return detail_filename;
}
/*
* Write the backtrace from the core file into a text
- * file named after the pid
+ * file named as $APP_$TIMESTAMP.txt
*/
static void write_core_detail_file(char *filename, char *text)
{
@@ -517,37 +520,49 @@ static void write_core_detail_file(char *filename, char *text)
*/
static void remove_from_processing_queue(void)
{
+ fprintf(stderr, "+ removing processing_queue head\n");
free(processing_queue[pq_head]);
processing_queue[pq_head++] = NULL;
- if (pq_head == MAX_PROCESSING_OOPS)
+ if (pq_head == MAX_PROCESSING_OOPS) {
+ fprintf(stderr, "+ wrapping processing_queue head to 0 (bugs here?)\n");
pq_head = 0;
+ }
}
/*
- * Removes file from processing_oops hash based on pid.
- * Extracts pid from the fullpath such that
- * /home/user/core.pid will be tranformed into just the pid.
+ * Removes file from processing_oops hash based on core name,
+ * extracting that core name from a fullpath such as
+ * "/${processed_folder}/core_$APP_$TIMESTAMP.$PID"
+ * in order to get just "$APP_$TIMESTAMP"
*
* Expects the lock on the given hash to be held.
*/
-void remove_pid_from_hash(char *fullpath, GHashTable *ht)
+void remove_name_from_hash(char *fullpath, GHashTable *ht)
{
- char *c1 = NULL, *c2 = NULL;
+ char *name = NULL, *corename = NULL, *shortname = NULL;
- if (!(c1 = strip_directories(fullpath)))
+ if (!(name = strip_directories(fullpath)))
return;
- if (!(c2 = get_core_filename(c1, NULL))) {
- free(c1);
+ if (!(corename = get_core_filename(name, NULL))) {
+ free(name);
return;
}
+ free(name);
- free(c1);
+ if (!(shortname = strip_directories(corename))) {
+ free(corename);
+ return;
+ }
+ free(corename);
- g_hash_table_remove(ht, c2);
+ if (g_hash_table_remove(ht, shortname))
+ fprintf(stderr, "+ core %s removed from processing_oops hash table\n", shortname);
+ else
+ fprintf(stderr, "+ core %s not in processing_oops hash table\n", shortname);
- free(c2);
+ free(shortname);
}
/*
@@ -581,13 +596,12 @@ static struct oops *process_common(char *fullpath)
/*
* Processes .to-process core files.
- * Also creates the pid.txt file and adds
+ * Also creates the $APP_$TIMESTAMP.txt file and adds
* the oops struct to the submit queue
*
* Picks up and sets down the gdb_mtx and
* picks up and sets down the processing_queue_mtx.
* (held at the same time in that order)
- * Also will pick up and sets down the queued_mtx.
*/
static void *process_new(void __unused *vp)
{
@@ -598,28 +612,40 @@ static void *process_new(void __unused *vp)
g_mutex_lock(&gdb_mtx);
g_mutex_lock(&processing_queue_mtx);
+ fprintf(stderr, "+ Entered process_new()\n");
+
if (!(fullpath = processing_queue[pq_head])) {
- /* something went quite wrong */
+ fprintf(stderr, "+ processing_queue corruption?\n");
g_mutex_unlock(&processing_queue_mtx);
g_mutex_unlock(&gdb_mtx);
g_mutex_unlock(&core_status.processing_mtx);
return NULL;
}
- if (!(corefn = strip_directories(fullpath)))
+ if (!(corefn = strip_directories(fullpath))) {
+ fprintf(stderr, "+ No corefile? (%s)\n", fullpath);
goto clean_process_new;
+ }
- if (!(procfn = replace_name(fullpath, ".to-process", ".processed")))
+ if (!(procfn = replace_name(fullpath, ".to-process", ".processed"))) {
+ fprintf(stderr, "+ Problems with filename manipulation for %s\n", corefn);
goto clean_process_new;
+ }
- if (!(oops = process_common(fullpath)))
+ if (!(oops = process_common(fullpath))) {
+ fprintf(stderr, "+ Problems processing %s\n", procfn);
goto clean_process_new;
+ }
- if (!(oops->detail_filename = get_core_filename(corefn, "txt")))
+ if (!(oops->detail_filename = get_core_filename(corefn, "txt"))) {
+ fprintf(stderr, "+ Problems with filename manipulation for %s\n", procfn);
goto clean_process_new;
+ }
- if (rename(fullpath, procfn))
+ if (rename(fullpath, procfn)) {
+ fprintf(stderr, "+ Unable to move %s to %s\n", fullpath, procfn);
goto clean_process_new;
+ }
free(oops->filename);
oops->filename = procfn;
@@ -632,20 +658,18 @@ static void *process_new(void __unused *vp)
write_core_detail_file(corefn, oops->text);
- g_mutex_lock(&core_status.queued_mtx);
queue_backtrace(oops);
- g_mutex_unlock(&core_status.queued_mtx);
- /* don't need to free procfn because was set to oops->filename and that gets free'd */
+ fprintf(stderr, "+ Leaving process_new() with %s queued\n", oops->detail_filename);
+
+ /* mustn't free procfn because it was hung on oops->filename */
free(corefn);
- FREE_OOPS(oops);
return NULL;
clean_process_new:
- remove_pid_from_hash(fullpath, core_status.processing_oops);
+ remove_name_from_hash(fullpath, core_status.processing_oops);
remove_from_processing_queue();
free(procfn);
- procfn = NULL; /* don't know if oops->filename == procfn so be safe */
free(corefn);
FREE_OOPS(oops);
g_mutex_unlock(&processing_queue_mtx);
@@ -660,7 +684,6 @@ clean_process_new:
* Picks up and sets down the gdb_mtx.
* Picks up and sets down the processing_queue_mtx.
* (held at the same time in that order)
- * Also will pick up and sets down the queued_mtx.
*/
static void *process_old(void __unused *vp)
{
@@ -670,37 +693,45 @@ static void *process_old(void __unused *vp)
g_mutex_lock(&gdb_mtx);
g_mutex_lock(&processing_queue_mtx);
+ fprintf(stderr, "+ Entered process_old()\n");
+
if (!(fullpath = processing_queue[pq_head])) {
- /* something went quite wrong */
+ fprintf(stderr, "+ processing_queue corruption?\n");
g_mutex_unlock(&processing_queue_mtx);
g_mutex_unlock(&gdb_mtx);
return NULL;
}
+ fprintf(stderr, "+ Reprocessing %s\n", fullpath);
- if (!(corefn = strip_directories(fullpath)))
+ if (!(corefn = strip_directories(fullpath))) {
+ fprintf(stderr, "+ No corefile? (%s)\n", fullpath);
goto clean_process_old;
+ }
- if (!(oops = process_common(fullpath)))
+ if (!(oops = process_common(fullpath))) {
+ fprintf(stderr, "+ Problems processing %s\n", corefn);
goto clean_process_old;
+ }
- if (!(oops->detail_filename = get_core_filename(corefn, "txt")))
+ if (!(oops->detail_filename = get_core_filename(corefn, "txt"))) {
+ fprintf(stderr, "+ Problems with filename manipulation for %s\n", corefn);
goto clean_process_old;
+ }
remove_from_processing_queue();
g_mutex_unlock(&processing_queue_mtx);
g_mutex_unlock(&gdb_mtx);
- g_mutex_lock(&core_status.queued_mtx);
queue_backtrace(oops);
- g_mutex_unlock(&core_status.queued_mtx);
+
+ fprintf(stderr, "+ Leaving process_old() with %s queued\n", oops->detail_filename);
free(corefn);
- FREE_OOPS(oops);
return NULL;
clean_process_old:
- remove_pid_from_hash(fullpath, core_status.processing_oops);
+ remove_name_from_hash(fullpath, core_status.processing_oops);
remove_from_processing_queue();
free(corefn);
FREE_OOPS(oops);
@@ -710,7 +741,7 @@ clean_process_old:
}
/*
- * Adds corefile (based on pid) to the processing_oops
+ * Adds corefile (based on name) to the processing_oops
* hash table if it is not already there, then
* tries to add to the processing_queue.
*
@@ -739,6 +770,7 @@ static int add_to_processing(char *fullpath)
g_mutex_lock(&core_status.processing_mtx);
if (g_hash_table_lookup(core_status.processing_oops, c2)) {
g_mutex_unlock(&core_status.processing_mtx);
+ fprintf(stderr, "+ ...name %s already in processing_oops hash table\n", c2);
goto clean_add_to_processing;
}
@@ -746,6 +778,7 @@ static int add_to_processing(char *fullpath)
if (processing_queue[pq_tail]) {
g_mutex_unlock(&processing_queue_mtx);
g_mutex_unlock(&core_status.processing_mtx);
+ fprintf(stderr, "+ ...processing_queue full\n");
goto clean_add_to_processing;
}
@@ -811,7 +844,7 @@ static void scan_core_folder(void __unused *unused)
dir = opendir(core_folder);
if (!dir)
return;
- fprintf(stderr, "+ scanning %s...\n", core_folder);
+ fprintf(stderr, "+ Begin scanning %s...\n", core_folder);
while(1) {
free(fullpath);
fullpath = NULL;
@@ -824,7 +857,7 @@ static void scan_core_folder(void __unused *unused)
if (strncmp(entry->d_name, "core_", 5))
continue;
- /* matched core_#### where #### is the pid of the process */
+ /* matched core_#### */
r = asprintf(&fullpath, "%s%s", core_folder, entry->d_name);
if (r == -1) {
fullpath = NULL;
@@ -848,6 +881,7 @@ static void scan_core_folder(void __unused *unused)
}
}
closedir(dir);
+ fprintf(stderr, "+ End scanning %s...\n", core_folder);
}
static void scan_processed_folder(void __unused *unused)
@@ -861,7 +895,7 @@ static void scan_processed_folder(void __unused *unused)
dir = opendir(processed_folder);
if (!dir)
return;
- fprintf(stderr, "+ scanning %s...\n", processed_folder);
+ fprintf(stderr, "+ Begin scanning %s...\n", processed_folder);
while(1) {
free(fullpath);
fullpath = NULL;
@@ -889,6 +923,7 @@ static void scan_processed_folder(void __unused *unused)
reprocess_corefile(fullpath);
}
closedir(dir);
+ fprintf(stderr, "+ End scanning %s...\n", processed_folder);
}
int scan_corefolders(void __unused *unused)
@@ -896,7 +931,5 @@ int scan_corefolders(void __unused *unused)
scan_core_folder(NULL);
scan_processed_folder(NULL);
- submit_queue();
-
return 1;
}