Printx commands (off by default)
authorBarret Rhoden <brho@cs.berkeley.edu>
Thu, 18 Sep 2014 00:39:01 +0000 (17:39 -0700)
committerBarret Rhoden <brho@cs.berkeley.edu>
Thu, 18 Sep 2014 00:59:33 +0000 (17:59 -0700)
A common tool I use is to printk, or now even trace_printk, to debug something.
But you don't always want the printing on, due to massive amounts of printing
under certain circumstances.

Invariably, I'd make a throw-away function that I would kfunc to toggle the
printing on and off.  I already do something similar with the poor-mans
ftrace/spatch.

"printx" is the term for this debugging style printing, and it can be turned on
and off.  There is a monitor command (px) that toggles it.  And just for fun
(and profit) there's a Kprof file to control it too (kprintx).

$ echo on > /prof/kprintx (once #K is attached).

The 'x' comes from "xme", which is the name of the one-off kfunc function I
usually use for debugging.

The default value is off.  The poor-mans ftrace uses printx_on as well, so if
you want the tracing on, you'll need to turn it on manually.  This is a change,
but a good one.

kern/drivers/dev/kprof.c
kern/include/kdebug.h
kern/include/monitor.h
kern/src/kdebug.c
kern/src/monitor.c

index 85f8ae0..8aac92a 100644 (file)
@@ -66,6 +66,7 @@ enum{
        Kprofctlqid,
        Kprofoprofileqid,
        Kptraceqid,
+       Kprintxqid,
 };
 struct dirtab kproftab[]={
        {".",           {Kprofdirqid, 0, QTDIR},0,      DMDIR|0550},
@@ -73,6 +74,7 @@ struct dirtab kproftab[]={
        {"kpctl",       {Kprofctlqid},          0,      0600},
        {"kpoprofile",  {Kprofoprofileqid},     0,      0600},
        {"kptrace",     {Kptraceqid},           0,      0600},
+       {"kprintx",     {Kprintxqid},           0,      0600},
 };
 
 static struct chan*
@@ -285,6 +287,9 @@ kprofread(struct chan *c, void *va, long n, int64_t off)
                } else
                        error("no systrace queue");
                break;
+       case Kprintxqid:
+               n = readstr(offset, va, n, printx_on ? "on" : "off");
+               break;
        default:
                n = 0;
                break;
@@ -334,6 +339,16 @@ kprofwrite(struct chan *c, void *a, long n, int64_t unused)
                pc = strtoul(a, 0, 0);
                oprofile_add_trace(pc);
                break;
+       case Kprintxqid:
+               if (!strncmp(a, "on", 2))
+                       set_printx(1);
+               else if (!strncmp(a, "off", 3))
+                       set_printx(0);
+               else if (!strncmp(a, "toggle", 6))      /* why not. */
+                       set_printx(2);
+               else
+                       error("invalid option to Kprintx %s\n", a);
+               break;
        default:
                error(Ebadusefd);
        }
index 970e01f..40d401f 100644 (file)
@@ -33,6 +33,11 @@ void hexdump(void *v, int length);
 void pahexdump(uintptr_t pa, int length);
 int printdump(char *buf, int buflen, uint8_t *data);
 
+extern bool printx_on;
+void set_printx(int mode);
+#define printx(args...) if (printx_on) printk(args)
+#define trace_printx(args...) if (printx_on) trace_printk(args)
+
 #include <oprofile.h>
 #define TRACEME() oprofile_add_backtrace(read_pc(), read_bp())
 
index b1805c9..476f181 100644 (file)
@@ -38,5 +38,6 @@ int mon_bb(int argc, char **argv, struct hw_trapframe *hw_tf);
 int mon_alarm(int argc, char **argv, struct hw_trapframe *hw_tf);
 int mon_msr(int argc, char **argv, struct hw_trapframe *hw_tf);
 int mon_db(int argc, char **argv, struct hw_trapframe *hw_tf);
+int mon_px(int argc, char **argv, struct hw_trapframe *hw_tf);
 
 #endif // !ROS_KERN_MONITOR_H
index 01619c4..3946e81 100644 (file)
@@ -74,20 +74,13 @@ static bool is_blacklisted(const char *s)
 }
 
 static int tab_depth = 0;
-static bool print = TRUE;
 
-/* Call these via kfunc */
+/* Call this via kfunc */
 void reset_print_func_depth(void)
 {
        tab_depth = 0;
 }
 
-void toggle_print_func(void)
-{
-       print = !print;
-       printk("Func entry/exit printing is now %sabled\n", print ? "en" : "dis");
-}
-
 static spinlock_t lock = SPINLOCK_INITIALIZER_IRQSAVE;
 
 static void __print_hdr(void)
@@ -110,7 +103,7 @@ void __print_func_entry(const char *func, const char *file)
 {
        char tentabs[] = "\t\t\t\t\t\t\t\t\t\t"; // ten tabs and a \0
        char *ourtabs = &tentabs[10 - MIN(tab_depth, 10)];
-       if (!print)
+       if (!printx_on)
                return;
        if (is_blacklisted(func))
                return;
@@ -125,7 +118,7 @@ void __print_func_exit(const char *func, const char *file)
 {
        char tentabs[] = "\t\t\t\t\t\t\t\t\t\t"; // ten tabs and a \0
        char *ourtabs;
-       if (!print)
+       if (!printx_on)
                return;
        if (is_blacklisted(func))
                return;
@@ -136,3 +129,20 @@ void __print_func_exit(const char *func, const char *file)
        printk("%s---- %s()\n", ourtabs, func);
        spin_unlock_irqsave(&lock);
 }
+
+bool printx_on = FALSE;
+
+void set_printx(int mode)
+{
+       switch (mode) {
+               case 0:
+                       printx_on = FALSE;
+                       break;
+               case 1:
+                       printx_on = TRUE;
+                       break;
+               case 2:
+                       printx_on = !printx_on;
+                       break;
+       }
+}
index 61ddceb..9265375 100644 (file)
@@ -70,6 +70,7 @@ static command_t (RO commands)[] = {
        { "alarm", "Alarm Diagnostics", mon_alarm},
        { "msr", "read/write msr: msr msr [value]", mon_msr},
        { "db", "Misc debugging", mon_db},
+       { "px", "Toggle printx", mon_px},
 };
 #define NCOMMANDS (sizeof(commands)/sizeof(commands[0]))
 
@@ -1167,3 +1168,10 @@ int mon_db(int argc, char **argv, struct hw_trapframe *hw_tf)
        }
        return 0;
 }
+
+int mon_px(int argc, char **argv, struct hw_trapframe *hw_tf)
+{
+       set_printx(2);
+       printk("Printxing is now %sabled\n", printx_on ? "en" : "dis");
+       return 0;
+}