diff options
| author | Sergey Senozhatsky <sergey.senozhatsky@mail.by> | 2009-08-27 09:29:18 -0400 |
|---|---|---|
| committer | Catalin Marinas <catalin.marinas@arm.com> | 2009-08-27 09:29:18 -0400 |
| commit | 0494e08281d08f0a3dc442eb5e5cecc125b53b27 (patch) | |
| tree | 2050fee8744a101a25b84a45dc8abf4966ca00b6 | |
| parent | 008139d9146f9afee0e58df4b7422d0c9921f8ce (diff) | |
kmemleak: Printing of the objects hex dump
Introducing printing of the objects hex dump to the seq file.
The number of lines to be printed is limited to HEX_MAX_LINES
to prevent seq file spamming. The actual number of printed
bytes is less than or equal to (HEX_MAX_LINES * HEX_ROW_SIZE).
(slight adjustments by Catalin Marinas)
Signed-off-by: Sergey Senozhatsky <sergey.senozhatsky@mail.by>
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
| -rw-r--r-- | mm/kmemleak.c | 39 |
1 files changed, 39 insertions, 0 deletions
diff --git a/mm/kmemleak.c b/mm/kmemleak.c index 8172154502a6..1d7645b0a97c 100644 --- a/mm/kmemleak.c +++ b/mm/kmemleak.c | |||
| @@ -162,6 +162,15 @@ struct kmemleak_object { | |||
| 162 | /* flag set on newly allocated objects */ | 162 | /* flag set on newly allocated objects */ |
| 163 | #define OBJECT_NEW (1 << 3) | 163 | #define OBJECT_NEW (1 << 3) |
| 164 | 164 | ||
| 165 | /* number of bytes to print per line; must be 16 or 32 */ | ||
| 166 | #define HEX_ROW_SIZE 16 | ||
| 167 | /* number of bytes to print at a time (1, 2, 4, 8) */ | ||
| 168 | #define HEX_GROUP_SIZE 1 | ||
| 169 | /* include ASCII after the hex output */ | ||
| 170 | #define HEX_ASCII 1 | ||
| 171 | /* max number of lines to be printed */ | ||
| 172 | #define HEX_MAX_LINES 2 | ||
| 173 | |||
| 165 | /* the list of all allocated objects */ | 174 | /* the list of all allocated objects */ |
| 166 | static LIST_HEAD(object_list); | 175 | static LIST_HEAD(object_list); |
| 167 | /* the list of gray-colored objects (see color_gray comment below) */ | 176 | /* the list of gray-colored objects (see color_gray comment below) */ |
| @@ -259,6 +268,35 @@ static void kmemleak_disable(void); | |||
| 259 | } while (0) | 268 | } while (0) |
| 260 | 269 | ||
| 261 | /* | 270 | /* |
| 271 | * Printing of the objects hex dump to the seq file. The number of lines to be | ||
| 272 | * printed is limited to HEX_MAX_LINES to prevent seq file spamming. The | ||
| 273 | * actual number of printed bytes depends on HEX_ROW_SIZE. It must be called | ||
| 274 | * with the object->lock held. | ||
| 275 | */ | ||
| 276 | static void hex_dump_object(struct seq_file *seq, | ||
| 277 | struct kmemleak_object *object) | ||
| 278 | { | ||
| 279 | const u8 *ptr = (const u8 *)object->pointer; | ||
| 280 | int i, len, remaining; | ||
| 281 | unsigned char linebuf[HEX_ROW_SIZE * 5]; | ||
| 282 | |||
| 283 | /* limit the number of lines to HEX_MAX_LINES */ | ||
| 284 | remaining = len = | ||
| 285 | min(object->size, (size_t)(HEX_MAX_LINES * HEX_ROW_SIZE)); | ||
| 286 | |||
| 287 | seq_printf(seq, " hex dump (first %d bytes):\n", len); | ||
| 288 | for (i = 0; i < len; i += HEX_ROW_SIZE) { | ||
| 289 | int linelen = min(remaining, HEX_ROW_SIZE); | ||
| 290 | |||
| 291 | remaining -= HEX_ROW_SIZE; | ||
| 292 | hex_dump_to_buffer(ptr + i, linelen, HEX_ROW_SIZE, | ||
| 293 | HEX_GROUP_SIZE, linebuf, sizeof(linebuf), | ||
| 294 | HEX_ASCII); | ||
| 295 | seq_printf(seq, " %s\n", linebuf); | ||
| 296 | } | ||
| 297 | } | ||
| 298 | |||
| 299 | /* | ||
| 262 | * Object colors, encoded with count and min_count: | 300 | * Object colors, encoded with count and min_count: |
| 263 | * - white - orphan object, not enough references to it (count < min_count) | 301 | * - white - orphan object, not enough references to it (count < min_count) |
| 264 | * - gray - not orphan, not marked as false positive (min_count == 0) or | 302 | * - gray - not orphan, not marked as false positive (min_count == 0) or |
| @@ -308,6 +346,7 @@ static void print_unreferenced(struct seq_file *seq, | |||
| 308 | object->pointer, object->size); | 346 | object->pointer, object->size); |
| 309 | seq_printf(seq, " comm \"%s\", pid %d, jiffies %lu\n", | 347 | seq_printf(seq, " comm \"%s\", pid %d, jiffies %lu\n", |
| 310 | object->comm, object->pid, object->jiffies); | 348 | object->comm, object->pid, object->jiffies); |
| 349 | hex_dump_object(seq, object); | ||
| 311 | seq_printf(seq, " backtrace:\n"); | 350 | seq_printf(seq, " backtrace:\n"); |
| 312 | 351 | ||
| 313 | for (i = 0; i < object->trace_len; i++) { | 352 | for (i = 0; i < object->trace_len; i++) { |
