From 87b82389c258f068d5aedbeeabe193a0295f9775 Mon Sep 17 00:00:00 2001 From: Nicholas Lowell Date: Mon, 20 Jun 2016 12:34:30 -0400 Subject: [PATCH 1/3] Print thread name when dumping backtrace Keeping proc interactions isoltated: added function in proc.h/.c that prints thread name to stdout. It is then used by backtrace.c directly to keep from having to store the string in memory in snapshot or any other struct --- src/backtrace.c | 8 ++++++-- src/proc.c | 24 ++++++++++++++++++++++++ src/proc.h | 6 ++++++ 3 files changed, 36 insertions(+), 2 deletions(-) mode change 100644 => 100755 src/backtrace.c mode change 100644 => 100755 src/proc.c mode change 100644 => 100755 src/proc.h diff --git a/src/backtrace.c b/src/backtrace.c old mode 100644 new mode 100755 index f1761c4..feb50a4 --- a/src/backtrace.c +++ b/src/backtrace.c @@ -108,8 +108,10 @@ int backtrace_snapshot(int pid, int *tids, int *index, int nr_tids) return -1; for (i = 0; i < snap->num_threads; ++i) { - printf("-------------------- thread %d (%d) --------------------\n", + printf("-------------------- thread %d (%d) (", (index != NULL ? index[i] : i+1), snap->tids[i]); + print_proc_comm(snap->tids[i]); + printf(") --------------------\n"); snap->cur_thr = i; if (backtrace_thread(&snapshot_addr_space_accessors, snap) < 0) @@ -145,8 +147,10 @@ int backtrace_ptrace(int pid, int *tids, int *index, int nr_tids) for (i = 0; i < count; ++i) { void *upt_info; - printf("-------------------- thread %d (%d) --------------------\n", + printf("-------------------- thread %d (%d) (", (index != NULL ? index[i] : i+1), threads[i]); + print_proc_comm(threads[i]); + printf(") --------------------\n"); if (threads[i] != pid && attach_thread(threads[i]) < 0) { rc = -1; diff --git a/src/proc.c b/src/proc.c old mode 100644 new mode 100755 index 5674df0..084d277 --- a/src/proc.c +++ b/src/proc.c @@ -191,6 +191,30 @@ int print_proc_maps(int pid) return system(cmd); } +int print_proc_comm(int pid) +{ + FILE *f; + char buf[32] = ""; + int i; + int rc = -1; + + snprintf(buf, sizeof(buf), "/proc/%d/comm", pid); + if ((f = fopen(buf, "r")) == NULL) { + fprintf(stderr, "cannot open %s: %s\n", buf, strerror(errno)); + return -1; + } + + if (fgets(buf, sizeof(buf), f)) { + i = strcspn(buf, "\n"); + buf[i] = '\0'; + printf("%s", buf); + rc = 0; + } + + fclose(f); + return rc; +} + /* * filter for scandir(). choose only thread identifiers */ diff --git a/src/proc.h b/src/proc.h old mode 100644 new mode 100755 index 127b71f..7bea5df --- a/src/proc.h +++ b/src/proc.h @@ -27,6 +27,12 @@ struct mem_map *create_maps(int pid); */ int print_proc_maps(int pid); +/* + * simple routine to print process comm for + * debugging or advanced error reporting + */ +int print_proc_comm(int pid); + /* * get thread identifiers of the process */ From eff3adb8f77cfea2f8d0055a9962e0df06f427cd Mon Sep 17 00:00:00 2001 From: Nicholas Lowell Date: Mon, 27 Jun 2016 13:49:10 -0400 Subject: [PATCH 2/3] Cleaner string handling and printing of process comm --- src/backtrace.c | 18 +++++++++--------- src/proc.c | 20 +++++++++++++++----- src/proc.h | 5 ++--- 3 files changed, 26 insertions(+), 17 deletions(-) diff --git a/src/backtrace.c b/src/backtrace.c index feb50a4..4d059fe 100755 --- a/src/backtrace.c +++ b/src/backtrace.c @@ -103,15 +103,15 @@ int backtrace_snapshot(int pid, int *tids, int *index, int nr_tids) { int i, rc = 0; struct snapshot *snap; - + if ((snap = get_snapshot(pid, tids, index, nr_tids)) == NULL) return -1; for (i = 0; i < snap->num_threads; ++i) { - printf("-------------------- thread %d (%d) (", - (index != NULL ? index[i] : i+1), snap->tids[i]); - print_proc_comm(snap->tids[i]); - printf(") --------------------\n"); + char comm[16]; + + get_thread_comm(snap->tids[i], comm, sizeof(comm)); + printf("-------------------- thread %d (%d) (%s) --------------------\n", (index != NULL ? index[i] : i+1), snap->tids[i], comm); snap->cur_thr = i; if (backtrace_thread(&snapshot_addr_space_accessors, snap) < 0) @@ -146,11 +146,11 @@ int backtrace_ptrace(int pid, int *tids, int *index, int nr_tids) for (i = 0; i < count; ++i) { void *upt_info; + char comm[16]; + + get_thread_comm(threads[i], comm, sizeof(comm)); - printf("-------------------- thread %d (%d) (", - (index != NULL ? index[i] : i+1), threads[i]); - print_proc_comm(threads[i]); - printf(") --------------------\n"); + printf("-------------------- thread %d (%d) (%s) --------------------\n",(index != NULL ? index[i] : i+1), threads[i], comm); if (threads[i] != pid && attach_thread(threads[i]) < 0) { rc = -1; diff --git a/src/proc.c b/src/proc.c index 084d277..2d38cd3 100755 --- a/src/proc.c +++ b/src/proc.c @@ -34,6 +34,9 @@ #define SLEEP_WAIT 500 +#define MAX(a,b) ((a) > (b) ? a : b) +#define MIN(a,b) ((a) < (b) ? a : b) + int attached_pid = 0; /* timeout on waiting for process to stop (us) */ @@ -191,13 +194,18 @@ int print_proc_maps(int pid) return system(cmd); } -int print_proc_comm(int pid) +int get_thread_comm(int pid, char * dst, size_t n) { FILE *f; - char buf[32] = ""; - int i; + char buf[32]; + int i, x; int rc = -1; + if (dst == NULL) + { + return -1; + } + snprintf(buf, sizeof(buf), "/proc/%d/comm", pid); if ((f = fopen(buf, "r")) == NULL) { fprintf(stderr, "cannot open %s: %s\n", buf, strerror(errno)); @@ -207,8 +215,10 @@ int print_proc_comm(int pid) if (fgets(buf, sizeof(buf), f)) { i = strcspn(buf, "\n"); buf[i] = '\0'; - printf("%s", buf); - rc = 0; + x = MAX(MIN(n-1, i+1), 0); + strncpy(dst, buf, x); + dst[x] = '\0'; + rc = x; } fclose(f); diff --git a/src/proc.h b/src/proc.h index 7bea5df..11c4ee9 100755 --- a/src/proc.h +++ b/src/proc.h @@ -28,10 +28,9 @@ struct mem_map *create_maps(int pid); int print_proc_maps(int pid); /* - * simple routine to print process comm for - * debugging or advanced error reporting + * copy pid process comm into dst string, up to n characters */ -int print_proc_comm(int pid); +int get_thread_comm(int pid, char * dst, size_t n); /* * get thread identifiers of the process From 1a15b0dd9d9996df5cab7f992098da4791e39f85 Mon Sep 17 00:00:00 2001 From: Nicholas Lowell Date: Mon, 27 Jun 2016 15:05:57 -0400 Subject: [PATCH 3/3] Standardize right side padding when printing thread names --- src/backtrace.c | 20 ++++++++++++++++---- src/proc.c | 4 ++-- 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/src/backtrace.c b/src/backtrace.c index 4d059fe..48d0148 100755 --- a/src/backtrace.c +++ b/src/backtrace.c @@ -108,10 +108,16 @@ int backtrace_snapshot(int pid, int *tids, int *index, int nr_tids) return -1; for (i = 0; i < snap->num_threads; ++i) { + int x; char comm[16]; + char end_pad[25] = "------------------------"; - get_thread_comm(snap->tids[i], comm, sizeof(comm)); - printf("-------------------- thread %d (%d) (%s) --------------------\n", (index != NULL ? index[i] : i+1), snap->tids[i], comm); + x = get_thread_comm(snap->tids[i], comm, sizeof(comm)); + if (x > 0 && x <= sizeof(end_pad)) + { + end_pad[sizeof(end_pad) - x] = '\0'; + printf("-------------- thread %d (%d) (%s) %s\n", (index != NULL ? index[i] : i+1), snap->tids[i], comm, end_pad); + } snap->cur_thr = i; if (backtrace_thread(&snapshot_addr_space_accessors, snap) < 0) @@ -146,11 +152,17 @@ int backtrace_ptrace(int pid, int *tids, int *index, int nr_tids) for (i = 0; i < count; ++i) { void *upt_info; + int x; char comm[16]; + char end_pad[25] = "------------------------"; - get_thread_comm(threads[i], comm, sizeof(comm)); + x = get_thread_comm(threads[i], comm, sizeof(comm)); - printf("-------------------- thread %d (%d) (%s) --------------------\n",(index != NULL ? index[i] : i+1), threads[i], comm); + if (x > 0 && x <= sizeof(end_pad)) + { + end_pad[sizeof(end_pad) - x] = '\0'; + printf("-------------- thread %d (%d) (%s) %s\n", (index != NULL ? index[i] : i + 1), threads[i], comm, end_pad); + } if (threads[i] != pid && attach_thread(threads[i]) < 0) { rc = -1; diff --git a/src/proc.c b/src/proc.c index 2d38cd3..266c6df 100755 --- a/src/proc.c +++ b/src/proc.c @@ -215,9 +215,9 @@ int get_thread_comm(int pid, char * dst, size_t n) if (fgets(buf, sizeof(buf), f)) { i = strcspn(buf, "\n"); buf[i] = '\0'; - x = MAX(MIN(n-1, i+1), 0); + x = MAX(MIN(n, i+1), 1); strncpy(dst, buf, x); - dst[x] = '\0'; + dst[x-1] = '\0'; rc = x; }