kmemleak hexdump proposal

Sergey Senozhatsky
2009-06-28T17:35:28+00:00

Hello.
What do you think about ability to 'watch' leaked region? (hex + ascii).
(done via lib/hexdump.c)

To turn on hex dump:
echo "hexdump=on" > /sys/kernel/debug/kmemleak

/**
Or (as alternative):
echo "hexdump=f6aac7f8" > /sys/kernel/debug/kmemleak
where f6aac7f8 - object's pointer.
**/

cat /sys/kernel/debug/kmemleak

unreferenced object 0xf6aac7f8 (size 32):
  comm "swapper", pid 1, jiffies 4294877610
HEX dump:
70 6e 70 20 30 30 3a 30 61 00 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a a5  pnp 00:0a.ZZZZZZZZZZZZZZZZZZZZZ.

  backtrace:
    [<c10e92eb>] kmemleak-alloc+0x11b/0x2b0
    [<c10e4b91>] kmem-cache-alloc+0x111/0x1c0
    [<c12c424e>] reserve-range+0x3e/0x1b0
    [<c12c4454>] system-pnp-probe+0x94/0x140
    [<c12baf84>] pnp-device-probe+0x84/0x100
    [<c12f1919>] driver-probe-device+0x89/0x170
    [<c12f1a99>]     [<c100115f>] do-one-initcall+0x3f/0x1a0
    [<c15aa4af>] kernel-init+0x13e/0x1a6
    [<c1003e07>] kernel-thread-helper+0x7/0x10
unreferenced object 0xf63f4d18 (size 192):
  comm "swapper", pid 1, jiffies 4294878292
