blob: 4a9fef6244ed0f0247c1e13afc225235955219f6 [file] [log] [blame]
Brian Swetland6669dac2008-04-08 22:34:46 -07001/* drivers/android/kernel_debugger.c
2 *
3 * Guts of the kernel debugger.
4 * Needs something to actually push commands to it.
5 *
6 * Copyright (C) 2007-2008 Google, Inc.
7 *
8 * This software is licensed under the terms of the GNU General Public
9 * License version 2, as published by the Free Software Foundation, and
10 * may be copied, distributed, and modified under those terms.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 */
18
19#include <linux/ctype.h>
20#include <linux/device.h>
21#include <linux/sched.h>
22#include <linux/spinlock.h>
23#include <linux/sysrq.h>
24#include <linux/kernel_debugger.h>
25
26#define dprintf(fmt...) (ctxt->printf(ctxt->cookie, fmt))
27
28static void do_ps(struct kdbg_ctxt *ctxt)
29{
30 struct task_struct *g, *p;
31 unsigned state;
32 static const char stat_nam[] = "RSDTtZX";
33
34 dprintf("pid ppid prio task pc\n");
35 read_lock(&tasklist_lock);
36 do_each_thread(g, p) {
37 state = p->state ? __ffs(p->state) + 1 : 0;
38 dprintf("%5d %5d %4d ", p->pid, p->parent->pid, p->prio);
39 dprintf("%-13.13s %c", p->comm,
40 state >= sizeof(stat_nam) ? '?' : stat_nam[state]);
41 if (state == TASK_RUNNING)
42 dprintf(" running\n");
43 else
44 dprintf(" %08lx\n", thread_saved_pc(p));
45 } while_each_thread(g, p);
46 read_unlock(&tasklist_lock);
47}
48
49int log_buf_copy(char *dest, int idx, int len);
50extern int do_syslog(int type, char __user *bug, int count);
51static void do_sysrq(struct kdbg_ctxt *ctxt, char rq)
52{
53 char buf[128];
54 int ret;
55 int idx = 0;
56 do_syslog(5 /* clear */, NULL, 0);
Erik Gilling12650972010-08-30 18:16:30 -070057 handle_sysrq(rq);
Brian Swetland6669dac2008-04-08 22:34:46 -070058 while (1) {
59 ret = log_buf_copy(buf, idx, sizeof(buf) - 1);
60 if (ret <= 0)
61 break;
62 buf[ret] = 0;
63 dprintf("%s", buf);
64 idx += ret;
65 }
66}
67
Dmitry Shmidtc4452542010-11-16 15:39:43 -080068static void do_help(struct kdbg_ctxt *ctxt)
69{
70 dprintf("Kernel Debugger commands:\n");
71 dprintf(" ps Process list\n");
72 dprintf(" sysrq sysrq options\n");
73 dprintf(" sysrq <param> Execute sysrq with <param>\n");
74}
75
Brian Swetland6669dac2008-04-08 22:34:46 -070076int kernel_debugger(struct kdbg_ctxt *ctxt, char *cmd)
77{
78 if (!strcmp(cmd, "ps"))
79 do_ps(ctxt);
80 if (!strcmp(cmd, "sysrq"))
81 do_sysrq(ctxt, 'h');
82 if (!strncmp(cmd, "sysrq ", 6))
83 do_sysrq(ctxt, cmd[6]);
Dmitry Shmidtc4452542010-11-16 15:39:43 -080084 if (!strcmp(cmd, "help"))
85 do_help(ctxt);
Brian Swetland6669dac2008-04-08 22:34:46 -070086
87 return 0;
88}
89