[RFC][PATCH] proc: add "stacktrace" file

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi,

I am not entirely convinced of the usefulness (or safety) of this patch
yet, so I'm requesting comments.

The rationale for this patch was to be able to detect where a task was
hanging if it was stuck somewhere in the kernel and other parts of the
system were still alive. Though there are several other ways to read
this information, I guess asking a reporter to cat /proc/<pid>/stacktrace
would be one of the easiest. Not that this situation occurs frequently,
though (I have no idea, to be frank).

I also have some specific concerns:

Do we need to lock the task before accessing its stack, or will the proc
system take care of all this for us?

Can save_stack_trace() ever crash the kernel, say, if the task is in the
middle of switching stacks, has an invalid stack pointer, etc.?

It also seems quite clear that it is unsafe to pour an arbitrary amount
of information into a buffer of finite, but unknown, length. I suppose
the function should be rewritten to take advantage of seq_file lest
random memory corruption should occur.

So again, the patch is probably pure and utter crap, but I would like to
hear if the idea of it is useful and (if so) what would be needed to fix
it up.


Vegard


>From 29a2cff09e52ea9a7ecc4bef3e52012d1dd3d525 Mon Sep 17 00:00:00 2001
From: Vegard Nossum <vegard.nossum@xxxxxxxxx>
Date: Fri, 16 May 2008 16:33:29 +0200
Subject: [PATCH] proc: add "stacktrace" file

This patch adds a /proc/<pid>/stacktrace file which will show the current
kernel stack trace of the specified pid.

Signed-off-by: Vegard Nossum <vegard.nossum@xxxxxxxxx>
---
 fs/proc/base.c |   49 +++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 49 insertions(+), 0 deletions(-)

diff --git a/fs/proc/base.c b/fs/proc/base.c
index 808cbdc..9e2e29e 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -64,6 +64,7 @@
 #include <linux/mm.h>
 #include <linux/rcupdate.h>
 #include <linux/kallsyms.h>
+#include <linux/stacktrace.h>
 #include <linux/resource.h>
 #include <linux/module.h>
 #include <linux/mount.h>
@@ -318,6 +319,48 @@ static int proc_pid_wchan(struct task_struct *task, char *buffer)
 }
 #endif /* CONFIG_KALLSYMS */
 
+#ifdef CONFIG_STACKTRACE
+static int proc_stack_trace(struct task_struct *task, char *buffer)
+{
+	char *cur;
+	unsigned int len;
+
+	struct stack_trace trace;
+	unsigned long entries[32];
+	int i;
+
+	cur = buffer;
+
+	trace.nr_entries = 0;
+	trace.entries = entries;
+	trace.max_entries = ARRAY_SIZE(entries);
+	trace.skip = 0;
+
+	save_stack_trace_tsk(task, &trace);
+
+	for(i = 0; i < trace.nr_entries; ++i) {
+		unsigned long ip = trace.entries[i];
+
+		len = sprintf(cur, "[<%p>] ", (void *) ip);
+		if (len < 0)
+			return len;
+		cur += len;
+
+		len = sprint_symbol(cur, ip);
+		if (len < 0)
+			return len;
+		cur += len;
+
+		len = sprintf(cur, "\n");
+		if (len < 0)
+			return len;
+		cur += len;
+	}
+
+	return cur - buffer;
+}
+#endif
+
 #ifdef CONFIG_SCHEDSTATS
 /*
  * Provides /proc/PID/schedstat
@@ -2425,6 +2468,9 @@ static const struct pid_entry tgid_base_stuff[] = {
 #ifdef CONFIG_KALLSYMS
 	INF("wchan",      S_IRUGO, pid_wchan),
 #endif
+#ifdef CONFIG_STACKTRACE
+	INF("stacktrace", S_IRUSR, stack_trace),
+#endif
 #ifdef CONFIG_SCHEDSTATS
 	INF("schedstat",  S_IRUGO, pid_schedstat),
 #endif
@@ -2757,6 +2803,9 @@ static const struct pid_entry tid_base_stuff[] = {
 #ifdef CONFIG_KALLSYMS
 	INF("wchan",     S_IRUGO, pid_wchan),
 #endif
+#ifdef CONFIG_STACKTRACE
+	INF("stacktrace", S_IRUSR, stack_trace),
+#endif
 #ifdef CONFIG_SCHEDSTATS
 	INF("schedstat", S_IRUGO, pid_schedstat),
 #endif
-- 
1.5.4.1


--
To unsubscribe from this list: send an email with
"unsubscribe kernelnewbies" to ecartis@xxxxxxxxxxxx
Please read the FAQ at http://kernelnewbies.org/FAQ


[Index of Archives]     [Newbies FAQ]     [Linux Kernel Mentors]     [Linux Kernel Development]     [IETF Annouce]     [Git]     [Networking]     [Security]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux SCSI]     [Linux ACPI]
  Powered by Linux