HEX dump:
3c 06 00 00 00 00 00 00 78 69 00 00 00 00 00 00 0a 00 00 00 00 00 00 00 0a 00 00 00 00 00 00 00  <.......xi......................
25 0c 00 00 00 00 00 00 25 0c 00 00 00 00 00 00 32 05 00 00 00 00 00 00 60 54 00 00 00 00 00 00  %.......%.......2.......`T......
0a 00 00 00 00 00 00 00 0a 00 00 00 00 00 00 00 1f 0a 00 00 00 00 00 00 1f 0a 00 00 00 00 00 00  ................................
28 04 00 00 00 00 00 00 48 3f 00 00 00 00 00 00 0a 00 00 00 00 00 00 00 0a 00 00 00 00 00 00 00  (.......H?......................
19 08 00 00 00 00 00 00 19 08 00 00 00 00 00 00 1e 03 00 00 00 00 00 00 30 2a 00 00 00 00 00 00  ........................0*......
0a 00 00 00 00 00 00 00 0a 00 00 00 00 00 00 00 13 06 00 00 00 00 00 00 13 06 00 00 00 00 00 00  ................................

  backtrace:
    [<c10e92eb>] kmemleak-alloc+0x11b/0x2b0
    [<c10e584d>]     [<c100115f>] do-one-initcall+0x3f/0x1a0
    [<c15aa4af>] kernel-init+0x13e/0x1a6
    [<c1003e07>] kernel-thread-helper+0x7/0x10
    [<ffffffff>] 0xffffffff

To disable hex dump:
echo "hexdump=off" > /sys/kernel/debug/kmemleak

I guess it could safe someone's time.
(May be, showed examples aren't so good. Just to demonstrate the idea.)

(concept. feel free to ask for comments.)

diff -u -p

+#define HEX-ROW-SIZE 32
+/* number of bytes to print at a time (1, 2, 4, 8) */
+#define HEX-GROUP-SIZE 1
+/* include ASCII after the hex output */ 
+#define HEX-ASCII 1
+
 /* the list of all allocated objects */
 static LIST-HEAD(object-list);
 /* the list of gray-colored objects (see color-gray comment below) */
@@ -182,6 +189,9 @@ static atomic-t kmemleak-early-log = ATO
 /* set if a fata kmemleak error has occurred */
 static atomic-t kmemleak-error = ATOMIC-INIT(0);
 
+/* set if HEX dump should be printed */
+static atomic-t kmemleak-hex-dump = ATOMIC-INIT(0);
+
 /* minimum and maximum address that may be valid pointers */
 static unsigned long min-addr = ULONG-MAX;
 static unsigned long max-addr;
@@ -290,6 +300,29 @@ static int unreferenced-object(struct km
 			       jiffies-last-scan);
 }
 
+
+static void object-hex-dump(struct seq-file *seq, struct kmemleak-object *object)
+{
+	const u8 *ptr = (const u8*)object->pointer;
+	int len = object->size;
+	int i, linelen, remaining = object->size;
+	unsigned char linebuf[200];
+	
+	seq-printf(seq, "HEX dump:n");
+	
+	for (i = 0; i < len; i += HEX-ROW-SIZE) {
+		linelen = min(remaining, HEX-ROW-SIZE);
+		remaining -= HEX-ROW-SIZE;
+		hex-dump-to-buffer(ptr + i, linelen, HEX-ROW-SIZE, HEX-GROUP-SIZE,
+				linebuf, sizeof(linebuf), HEX-ASCII);
+
+		seq-printf(seq, "%sn", linebuf);	
+	}
+	
+	seq-printf(seq, "n");
+}
+
+
 /*
  * Printing of the unreferenced objects information to the seq file. The
  * print-unreferenced function must be called with the object->lock held.
@@ -301,10 +334,17 @@ static void print-unreferenced(struct se
 
 	seq-printf(seq, "unreferenced object 0x%08lx (size %zu):n",
 		   object->pointer, object->size);
+
 	seq-printf(seq, "  comm "%s", pid %d, jiffies %lun",
 		   object->comm, object->pid, object->jiffies);
-	seq-printf(seq, "  backtrace:n");
 
+	/* check whether hex dump should be printed*/
+	if (atomic-read(&kmemleak-hex-dump))
+		object-hex-dump(seq, object);
+	
+	
+	seq-printf(seq, "  backtrace:n");
+	
 	for (i = 0; i < object->trace-len; i++) {
 		void *ptr = (void *)object->trace[i];
 		seq-printf(seq, "    [<%p>] %pSn", ptr, ptr);
@@ -1269,6 +1309,12 @@ static ssize-t kmemleak-write(struct fil
 		start-scan-thread();
 	else if (strncmp(buf, "scan=off", 8) == 0)
 		stop-scan-thread();
+	else if (strncmp(buf, "hexdump=on", 10) == 0) {
+		atomic-set(&kmemleak-hex-dump, 1);
+	}
+	else if (strncmp(buf, "hexdump=off", 11) == 0) {
+		atomic-set(&kmemleak-hex-dump, 0);
+	}
 	else if (strncmp(buf, "scan=", 5) == 0) {
 		unsigned long secs;
 		int err;


	Sergey

Re: kmemleak hexdump proposal by Pekka Enberg on 2009-06-29T09:43:32+00:00
Hi Sergey,

On Sun, Jun 28, 2009 at 8:36 PM, Sergey
Senozhatsky<sergey.senozhatsky@mail.by> wrote:
> What do you think about ability to 'watch' leaked region? (hex + ascii).
> (done via lib/hexdump.c)

What's your use case for this? I'm usually more interested in the
stack trace when there's a memory leak.

                        Pekka

Re: kmemleak hexdump proposal by Catalin Marinas on 2009-06-29T09:49:43+00:00
On Mon, 2009-06-29 at 12:43 +0300, Pekka Enberg wrote:
> On Sun, Jun 28, 2009 at 8:36 PM, Sergey
> Senozhatsky<sergey.senozhatsky@mail.by> wrote:
> > What do you think about ability to 'watch' leaked region? (hex + ascii).
> > (done via lib/hexdump.c)
> 
> What's your use case for this? I'm usually more interested in the
> stack trace when there's a memory leak.

I once had a need for such feature when investigating a memory leak (it
was more like debugging kmemleak) but a script combining dd, od
and /dev/kmem did the trick (I also work in an embedded world where I
have a halting debugger connected most of the times).


Re: kmemleak hexdump proposal by Sergey Senozhatsky on 2009-06-29T10:17:56+00:00
On (06/29/09 12:43), Pekka Enberg wrote:
> Hi Sergey,
> 
> On Sun, Jun 28, 2009 at 8:36 PM, Sergey
> Senozhatsky<sergey.senozhatsky@mail.by> wrote:
> > What do you think about ability to 'watch' leaked region? (hex + ascii).
> > (done via lib/hexdump.c)
> 
> What's your use case for this? I'm usually more interested in the
> stack trace when there's a memory leak.
> 
>                         Pekka
> 

Hello Pekka,
Well, it's not easy to come up with something strong. 
I agree, that stack gives you almost all you need.

HEX dump can give you a -tip- in case you're not sure. 

for example:
unreferenced object 0xf6aac7f8 (size 32):
  comm "swapper", pid 1, jiffies 4294877610
HEX dump:
70 6e 70 20 30 30 3a 30 61 00 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a a5  pnp 00:0a.ZZZZZZZZZZZZZZZZZZZZZ.

  backtrace:
    [<c10e92eb>] kmemleak-alloc+0x11b/0x2b0
    [<c10e4b91>] kmem-cache-alloc+0x111/0x1c0
    [<c12c424e>] reserve-range+0x3e/0x1b0
    [<c12c4454>] system-pnp-probe+0x94/0x140
    [<c12baf84>] pnp-device-probe+0x84/0x100
    [<c12f1919>] driver-probe-device+0x89/0x170
    [<c12f1a99>]     [<c100115f>] do-one-initcall+0x3f/0x1a0
    [<c15aa4af>] kernel-init+0x13e/0x1a6
    [<c1003e07>] kernel-thread-helper+0x7/0x10

- Ah, pnp 00:0a. Got it.
or
- Ah, pnp 00:0a. No.. It's false. (EXAMPLE)

Or something like that :-)

	Sergey

Re: kmemleak hexdump proposal by Pekka Enberg on 2009-06-29T10:19:54+00:00
Hi Sergey,

On Mon, 2009-06-29 at 13:19 +0300, Sergey Senozhatsky wrote:
> Well, it's not easy to come up with something strong. 
> I agree, that stack gives you almost all you need.
> 
> HEX dump can give you a -tip- in case you're not sure. 

Don't get me wrong, I'm not against it in any way. If Catalin is
interested in merging this kind of functionality, go for it! You might
want to consider unconditionally enabling the hexdump. If the
information is valuable, we should print it all the time.

			Pekka


Re: kmemleak hexdump proposal by Catalin Marinas on 2009-06-29T10:40:10+00:00
On Mon, 2009-06-29 at 13:19 +0300, Pekka Enberg wrote:
> On Mon, 2009-06-29 at 13:19 +0300, Sergey Senozhatsky wrote:
> > Well, it's not easy to come up with something strong. 
> > I agree, that stack gives you almost all you need.
> > 
> > HEX dump can give you a -tip- in case you're not sure. 
> 
> Don't get me wrong, I'm not against it in any way. If Catalin is
> interested in merging this kind of functionality, go for it! You might
> want to consider unconditionally enabling the hexdump. If the
> information is valuable, we should print it all the time.

Though I prefer to do as much as possible in user space, I think this
feature would be useful.

Anyway, I may not include it before the next merging window (when is
actually the best time for new features). Currently, my main focus is on
reducing the false positives.


Re: kmemleak hexdump proposal by Pekka Enberg on 2009-06-29T10:42:34+00:00
Hi Catalin,

On Mon, 2009-06-29 at 11:38 +0100, Catalin Marinas wrote:
> Anyway, I may not include it before the next merging window (when is
> actually the best time for new features). Currently, my main focus is on
> reducing the false positives.

Yes, this new feature shouldn't go into 2.6.31. That said, you -do- want
to include it in linux-next now if you're interested in pushing it to
2.6.32.

			Pekka


Re: kmemleak hexdump proposal by Sergey Senozhatsky on 2009-06-29T10:44:34+00:00
On (06/29/09 13:19), Pekka Enberg wrote:
> Hi Sergey,
> 
> On Mon, 2009-06-29 at 13:19 +0300, Sergey Senozhatsky wrote:
> > Well, it's not easy to come up with something strong. 
> > I agree, that stack gives you almost all you need.
> > 
> > HEX dump can give you a -tip- in case you're not sure. 
> 
> Don't get me wrong, I'm not against it in any way. 
I don't think so ;) -IF- even so - it's absolutely normal, to my mind.

> If Catalin is interested in merging this kind of 
> functionality, go for it! You might want to consider unconditionally
> enabling the hexdump. If the information is valuable, we should print
> it all the time.
I guess it's valuable enougth to print it, but not valuable enougth to print it all the time.
So, let me say - it's valuable enougth to print 'on demand', I guess. (I may be wrong).

BTW, printing it all the time we can spam kmemleak (in case there are objects sized 2K, 4K and so on).
That's why I wrote about hexdump=OBJECT-POINTER.

>
> 			Pekka
> 

	Sergey

Re: kmemleak hexdump proposal by Sergey Senozhatsky on 2009-06-29T10:51:29+00:00
On (06/29/09 11:38), Catalin Marinas wrote:
> On Mon, 2009-06-29 at 13:19 +0300, Pekka Enberg wrote:
> > On Mon, 2009-06-29 at 13:19 +0300, Sergey Senozhatsky wrote:
> > > Well, it's not easy to come up with something strong. 
> > > I agree, that stack gives you almost all you need.
> > > 
> > > HEX dump can give you a -tip- in case you're not sure. 
> > 
> > Don't get me wrong, I'm not against it in any way. If Catalin is
> > interested in merging this kind of functionality, go for it! You might
> > want to consider unconditionally enabling the hexdump. If the
> > information is valuable, we should print it all the time.
> 
> Though I prefer to do as much as possible in user space, 
Agreed. Good example is 'function filtering' ;)

> I think this feature would be useful.
> 
So, I'll continue my work. (given patch didn't even passed ./checkpatch.pl).
Ok?

> Anyway, I may not include it before the next merging window (when is
> actually the best time for new features). Currently, my main focus is on
> reducing the false positives.
Sure. No problems.

> 
> 	Sergey

Re: kmemleak hexdump proposal by Catalin Marinas on 2009-06-29T10:59:01+00:00
On Mon, 2009-06-29 at 13:45 +0300, Sergey Senozhatsky wrote:
> BTW, printing it all the time we can spam kmemleak (in case there are objects sized 2K, 4K and so on).
> That's why I wrote about hexdump=OBJECT-POINTER.

I'm more in favour of an on/off hexdump feature (maybe even permanently
on) and with a limit to the number of bytes it displays. For larger
blocks, the hexdump=OBJECT-POINTER is easily achievable in user space
via /dev/kmem.

My proposal is for an always on hexdump but with no more than 2-3 lines
of hex values. As Pekka said, I should get it into linux-next before the
next merging window.


Re: kmemleak hexdump proposal by Sergey Senozhatsky on 2009-06-29T11:06:49+00:00
On (06/29/09 11:58), Catalin Marinas wrote:
> On Mon, 2009-06-29 at 13:45 +0300, Sergey Senozhatsky wrote:
> > BTW, printing it all the time we can spam kmemleak (in case there are objects sized 2K, 4K and so on).
> > That's why I wrote about hexdump=OBJECT-POINTER.
> 
> I'm more in favour of an on/off hexdump feature (maybe even permanently
> on) and with a limit to the number of bytes it displays. For larger
> blocks, the hexdump=OBJECT-POINTER is easily achievable in user space
> via /dev/kmem.
> 
Yeah. Good point.

> My proposal is for an always on hexdump but with no more than 2-3 lines
> of hex values. 
I like it.

> As Pekka said, I should get it into linux-next before the
> next merging window.
I'll send new patch to you (today evening)/(tomorrow). 
Ok?

> 
> 	Sergey

Re: kmemleak hexdump proposal by Sergey Senozhatsky on 2009-06-29T20:08:56+00:00
Hello.
This is actually draft. We'll discuss details during next merge window (or earlier).

Thanks.
-Example (HEX-ROW-SIZE 16):

unreferenced object 0xf68b59b8 (size 32):
  comm "swapper", pid 1, jiffies 4294877610
  hex dump (first 32 bytes):
    70 6e 70 20 30 30 3a 30 31 00 5a 5a 5a 5a 5a 5a  pnp 00:01.ZZZZZZ
    5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a a5  ZZZZZZZZZZZZZZZ.
  backtrace:
    [<c10e931b>] kmemleak-alloc+0x11b/0x2b0
    [<c10e4bc1>] kmem-cache-alloc+0x111/0x1c0
    [<c12c426e>] reserve-range+0x3e/0x1b0
    [<c12c4474>] system-pnp-probe+0x94/0x140
    [<c12bafa4>] pnp-device-probe+0x84/0x100
    [<c12f1939>] driver-probe-device+0x89/0x170
    [<c12f1ab9>]     [<c100115f>] do-one-initcall+0x3f/0x1a0
    [<c15ac4af>] kernel-init+0x13e/0x1a6
    [<c1003e07>] kernel-thread-helper+0x7/0x10


Example (HEX-ROW-SIZE 32):

unreferenced object 0xf5e2e130 (size 2048):
  comm "modprobe", pid 2084, jiffies 4294880769
  hex dump (first 64 bytes):
    24 97 ff ff fc ff ff ff fc ff ff ff fc ff ff ff fc ff ff ff fc ff ff ff fc ff ff ff fc ff ff ff  $...............................
    fc ff ff ff fc ff ff ff fc ff ff ff fc ff ff ff fc ff ff ff fc ff ff ff fc ff ff ff fc ff ff ff  ................................
  backtrace:
    [<c10e931b>] kmemleak-alloc+0x11b/0x2b0
    [<c10e587d>]     [<fd61a25b>] loop-alloc+0x6b/0x170 [loop]
    [<fd61e092>] 0xfd61e092
    [<c100115f>] do-one-initcall+0x3f/0x1a0
    [<c10785ad>] sys-init-module+0xdd/0x220
    [<c100324b>] sysenter-do-call+0x12/0x22
    [<ffffffff>] 0xffffffff
unreferenced object 0xf5d3cd00 (size 32):
  comm "consolechars", pid 2433, jiffies 4294894598
  hex dump (first 32 bytes):
    60 15 58 c1 00 00 00 00 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a a5  `.X.....ZZZZZZZZZZZZZZZZZZZZZZZ.
  backtrace:
    [<c10e931b>] kmemleak-alloc+0x11b/0x2b0
    [<c10e4bc1>] kmem-cache-alloc+0x111/0x1c0
    [<c12cf49b>] tty-ldisc-try-get+0x2b/0x130
    [<c12cf7d7>] tty-ldisc-get+0x37/0x70
    [<c12cfa54>] tty-ldisc-reinit+0x34/0x70
    [<c12cfac5>] tty-ldisc-release+0x35/0x60
    [<c12ca1fe>] tty-release-dev+0x33e/0x500
    [<c12ca3e0>] tty-release+0x20/0x40
    [<c10ed61d>]     [<c1047622>] sys-exit-group+0x22/0x40


