From ad7fec49cf0c16167c51211f0d3433d1b6cf8bb4 Mon Sep 17 00:00:00 2001 From: Xiang Xiao Date: Tue, 20 Apr 2021 21:59:16 +0800 Subject: [PATCH 1/3] Rename loc_[v]dprintf to loc_[v]message append '\n' automatically if not yet and then remove '\n' or '\r\n' from caller Signed-off-by: Xiang Xiao Change-Id: I3403fca5dcb7f4c43e5aa38b32081c76077134ba --- append.c | 13 ++++++++++--- append.h | 4 ++-- error.c | 16 ++++++++-------- heap.c | 4 ++-- user_malloc.c | 8 ++++---- 5 files changed, 26 insertions(+), 19 deletions(-) diff --git a/append.c b/append.c index 815c68b..a5abe42 100644 --- a/append.c +++ b/append.c @@ -561,18 +561,18 @@ void loc_vfprintf(FILE *file, const char *format, va_list args) /* * Local implementation of dprintf so we can use %p and other non-standard formats. */ -void loc_dprintf(int fd, const char *format, ...) +void loc_message(int fd, const char *format, ...) { va_list args; va_start(args, format); - loc_vdprintf(fd, format, args); + loc_vmessage(fd, format, args); va_end(args); } /* * Local implementation of vdprintf so we can use %p and other non-standard formats. */ -void loc_vdprintf(int fd, const char *format, va_list args) +void loc_vmessage(int fd, const char *format, va_list args) { // these are simple messages so this limit is ok char buf[256]; @@ -580,5 +580,12 @@ void loc_vdprintf(int fd, const char *format, va_list args) limit = buf + sizeof(buf); buf_p = append_vformat(buf, limit, format, args); + if (buf_p != buf && *(buf_p - 1) != '\n') { + if (buf_p == limit) { + buf_p--; + } + *buf_p++ = '\n'; + } + (void)!write(fd, buf, buf_p - buf); } diff --git a/append.h b/append.h index 2ff5dc4..99ac340 100644 --- a/append.h +++ b/append.h @@ -130,13 +130,13 @@ void loc_vfprintf(FILE *file, const char *format, va_list args); * Local implementation of dprintf so we can use %p and other non-standard formats. */ extern -void loc_dprintf(int fd, const char *format, ...); +void loc_message(int fd, const char *format, ...); /* * Local implementation of vdprintf so we can use %p and other non-standard formats. */ extern -void loc_vdprintf(int fd, const char *format, va_list args); +void loc_vmessage(int fd, const char *format, va_list args); /*<<<<<<<<<< This is end of the auto-generated output from fillproto. */ diff --git a/error.c b/error.c index 7947927..5f3746a 100644 --- a/error.c +++ b/error.c @@ -218,8 +218,8 @@ static void build_logfile_path(char *buf, const int buf_len) if (buf_p >= bounds_p - 1) { /* NOTE: we can't use dmalloc_message of course so do it the hard way */ - loc_dprintf(STDERR, - "debug-malloc library: logfile path too large '%s'\r\n", + loc_message(STDERR, + "debug-malloc library: logfile path too large '%s'", dmalloc_logpath); } @@ -247,8 +247,8 @@ void _dmalloc_open_log(void) outfile_fd = open(log_path, O_WRONLY | O_CREAT | O_TRUNC, 0666); if (outfile_fd < 0) { /* NOTE: we can't use dmalloc_message of course so do it the hardway */ - loc_dprintf(STDERR, - "debug-malloc library: could not open '%s'\r\n", + loc_message(STDERR, + "debug-malloc library: could not open '%s'", log_path); /* disable log_path */ dmalloc_logpath = NULL; @@ -574,12 +574,12 @@ void _dmalloc_die(const int silent_b) } /* print a message that we are going down */ - loc_dprintf(STDERR, - "debug-malloc library: %s program, fatal error\r\n", + loc_message(STDERR, + "debug-malloc library: %s program, fatal error", stop_str); if (dmalloc_errno != DMALLOC_ERROR_NONE) { - loc_dprintf(STDERR, - " Error: %s (err %d)\r\n", + loc_message(STDERR, + " Error: %s (err %d)", dmalloc_strerror(dmalloc_errno), dmalloc_errno); } } diff --git a/heap.c b/heap.c index 209ae5a..42f2d6a 100644 --- a/heap.c +++ b/heap.c @@ -101,8 +101,8 @@ static void *heap_extend(const int incr) if (ret == SBRK_ERROR) { if (BIT_IS_SET(_dmalloc_flags, DMALLOC_DEBUG_CATCH_NULL)) { - loc_dprintf(STDERR, - "\r\ndmalloc: critical error: could not extend heap %u more bytes\r\n", incr); + loc_message(STDERR, + "dmalloc: critical error: could not extend heap %u more bytes", incr); _dmalloc_die(0); } dmalloc_errno = DMALLOC_ERROR_ALLOC_FAILED; diff --git a/user_malloc.c b/user_malloc.c index a88cc95..03d0876 100644 --- a/user_malloc.c +++ b/user_malloc.c @@ -768,8 +768,8 @@ DMALLOC_PNT dmalloc_malloc(const char *file, const int line, if (xalloc_b && new_p == NULL) { char desc[128]; - loc_dprintf(STDERR, - "Out of memory while allocating %d bytes from '%s'\n", + loc_message(STDERR, + "Out of memory while allocating %d bytes from '%s'", size, _dmalloc_chunk_desc_pnt(desc, sizeof(desc), file, line)); @@ -869,8 +869,8 @@ DMALLOC_PNT dmalloc_realloc(const char *file, const int line, if (xalloc_b && new_p == NULL) { char desc[128]; - loc_dprintf(STDERR, - "Out of memory while reallocating %d bytes from '%s'\n", + loc_message(STDERR, + "Out of memory while reallocating %d bytes from '%s'", new_size, _dmalloc_chunk_desc_pnt(desc, sizeof(desc), file, line)); _exit(1); From 52ce0a9ec917030bc935c0c0cf4a74b7ed404cd3 Mon Sep 17 00:00:00 2001 From: Xiang Xiao Date: Tue, 20 Apr 2021 22:50:10 +0800 Subject: [PATCH 2/3] Change all va_list type argument to va_list* to more compatible with AMD64 platform: https://stackoverflow.com/questions/8047362/is-gcc-mishandling-a-pointer-to-a-va-list-passed-to-a-function Signed-off-by: Xiang Xiao Change-Id: Id711591dece832bd3941e91ae23e272905b72a8e --- append.c | 46 +++++++++++++++++++++++----------------------- append.h | 8 ++++---- error.c | 2 +- error.h | 2 +- user_malloc.c | 4 ++-- user_malloc.h | 2 +- 6 files changed, 32 insertions(+), 32 deletions(-) diff --git a/append.c b/append.c index a5abe42..6a992a2 100644 --- a/append.c +++ b/append.c @@ -261,7 +261,7 @@ char *append_pointer(char *dest, char *limit, PNT_ARITH_TYPE value, int base) * characters added will be returned. No \0 character will be added. */ char *append_vformat(char *dest, char *limit, const char *format, - va_list args) + va_list *args) { const char *format_p = format; char value_buf[64]; @@ -309,9 +309,9 @@ char *append_vformat(char *dest, char *limit, const char *format, trunc = 1; } else if (ch == '*') { if (trunc) { - trunc_len = va_arg(args, int); + trunc_len = va_arg(*args, int); } else { - width_len = va_arg(args, int); + width_len = va_arg(*args, int); } } else if (ch >= '0' && ch <= '9') { if (trunc) { @@ -338,20 +338,20 @@ char *append_vformat(char *dest, char *limit, const char *format, const char *value; if (ch == 'c') { - value_buf[0] = (char)va_arg(args, int); + value_buf[0] = (char)va_arg(*args, int); value_buf[1] = '\0'; value = value_buf; } else if (ch == 'd') { long num; if (long_arg) { - num = va_arg(args, long); + num = va_arg(*args, long); } else { - num = va_arg(args, int); + num = va_arg(*args, int); } handle_decimal(value_buf, value_limit, num, 10); value = value_buf; } else if (ch == 'f') { - double num = va_arg(args, double); + double num = va_arg(*args, double); if (trunc_len < 0) { handle_float(value_buf, value_limit, num, DEFAULT_DECIMAL_PRECISION, 1); } else { @@ -363,9 +363,9 @@ char *append_vformat(char *dest, char *limit, const char *format, } else if (ch == 'o') { long num; if (long_arg) { - num = va_arg(args, long); + num = va_arg(*args, long); } else { - num = va_arg(args, int); + num = va_arg(*args, int); } handle_decimal(value_buf, value_limit, num, 8); value = value_buf; @@ -374,7 +374,7 @@ char *append_vformat(char *dest, char *limit, const char *format, prefix_len = 1; } } else if (ch == 'p') { - DMALLOC_PNT pnt = va_arg(args, DMALLOC_PNT); + DMALLOC_PNT pnt = va_arg(*args, DMALLOC_PNT); PNT_ARITH_TYPE num = (PNT_ARITH_TYPE)pnt; handle_pointer(value_buf, value_limit, num, 16); value = value_buf; @@ -382,13 +382,13 @@ char *append_vformat(char *dest, char *limit, const char *format, prefix = "0x"; prefix_len = 2; } else if (ch == 's') { - value = va_arg(args, char *); + value = va_arg(*args, char *); } else if (ch == 'u') { unsigned long num; if (long_arg) { - num = va_arg(args, unsigned long); + num = va_arg(*args, unsigned long); } else { - num = va_arg(args, unsigned int); + num = va_arg(*args, unsigned int); } char *value_buf_p = value_buf; value_buf_p = append_ulong(value_buf_p, value_limit, num, 10); @@ -397,9 +397,9 @@ char *append_vformat(char *dest, char *limit, const char *format, } else if (ch == 'x') { long num; if (long_arg) { - num = va_arg(args, long); + num = va_arg(*args, long); } else { - num = va_arg(args, int); + num = va_arg(*args, int); } handle_decimal(value_buf, value_limit, num, 16); if (format_prefix) { @@ -469,7 +469,7 @@ char *append_format(char *dest, char *limit, const char *format, ...) char *dest_p; va_start(args, format); - dest_p = append_vformat(dest, limit, format, args); + dest_p = append_vformat(dest, limit, format, &args); va_end(args); return dest_p; @@ -496,7 +496,7 @@ char *append_null(char *dest, char *limit) * causing the library to go recursive. */ int loc_vsnprintf(char *buf, const int size, const char *format, - va_list args) + va_list *args) { char *limit, *buf_p; limit = buf + size; @@ -516,7 +516,7 @@ int loc_snprintf(char *buf, const int size, const char *format, ...) int len; va_start(args, format); - len = loc_vsnprintf(buf, size, format, args); + len = loc_vsnprintf(buf, size, format, &args); va_end(args); return len; @@ -529,7 +529,7 @@ void loc_printf(const char *format, ...) { va_list args; va_start(args, format); - loc_vfprintf(stdout, format, args); + loc_vfprintf(stdout, format, &args); va_end(args); } @@ -540,14 +540,14 @@ void loc_fprintf(FILE *file, const char *format, ...) { va_list args; va_start(args, format); - loc_vfprintf(file, format, args); + loc_vfprintf(file, format, &args); va_end(args); } /* * Local implementation of vfprintf so we can use %p and other non-standard formats. */ -void loc_vfprintf(FILE *file, const char *format, va_list args) +void loc_vfprintf(FILE *file, const char *format, va_list *args) { // these are simple messages so this limit is ok char buf[256]; @@ -565,14 +565,14 @@ void loc_message(int fd, const char *format, ...) { va_list args; va_start(args, format); - loc_vmessage(fd, format, args); + loc_vmessage(fd, format, &args); va_end(args); } /* * Local implementation of vdprintf so we can use %p and other non-standard formats. */ -void loc_vmessage(int fd, const char *format, va_list args) +void loc_vmessage(int fd, const char *format, va_list *args) { // these are simple messages so this limit is ok char buf[256]; diff --git a/append.h b/append.h index 99ac340..b277def 100644 --- a/append.h +++ b/append.h @@ -74,7 +74,7 @@ char *append_pointer(char *dest, char *limit, PNT_ARITH_TYPE value, int base); */ extern char *append_vformat(char *dest, char *limit, const char *format, - va_list args); + va_list *args); /* * Append a varargs format to destination. Pointer to the end of the @@ -98,7 +98,7 @@ char *append_null(char *dest, char *limit); */ extern int loc_vsnprintf(char *buf, const int size, const char *format, - va_list args); + va_list *args); /* * Local implementation of snprintf. We are doing this trying to not @@ -124,7 +124,7 @@ void loc_fprintf(FILE *file, const char *format, ...); * Local implementation of vfprintf so we can use %p and other non-standard formats. */ extern -void loc_vfprintf(FILE *file, const char *format, va_list args); +void loc_vfprintf(FILE *file, const char *format, va_list *args); /* * Local implementation of dprintf so we can use %p and other non-standard formats. @@ -136,7 +136,7 @@ void loc_message(int fd, const char *format, ...); * Local implementation of vdprintf so we can use %p and other non-standard formats. */ extern -void loc_vmessage(int fd, const char *format, va_list args); +void loc_vmessage(int fd, const char *format, va_list *args); /*<<<<<<<<<< This is end of the auto-generated output from fillproto. */ diff --git a/error.c b/error.c index 5f3746a..58008d0 100644 --- a/error.c +++ b/error.c @@ -435,7 +435,7 @@ char *_dmalloc_ptime(const TIME_TYPE *time_p, char *buf, const int buf_size, * * args -> Already converted pointer to a stdarg list. */ -void _dmalloc_vmessage(const char *format, va_list args) +void _dmalloc_vmessage(const char *format, va_list *args) { char *str_p, *bounds_p; int len; diff --git a/error.h b/error.h index 96f4ac4..2f15e8f 100644 --- a/error.h +++ b/error.h @@ -164,7 +164,7 @@ char *_dmalloc_ptime(const TIME_TYPE *time_p, char *buf, const int buf_size, * args -> Already converted pointer to a stdarg list. */ extern -void _dmalloc_vmessage(const char *format, va_list args); +void _dmalloc_vmessage(const char *format, va_list *args); /* * void _dmalloc_die diff --git a/user_malloc.c b/user_malloc.c index 03d0876..7b236cb 100644 --- a/user_malloc.c +++ b/user_malloc.c @@ -1824,7 +1824,7 @@ void dmalloc_log_changed(const unsigned long mark, const int not_freed_b, * * args -> Already converted pointer to a stdarg list. */ -void dmalloc_vmessage(const char *format, va_list args) +void dmalloc_vmessage(const char *format, va_list *args) { _dmalloc_vmessage(format, args); } @@ -1847,7 +1847,7 @@ void dmalloc_message(const char *format, ...) va_list args; va_start(args, format); - _dmalloc_vmessage(format, args); + _dmalloc_vmessage(format, &args); va_end(args); } diff --git a/user_malloc.h b/user_malloc.h index 1ffbecc..abfc99f 100644 --- a/user_malloc.h +++ b/user_malloc.h @@ -643,7 +643,7 @@ void dmalloc_log_changed(const unsigned long mark, const int not_freed_b, * args -> Already converted pointer to a stdarg list. */ extern -void dmalloc_vmessage(const char *format, va_list args); +void dmalloc_vmessage(const char *format, va_list *args); /* * void dmalloc_message From 6f4d29da098e985ab284b837eb5e45009f1b45e8 Mon Sep 17 00:00:00 2001 From: Xiang Xiao Date: Tue, 20 Apr 2021 23:49:54 +0800 Subject: [PATCH 3/3] Add %pV format support so message_str can be removed to save 1KB memory. Note: the idea come from printk: https://www.kernel.org/doc/html/latest/core-api/printk-formats.html Signed-off-by: Xiang Xiao Change-Id: Ie8bced627e5269a805ef3798862c0b50fcce6b20 --- append.c | 9 +++++++-- append.h | 5 +++++ error.c | 36 +++++++++++++----------------------- 3 files changed, 25 insertions(+), 25 deletions(-) diff --git a/append.c b/append.c index 6a992a2..929eb1c 100644 --- a/append.c +++ b/append.c @@ -375,8 +375,13 @@ char *append_vformat(char *dest, char *limit, const char *format, } } else if (ch == 'p') { DMALLOC_PNT pnt = va_arg(*args, DMALLOC_PNT); - PNT_ARITH_TYPE num = (PNT_ARITH_TYPE)pnt; - handle_pointer(value_buf, value_limit, num, 16); + if (*format_p == 'V') { + struct va_format *vaf = (struct va_format *)pnt; + dest_p = append_vformat(dest_p, limit, vaf->fmt, vaf->va); + format_p++; + break; + } + handle_pointer(value_buf, value_limit, (PNT_ARITH_TYPE)pnt, 16); value = value_buf; // because %#p throws a gcc warning, I've decreed that %p has a 0x hex prefix prefix = "0x"; diff --git a/append.h b/append.h index b277def..26565b1 100644 --- a/append.h +++ b/append.h @@ -33,6 +33,11 @@ /*<<<<<<<<<< The below prototypes are auto-generated by fillproto */ +struct va_format { + const char *fmt; + va_list *va; +}; + /* * Append string argument to destination up to limit pointer. Pointer * to the end of the characters added will be returned. No \0 diff --git a/error.c b/error.c index 58008d0..426329a 100644 --- a/error.c +++ b/error.c @@ -127,8 +127,6 @@ int _dmalloc_aborting_b = 0; /* local variables */ static int outfile_fd = -1; /* output file descriptor */ -/* the following are here to reduce stack overhead */ -static char message_str[1024]; /* message string buffer */ /* * void _dmalloc_open_log @@ -437,11 +435,13 @@ char *_dmalloc_ptime(const TIME_TYPE *time_p, char *buf, const int buf_size, */ void _dmalloc_vmessage(const char *format, va_list *args) { - char *str_p, *bounds_p; - int len; + char *str_p, *bounds_p; + char buf[64]; + int len; + struct va_format vaf; - str_p = message_str; - bounds_p = str_p + sizeof(message_str); + str_p = buf; + bounds_p = str_p + sizeof(buf); /* no logpath and no print then no workie */ if (dmalloc_logpath == NULL @@ -525,30 +525,20 @@ void _dmalloc_vmessage(const char *format, va_list *args) * specifications if necessary. */ - /* write the format + info into str */ - char *start_p = str_p; - str_p = append_vformat(str_p, bounds_p, format, args); - - /* was it an empty format? */ - if (str_p == start_p) { - return; - } - - /* tack on a '\n' if necessary */ - if (*(str_p - 1) != '\n') { - *str_p++ = '\n'; - *str_p = '\0'; - } - len = str_p - message_str; + /* write the format + info into file */ + append_null(str_p, bounds_p); + + vaf.fmt = format; + vaf.va = args; /* do we need to write the message to the logfile */ if (dmalloc_logpath != NULL) { - (void)write(outfile_fd, message_str, len); + loc_message(outfile_fd, "%s%pV", buf, &vaf); } /* do we need to print the message? */ if (BIT_IS_SET(_dmalloc_flags, DMALLOC_DEBUG_PRINT_MESSAGES)) { - (void)write(STDERR, message_str, len); + loc_message(STDERR, "%s%pV", buf, &vaf); } }