From 7ca9a8e21dc1ecb33195b6c9fdd207f203308636 Mon Sep 17 00:00:00 2001 From: HATAYAMA Daisuke Date: Thu, 4 Mar 2021 20:20:28 +0900 Subject: [PATCH 4/6] Add valgrind support for the crash's custom memory allocator This adds valgrind support for the crash's custom memory allocator using the way described in the following valgrind's Memcheck manual: https://www.valgrind.org/docs/manual/mc-manual.html#mc-manual.mempools This helps detecting various memory errors on the crash's custom memory allocator. To enable this feature, build crash command as: # make valgrind Then, run crash commnad using valgrind as: # valgrind ./crash vmlinux vmcore Signed-off-by: HATAYAMA Daisuke --- Makefile | 4 +++ README | 4 +++ configure.c | 27 ++++++++++++++++++--- help.c | 4 +++ tools.c | 70 ++++++++++++++++++++++++++++++++++++++++++++++++++++- 5 files changed, 104 insertions(+), 5 deletions(-) diff --git a/Makefile b/Makefile index b3c0d3a7f75b..31a3d3de0c07 100644 --- a/Makefile +++ b/Makefile @@ -333,6 +333,10 @@ snappy: make_configure @./configure -x snappy ${CONF_TARGET_FLAG} -w -b @make --no-print-directory gdb_merge +valgrind: make_configure + @./configure -x valgrind ${CONF_TARGET_FLAG} -w -b + @make --no-print-directory gdb_merge + main.o: ${GENERIC_HFILES} main.c ${CC} -c ${CRASH_CFLAGS} main.c ${WARNING_OPTIONS} ${WARNING_ERROR} diff --git a/README b/README index e2af9249caa2..d4a830985056 100644 --- a/README +++ b/README @@ -105,6 +105,10 @@ use either the LZO or snappy compression libraries. To build crash with either or both of those libraries, type "make lzo" or "make snappy". + crash supports valgrind Memcheck tool on the crash's custom memory allocator. + To build crash with this feature enabled, type "make valgrind" and then run + crash with valgrind as "valgrind crash vmlinux vmcore". + All of the alternate build commands above are "sticky" in that the special "make" targets only have to be entered one time; all subsequent builds will follow suit. diff --git a/configure.c b/configure.c index 7f6d19e0b87e..9480829ad2da 100644 --- a/configure.c +++ b/configure.c @@ -1704,18 +1704,22 @@ get_extra_flags(char *filename, char *initial) * a CFLAGS.extra file and an LDFLAGS.extra file. * For lzo: + * - enter -DLZO in the CFLAGS.extra file + * - enter -llzo2 in the LDFLAGS.extra file + * + * For snappy: * - enter -DSNAPPY in the CFLAGS.extra file * - enter -lsnappy in the LDFLAGS.extra file * - * For snappy: - * - enter -DLZO in the CFLAGS.extra file - * - enter -llzo2 in the LDFLAGS.extra file. + * For valgrind: + * - enter -DVALGRIND in the CFLAGS.extra file */ void add_extra_lib(char *option) { int lzo, add_DLZO, add_llzo2; int snappy, add_DSNAPPY, add_lsnappy; + int valgrind, add_DVALGRIND; char *cflags, *ldflags; FILE *fp_cflags, *fp_ldflags; char *mode; @@ -1723,6 +1727,7 @@ add_extra_lib(char *option) lzo = add_DLZO = add_llzo2 = 0; snappy = add_DSNAPPY = add_lsnappy = 0; + valgrind = add_DVALGRIND = 0; ldflags = get_extra_flags("LDFLAGS.extra", NULL); cflags = get_extra_flags("CFLAGS.extra", NULL); @@ -1743,12 +1748,24 @@ add_extra_lib(char *option) add_lsnappy++; } + if (strcmp(option, "valgrind") == 0) { + valgrind++; + if (!cflags || !strstr(cflags, "-DVALGRIND")) + add_DVALGRIND++; + } + if ((lzo || snappy) && file_exists("diskdump.o") && (unlink("diskdump.o") < 0)) { perror("diskdump.o"); return; } + if (valgrind && + file_exists("tools.o") && (unlink("tools.o") < 0)) { + perror("tools.o"); + return; + } + mode = file_exists("CFLAGS.extra") ? "r+" : "w+"; if ((fp_cflags = fopen("CFLAGS.extra", mode)) == NULL) { perror("CFLAGS.extra"); @@ -1762,13 +1779,15 @@ add_extra_lib(char *option) return; } - if (add_DLZO || add_DSNAPPY) { + if (add_DLZO || add_DSNAPPY || add_DVALGRIND) { while (fgets(inbuf, 512, fp_cflags)) ; if (add_DLZO) fputs("-DLZO\n", fp_cflags); if (add_DSNAPPY) fputs("-DSNAPPY\n", fp_cflags); + if (add_DVALGRIND) + fputs("-DVALGRIND\n", fp_cflags); } if (add_llzo2 || add_lsnappy) { diff --git a/help.c b/help.c index 85b334a0419e..531f50a7cd82 100644 --- a/help.c +++ b/help.c @@ -9387,6 +9387,10 @@ README_ENTER_DIRECTORY, " use either the LZO or snappy compression libraries. To build crash with", " either or both of those libraries, type \"make lzo\" or \"make snappy\".", "", +" crash supports valgrind Memcheck tool on the crash's custom memory allocator.", +" To build crash with this feature enabled, type \"make valgrind\" and then run", +" crash with valgrind as \"valgrind crash vmlinux vmcore\".", +"", " All of the alternate build commands above are \"sticky\" in that the", " special \"make\" targets only have to be entered one time; all subsequent", " builds will follow suit.", diff --git a/tools.c b/tools.c index 71bac6d0ee9a..e6978ae44ead 100644 --- a/tools.c +++ b/tools.c @@ -18,6 +18,11 @@ #include "defs.h" #include +#ifdef VALGRIND +#include +#include +#endif + static void print_number(struct number_option *, int, int); static long alloc_hq_entry(void); struct hq_entry; @@ -5679,8 +5684,21 @@ buf_init(void) bp->smallest = 0x7fffffff; bp->total = 0.0; -} +#ifdef VALGRIND + VALGRIND_MAKE_MEM_NOACCESS(&bp->buf_1K, sizeof(bp->buf_1K)); + VALGRIND_MAKE_MEM_NOACCESS(&bp->buf_2K, sizeof(bp->buf_2K)); + VALGRIND_MAKE_MEM_NOACCESS(&bp->buf_4K, sizeof(bp->buf_4K)); + VALGRIND_MAKE_MEM_NOACCESS(&bp->buf_8K, sizeof(bp->buf_8K)); + VALGRIND_MAKE_MEM_NOACCESS(&bp->buf_32K, sizeof(bp->buf_32K)); + + VALGRIND_CREATE_MEMPOOL(&bp->buf_1K, 0, 1); + VALGRIND_CREATE_MEMPOOL(&bp->buf_2K, 0, 1); + VALGRIND_CREATE_MEMPOOL(&bp->buf_4K, 0, 1); + VALGRIND_CREATE_MEMPOOL(&bp->buf_8K, 0, 1); + VALGRIND_CREATE_MEMPOOL(&bp->buf_32K, 0, 1); +#endif +} /* * Free up all buffers used by the last command. @@ -5707,6 +5725,26 @@ void free_all_bufs(void) if (bp->mallocs != bp->frees) error(WARNING, "malloc/free mismatch (%ld/%ld)\n", bp->mallocs, bp->frees); + +#ifdef VALGRIND + VALGRIND_DESTROY_MEMPOOL(&bp->buf_1K); + VALGRIND_DESTROY_MEMPOOL(&bp->buf_2K); + VALGRIND_DESTROY_MEMPOOL(&bp->buf_4K); + VALGRIND_DESTROY_MEMPOOL(&bp->buf_8K); + VALGRIND_DESTROY_MEMPOOL(&bp->buf_32K); + + VALGRIND_MAKE_MEM_NOACCESS(&bp->buf_1K, sizeof(bp->buf_1K)); + VALGRIND_MAKE_MEM_NOACCESS(&bp->buf_2K, sizeof(bp->buf_2K)); + VALGRIND_MAKE_MEM_NOACCESS(&bp->buf_4K, sizeof(bp->buf_4K)); + VALGRIND_MAKE_MEM_NOACCESS(&bp->buf_8K, sizeof(bp->buf_8K)); + VALGRIND_MAKE_MEM_NOACCESS(&bp->buf_32K, sizeof(bp->buf_32K)); + + VALGRIND_CREATE_MEMPOOL(&bp->buf_1K, 0, 1); + VALGRIND_CREATE_MEMPOOL(&bp->buf_2K, 0, 1); + VALGRIND_CREATE_MEMPOOL(&bp->buf_4K, 0, 1); + VALGRIND_CREATE_MEMPOOL(&bp->buf_8K, 0, 1); + VALGRIND_CREATE_MEMPOOL(&bp->buf_32K, 0, 1); +#endif } /* @@ -5731,6 +5769,9 @@ freebuf(char *addr) for (i = 0; i < NUMBER_1K_BUFS; i++) { if (addr == (char *)&bp->buf_1K[i]) { bp->buf_inuse[B1K] &= ~(1 << i); +#ifdef VALGRIND + VALGRIND_MEMPOOL_FREE(&bp->buf_1K, addr); +#endif return; } } @@ -5738,6 +5779,9 @@ freebuf(char *addr) for (i = 0; i < NUMBER_2K_BUFS; i++) { if (addr == (char *)&bp->buf_2K[i]) { bp->buf_inuse[B2K] &= ~(1 << i); +#ifdef VALGRIND + VALGRIND_MEMPOOL_FREE(&bp->buf_2K, addr); +#endif return; } } @@ -5745,6 +5789,9 @@ freebuf(char *addr) for (i = 0; i < NUMBER_4K_BUFS; i++) { if (addr == (char *)&bp->buf_4K[i]) { bp->buf_inuse[B4K] &= ~(1 << i); +#ifdef VALGRIND + VALGRIND_MEMPOOL_FREE(&bp->buf_4K, addr); +#endif return; } } @@ -5752,6 +5799,9 @@ freebuf(char *addr) for (i = 0; i < NUMBER_8K_BUFS; i++) { if (addr == (char *)&bp->buf_8K[i]) { bp->buf_inuse[B8K] &= ~(1 << i); +#ifdef VALGRIND + VALGRIND_MEMPOOL_FREE(&bp->buf_8K, addr); +#endif return; } } @@ -5759,6 +5809,9 @@ freebuf(char *addr) for (i = 0; i < NUMBER_32K_BUFS; i++) { if (addr == (char *)&bp->buf_32K[i]) { bp->buf_inuse[B32K] &= ~(1 << i); +#ifdef VALGRIND + VALGRIND_MEMPOOL_FREE(&bp->buf_32K, addr); +#endif return; } } @@ -5924,6 +5977,9 @@ getbuf(long reqsize) bp->buf_inuse[B1K] |= (1 << bdx); bp->buf_1K_maxuse = MAX(bp->buf_1K_maxuse, count_bits_int(bp->buf_inuse[B1K])); +#ifdef VALGRIND + VALGRIND_MEMPOOL_ALLOC(&bp->buf_1K, bufp, 1024); +#endif BZERO(bufp, 1024); return(bufp); } @@ -5938,6 +5994,9 @@ getbuf(long reqsize) bp->buf_inuse[B2K] |= (1 << bdx); bp->buf_2K_maxuse = MAX(bp->buf_2K_maxuse, count_bits_int(bp->buf_inuse[B2K])); +#ifdef VALGRIND + VALGRIND_MEMPOOL_ALLOC(&bp->buf_2K, bufp, 2048); +#endif BZERO(bufp, 2048); return(bufp); } @@ -5952,6 +6011,9 @@ getbuf(long reqsize) bp->buf_inuse[B4K] |= (1 << bdx); bp->buf_4K_maxuse = MAX(bp->buf_4K_maxuse, count_bits_int(bp->buf_inuse[B4K])); +#ifdef VALGRIND + VALGRIND_MEMPOOL_ALLOC(&bp->buf_4K, bufp, 4096); +#endif BZERO(bufp, 4096); return(bufp); } @@ -5966,6 +6028,9 @@ getbuf(long reqsize) bp->buf_inuse[B8K] |= (1 << bdx); bp->buf_8K_maxuse = MAX(bp->buf_8K_maxuse, count_bits_int(bp->buf_inuse[B8K])); +#ifdef VALGRIND + VALGRIND_MEMPOOL_ALLOC(&bp->buf_8K, bufp, 8192); +#endif BZERO(bufp, 8192); return(bufp); } @@ -5980,6 +6045,9 @@ getbuf(long reqsize) bp->buf_inuse[B32K] |= (1 << bdx); bp->buf_32K_maxuse = MAX(bp->buf_32K_maxuse, count_bits_int(bp->buf_inuse[B32K])); +#ifdef VALGRIND + VALGRIND_MEMPOOL_ALLOC(&bp->buf_32K, bufp, 32768); +#endif BZERO(bufp, 32768); return(bufp); } -- 2.29.2