hexdump.c can print prefix:
case DUMP-PREFIX-ADDRESS:
    f6998df0: 3c 06 00 00 00 00 00 00 78 69 00 00 ....  <.......xi......................
case DUMP-PREFIX-OFFSET:
    00000000: 3c 06 00 00 00 00 00 00 78 69 00 00 ....  <.......xi......................
default:
    3c 06 00 00 00 00 00 00 78 69 00 00 00 00 00 ....  <.......xi......................

hex-dump-object(struct seq-file *seq, struct kmemleak-object *object)
can be extended to accept prefix flag either. Though I don't think it's so important. So, it prints without any prefix.



diff  
+/* number of bytes to print per line; must be 16 or 32 */
+#define HEX-ROW-SIZE		32
+/* number of bytes to print at a time (1, 2, 4, 8) */
+#define HEX-GROUP-SIZE		1
+/* include ASCII after the hex output */
+#define HEX-ASCII		1
+/* max number of lines to be printed */
+#define HEX-MAX-LINES		2
+
 /* the list of all allocated objects */
 static LIST-HEAD(object-list);
 /* the list of gray-colored objects (see color-gray comment below) */
@@ -181,6 +190,8 @@ static atomic-t kmemleak-initialized = ATOMIC-INIT(0);
 static atomic-t kmemleak-early-log = ATOMIC-INIT(1);
 /* set if a fata kmemleak error has occurred */
 static atomic-t kmemleak-error = ATOMIC-INIT(0);
+/* set if hex dump should be printed */
+static atomic-t kmemleak-hex-dump = ATOMIC-INIT(1);
 
 /* minimum and maximum address that may be valid pointers */
 static unsigned long min-addr = ULONG-MAX;
@@ -258,6 +269,35 @@ static void kmemleak-disable(void);
 	kmemleak-disable();		
 } while (0)
 
+
+/*
+ * Printing of the objects hex dump to the seq file. The number on lines
+ * to be printed is limited to HEX-MAX-LINES to prevent seq file spamming.
+ * The actual number of printed bytes depends on HEX-ROW-SIZE.
+ * It must be called with the object->lock held.
+ */
+static void hex-dump-object(struct seq-file *seq,
+				struct kmemleak-object *object)
+{
+	const u8 *ptr = (const u8 *)object->pointer;
+	/* Limit the number of lines to HEX-MAX-LINES. */
+	int len = min(object->size, (size-t)(HEX-MAX-LINES * HEX-ROW-SIZE));
+	int i, remaining = len;
+	unsigned char linebuf[200];
+
+	seq-printf(seq, "  hex dump (first %d bytes):
", len);
+
+	for (i = 0; i < len; i += HEX-ROW-SIZE) {
+		int linelen = min(remaining, HEX-ROW-SIZE);
+		remaining -= HEX-ROW-SIZE;
+		hex-dump-to-buffer(ptr + i, linelen, HEX-ROW-SIZE,
+						   HEX-GROUP-SIZE, linebuf,
+						   sizeof(linebuf), HEX-ASCII);
+
+		seq-printf(seq, "    %s
", linebuf);
+	}
+}
+
 /*
  * Object colors, encoded with count and min-count:
  * - white - orphan object, not enough references to it (count < min-count)
@@ -303,6 +343,11 @@ static void print-unreferenced(struct seq-file *seq,
 		   object->pointer, object->size);
 	seq-printf(seq, "  comm "%s", pid %d, jiffies %lu
",
 		   object->comm, object->pid, object->jiffies);
+
+	/* check whether hex dump should be printed */
+	if (atomic-read(&kmemleak-hex-dump))
+		hex-dump-object(seq, object);
+
 	seq-printf(seq, "  backtrace:
");
 
 	for (i = 0; i < object->trace-len; i++) {
@@ -1269,6 +1314,10 @@ static ssize-t kmemleak-write(struct file *file, const char +		atomic-set(&kmemleak-hex-dump, 0);
 	else if (strncmp(buf, "scan=", 5) == 0) {
 		unsigned long secs;
 		int err;


	Sergey
Loading


$ This page is proudly powered by www.pubbs.net, you can see more at kernel archive | Partners: Global Manufacturers