Skip to content

Commit

Permalink
libbb: reduce the overhead of single parameter bb_error_msg() calls
Browse files Browse the repository at this point in the history
Back in 2007, commit 0c97c9d ("'simple' error message functions by
Loic Grenie") introduced bb_simple_perror_msg() to allow for a lower
overhead call to bb_perror_msg() when only a string was being printed
with no parameters. This saves space for some CPU architectures because
it avoids the overhead of a call to a variadic function. However there
has never been a simple version of bb_error_msg(), and since 2007 many
new calls to bb_perror_msg() have been added that only take a single
parameter and so could have been using bb_simple_perror_message().

This changeset introduces 'simple' versions of bb_info_msg(),
bb_error_msg(), bb_error_msg_and_die(), bb_herror_msg() and
bb_herror_msg_and_die(), and replaces all calls that only take a
single parameter, or use something like ("%s", arg), with calls to the
corresponding 'simple' version.

Since it is likely that single parameter calls to the variadic functions
may be accidentally reintroduced in the future a new debugging config
option WARN_SIMPLE_MSG has been introduced. This uses some macro magic
which will cause any such calls to generate a warning, but this is
turned off by default to avoid use of the unpleasant macros in normal
circumstances.

This is a large changeset due to the number of calls that have been
replaced. The only files that contain changes other than simple
substitution of function calls are libbb.h, libbb/herror_msg.c,
libbb/verror_msg.c and libbb/xfuncs_printf.c. In miscutils/devfsd.c,
networking/udhcp/common.h and util-linux/mdev.c additonal macros have
been added for logging so that single parameter and multiple parameter
logging variants exist.

The amount of space saved varies considerably by architecture, and was
found to be as follows (for 'defconfig' using GCC 7.4):

Arm:     -92 bytes
MIPS:    -52 bytes
PPC:   -1836 bytes
x86_64: -938 bytes

Note that for the MIPS architecture only an exception had to be made
disabling the 'simple' calls for 'udhcp' (in networking/udhcp/common.h)
because it made these files larger on MIPS.

Signed-off-by: James Byrne <[email protected]>
Signed-off-by: Denys Vlasenko <[email protected]>
  • Loading branch information
James Byrne authored and Denys Vlasenko committed Jul 2, 2019
1 parent caecfdc commit 6937487
Show file tree
Hide file tree
Showing 225 changed files with 845 additions and 736 deletions.
13 changes: 13 additions & 0 deletions Config.in
Original file line number Diff line number Diff line change
Expand Up @@ -661,6 +661,19 @@ config WERROR

Most people should answer N.

config WARN_SIMPLE_MSG
bool "Warn about single parameter bb_xx_msg calls"
default n
help
This will cause warnings to be shown for any instances of
bb_error_msg(), bb_error_msg_and_die(), bb_perror_msg(),
bb_perror_msg_and_die(), bb_herror_msg() or bb_herror_msg_and_die()
being called with a single parameter. In these cases the equivalent
bb_simple_xx_msg function should be used instead.
Note that use of STRERROR_FMT may give false positives.

If you aren't developing busybox, say N here.

choice
prompt "Additional debugging library"
default NO_DEBUG_LIB
Expand Down
2 changes: 1 addition & 1 deletion archival/bbunzip.c
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ int FAST_FUNC bbunpack(char **argv,

/* Check that the input is sane */
if (!(option_mask32 & BBUNPK_OPT_FORCE) && isatty(STDIN_FILENO)) {
bb_error_msg_and_die("compressed data not read from terminal, "
bb_simple_error_msg_and_die("compressed data not read from terminal, "
"use -f to force it");
}

Expand Down
4 changes: 2 additions & 2 deletions archival/bzip2.c
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ IF_DESKTOP(long long) int bz_write(bz_stream *strm, void* rbuf, ssize_t rlen, vo
if (n2 != n) {
if (n2 >= 0)
errno = 0; /* prevent bogus error message */
bb_perror_msg(n2 >= 0 ? "short write" : bb_msg_write_error);
bb_simple_perror_msg(n2 >= 0 ? "short write" : bb_msg_write_error);
return -1;
}
}
Expand Down Expand Up @@ -187,7 +187,7 @@ IF_DESKTOP(long long) int FAST_FUNC compressStream(transformer_state_t *xstate U
while (1) {
count = full_read(STDIN_FILENO, rbuf, IOBUF_SIZE);
if (count < 0) {
bb_perror_msg(bb_msg_read_error);
bb_simple_perror_msg(bb_msg_read_error);
total = -1;
break;
}
Expand Down
14 changes: 7 additions & 7 deletions archival/dpkg.c
Original file line number Diff line number Diff line change
Expand Up @@ -487,7 +487,7 @@ static void add_split_dependencies(common_node_t *parent_node, const char *whole
} else if (strncmp(version, ">=", offset_ch) == 0) {
edge->operator = VER_MORE_EQUAL;
} else {
bb_error_msg_and_die("illegal operator");
bb_simple_error_msg_and_die("illegal operator");
}
}
/* skip to start of version numbers */
Expand Down Expand Up @@ -730,7 +730,7 @@ static void set_status(const unsigned status_node_num, const char *new_value, co
status = new_value_num;
break;
default:
bb_error_msg_and_die("DEBUG ONLY: this shouldnt happen");
bb_simple_error_msg_and_die("DEBUG ONLY: this shouldnt happen");
}

new_status = xasprintf("%s %s %s", name_hashtable[want], name_hashtable[flag], name_hashtable[status]);
Expand Down Expand Up @@ -944,10 +944,10 @@ static void write_status_file(deb_file_t **deb_file)
/* Create a separate backfile to dpkg */
if (rename("/var/lib/dpkg/status", "/var/lib/dpkg/status.udeb.bak") == -1) {
if (errno != ENOENT)
bb_error_msg_and_die("can't create backup status file");
bb_simple_error_msg_and_die("can't create backup status file");
/* Its ok if renaming the status file fails because status
* file doesn't exist, maybe we are starting from scratch */
bb_error_msg("no status file found, creating new one");
bb_simple_error_msg("no status file found, creating new one");
}

xrename("/var/lib/dpkg/status.udeb", "/var/lib/dpkg/status");
Expand Down Expand Up @@ -1816,7 +1816,7 @@ int dpkg_main(int argc UNUSED_PARAM, char **argv)
init_archive_deb_control(archive_handle);
deb_file[deb_count]->control_file = deb_extract_control_file_to_buffer(archive_handle, control_list);
if (deb_file[deb_count]->control_file == NULL) {
bb_error_msg_and_die("can't extract control file");
bb_simple_error_msg_and_die("can't extract control file");
}
deb_file[deb_count]->filename = xstrdup(argv[0]);
package_num = fill_package_struct(deb_file[deb_count]->control_file);
Expand Down Expand Up @@ -1879,13 +1879,13 @@ int dpkg_main(int argc UNUSED_PARAM, char **argv)
argv++;
}
if (!deb_count)
bb_error_msg_and_die("no package files specified");
bb_simple_error_msg_and_die("no package files specified");
deb_file[deb_count] = NULL;

/* Check that the deb file arguments are installable */
if (!(opt & OPT_force_ignore_depends)) {
if (!check_deps(deb_file, 0 /*, deb_count*/)) {
bb_error_msg_and_die("dependency check failed");
bb_simple_error_msg_and_die("dependency check failed");
}
}

Expand Down
4 changes: 2 additions & 2 deletions archival/gzip.c
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ aa: 85.1% -- replaced with aa.gz
/* Diagnostic functions */
#ifdef DEBUG
static int verbose;
# define Assert(cond,msg) { if (!(cond)) bb_error_msg(msg); }
# define Assert(cond,msg) { if (!(cond)) bb_simple_error_msg(msg); }
# define Trace(x) fprintf x
# define Tracev(x) {if (verbose) fprintf x; }
# define Tracevv(x) {if (verbose > 1) fprintf x; }
Expand Down Expand Up @@ -787,7 +787,7 @@ static void check_match(IPos start, IPos match, int length)
/* check that the match is indeed a match */
if (memcmp(G1.window + match, G1.window + start, length) != 0) {
bb_error_msg(" start %d, match %d, length %d", start, match, length);
bb_error_msg("invalid match");
bb_simple_error_msg("invalid match");
}
if (verbose > 1) {
bb_error_msg("\\[%d,%d]", start - match, length);
Expand Down
4 changes: 2 additions & 2 deletions archival/libarchive/data_extract_all.c
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ void FAST_FUNC data_extract_all(archive_handle_t *archive_handle)
struct stat existing_sb;
if (lstat(dst_name, &existing_sb) == -1) {
if (errno != ENOENT) {
bb_perror_msg_and_die("can't stat old file");
bb_simple_perror_msg_and_die("can't stat old file");
}
}
else if (existing_sb.st_mtime >= file_header->mtime) {
Expand Down Expand Up @@ -207,7 +207,7 @@ void FAST_FUNC data_extract_all(archive_handle_t *archive_handle)
}
break;
default:
bb_error_msg_and_die("unrecognized file type");
bb_simple_error_msg_and_die("unrecognized file type");
}

if (!S_ISLNK(file_header->mode)) {
Expand Down
2 changes: 1 addition & 1 deletion archival/libarchive/decompress_bunzip2.c
Original file line number Diff line number Diff line change
Expand Up @@ -817,7 +817,7 @@ unpack_bz2_stream(transformer_state_t *xstate)
break;
}
if (bd->headerCRC != bd->totalCRC) {
bb_error_msg("CRC error");
bb_simple_error_msg("CRC error");
break;
}

Expand Down
14 changes: 7 additions & 7 deletions archival/libarchive/decompress_gunzip.c
Original file line number Diff line number Diff line change
Expand Up @@ -1012,7 +1012,7 @@ inflate_unzip_internal(STATE_PARAM transformer_state_t *xstate)
error_msg = "corrupted data";
if (setjmp(error_jmp)) {
/* Error from deep inside zip machinery */
bb_error_msg(error_msg);
bb_simple_error_msg(error_msg);
n = -1;
goto ret;
}
Expand Down Expand Up @@ -1085,7 +1085,7 @@ static int top_up(STATE_PARAM unsigned n)
bytebuffer_offset = 0;
bytebuffer_size = full_read(gunzip_src_fd, &bytebuffer[count], bytebuffer_max - count);
if ((int)bytebuffer_size < 0) {
bb_error_msg(bb_msg_read_error);
bb_simple_error_msg(bb_msg_read_error);
return 0;
}
bytebuffer_size += count;
Expand Down Expand Up @@ -1211,7 +1211,7 @@ unpack_gz_stream(transformer_state_t *xstate)

if (full_read(xstate->src_fd, &magic2, 2) != 2) {
bad_magic:
bb_error_msg("invalid magic");
bb_simple_error_msg("invalid magic");
return -1;
}
if (magic2 == COMPRESS_MAGIC) {
Expand All @@ -1233,7 +1233,7 @@ unpack_gz_stream(transformer_state_t *xstate)

again:
if (!check_header_gzip(PASS_STATE xstate)) {
bb_error_msg("corrupted data");
bb_simple_error_msg("corrupted data");
total = -1;
goto ret;
}
Expand All @@ -1246,23 +1246,23 @@ unpack_gz_stream(transformer_state_t *xstate)
total += n;

if (!top_up(PASS_STATE 8)) {
bb_error_msg("corrupted data");
bb_simple_error_msg("corrupted data");
total = -1;
goto ret;
}

/* Validate decompression - crc */
v32 = buffer_read_le_u32(PASS_STATE_ONLY);
if ((~gunzip_crc) != v32) {
bb_error_msg("crc error");
bb_simple_error_msg("crc error");
total = -1;
goto ret;
}

/* Validate decompression - size */
v32 = buffer_read_le_u32(PASS_STATE_ONLY);
if ((uint32_t)gunzip_bytes_out != v32) {
bb_error_msg("incorrect length");
bb_simple_error_msg("incorrect length");
total = -1;
}

Expand Down
10 changes: 5 additions & 5 deletions archival/libarchive/decompress_uncompress.c
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ unpack_Z_stream(transformer_state_t *xstate)
/* xread isn't good here, we have to return - caller may want
* to do some cleanup (e.g. delete incomplete unpacked file etc) */
if (full_read(xstate->src_fd, inbuf, 1) != 1) {
bb_error_msg("short read");
bb_simple_error_msg("short read");
goto err;
}

Expand Down Expand Up @@ -166,7 +166,7 @@ unpack_Z_stream(transformer_state_t *xstate)
if (insize < (int) (IBUFSIZ + 64) - IBUFSIZ) {
rsize = safe_read(xstate->src_fd, inbuf + insize, IBUFSIZ);
if (rsize < 0)
bb_error_msg_and_die(bb_msg_read_error);
bb_simple_error_msg_and_die(bb_msg_read_error);
insize += rsize;
}

Expand Down Expand Up @@ -200,7 +200,7 @@ unpack_Z_stream(transformer_state_t *xstate)

if (oldcode == -1) {
if (code >= 256)
bb_error_msg_and_die("corrupted data"); /* %ld", code); */
bb_simple_error_msg_and_die("corrupted data"); /* %ld", code); */
oldcode = code;
finchar = (int) oldcode;
outbuf[outpos++] = (unsigned char) finchar;
Expand Down Expand Up @@ -236,7 +236,7 @@ unpack_Z_stream(transformer_state_t *xstate)
insize, posbits, p[-1], p[0], p[1], p[2], p[3],
(posbits & 07));
*/
bb_error_msg("corrupted data");
bb_simple_error_msg("corrupted data");
goto err;
}

Expand All @@ -247,7 +247,7 @@ unpack_Z_stream(transformer_state_t *xstate)
/* Generate output characters in reverse order */
while (code >= 256) {
if (stackp <= &htabof(0))
bb_error_msg_and_die("corrupted data");
bb_simple_error_msg_and_die("corrupted data");
*--stackp = tab_suffixof(code);
code = tab_prefixof(code);
}
Expand Down
6 changes: 3 additions & 3 deletions archival/libarchive/decompress_unlzma.c
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ static void rc_read(rc_t *rc)
//TODO: return -1 instead
//This will make unlzma delete broken unpacked file on unpack errors
if (buffer_size <= 0)
bb_error_msg_and_die("unexpected EOF");
bb_simple_error_msg_and_die("unexpected EOF");
rc->buffer_end = RC_BUFFER + buffer_size;
rc->ptr = RC_BUFFER;
}
Expand Down Expand Up @@ -234,7 +234,7 @@ unpack_lzma_stream(transformer_state_t *xstate)
if (full_read(xstate->src_fd, &header, sizeof(header)) != sizeof(header)
|| header.pos >= (9 * 5 * 5)
) {
bb_error_msg("bad lzma header");
bb_simple_error_msg("bad lzma header");
return -1;
}

Expand Down Expand Up @@ -513,7 +513,7 @@ unpack_lzma_stream(transformer_state_t *xstate)
* potentially more detailed information).
* Do not fail silently.
*/
bb_error_msg("corrupted data");
bb_simple_error_msg("corrupted data");
total_written = -1; /* failure */
}
rc_free(rc);
Expand Down
4 changes: 2 additions & 2 deletions archival/libarchive/decompress_unxz.c
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ unpack_xz_stream(transformer_state_t *xstate)
if (iobuf.in_pos == iobuf.in_size) {
int rd = safe_read(xstate->src_fd, membuf, BUFSIZ);
if (rd < 0) {
bb_error_msg(bb_msg_read_error);
bb_simple_error_msg(bb_msg_read_error);
total = -1;
break;
}
Expand Down Expand Up @@ -123,7 +123,7 @@ unpack_xz_stream(transformer_state_t *xstate)
continue;
}
if (xz_result != XZ_OK && xz_result != XZ_UNSUPPORTED_CHECK) {
bb_error_msg("corrupted data");
bb_simple_error_msg("corrupted data");
total = -1;
break;
}
Expand Down
8 changes: 4 additions & 4 deletions archival/libarchive/get_header_ar.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ static unsigned read_num(char *str, int base, int len)
* on misformatted numbers bb_strtou returns all-ones */
err = bb_strtou(str, NULL, base);
if (err == -1)
bb_error_msg_and_die("invalid ar header");
bb_simple_error_msg_and_die("invalid ar header");
return err;
}

Expand Down Expand Up @@ -53,7 +53,7 @@ char FAST_FUNC get_header_ar(archive_handle_t *archive_handle)
archive_handle->offset += 60;

if (ar.formatted.magic[0] != '`' || ar.formatted.magic[1] != '\n')
bb_error_msg_and_die("invalid ar header");
bb_simple_error_msg_and_die("invalid ar header");

/*
* Note that the fields MUST be read in reverse order as
Expand Down Expand Up @@ -86,7 +86,7 @@ char FAST_FUNC get_header_ar(archive_handle_t *archive_handle)
return get_header_ar(archive_handle);
}
#else
bb_error_msg_and_die("long filenames not supported");
bb_simple_error_msg_and_die("long filenames not supported");
#endif
}
/* Only size is always present, the rest may be missing in
Expand All @@ -107,7 +107,7 @@ char FAST_FUNC get_header_ar(archive_handle_t *archive_handle)
long_offset = read_num(&ar.formatted.name[1], 10,
sizeof(ar.formatted.name) - 1);
if (long_offset >= archive_handle->ar__long_name_size) {
bb_error_msg_and_die("can't resolve long filename");
bb_simple_error_msg_and_die("can't resolve long filename");
}
typed->name = xstrdup(archive_handle->ar__long_names + long_offset);
} else
Expand Down
6 changes: 3 additions & 3 deletions archival/libarchive/get_header_cpio.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,14 +33,14 @@ char FAST_FUNC get_header_cpio(archive_handle_t *archive_handle)
goto create_hardlinks;
}
if (size != 110) {
bb_error_msg_and_die("short read");
bb_simple_error_msg_and_die("short read");
}
archive_handle->offset += 110;

if (!is_prefixed_with(&cpio_header[0], "07070")
|| (cpio_header[5] != '1' && cpio_header[5] != '2')
) {
bb_error_msg_and_die("unsupported cpio format, use newc or crc");
bb_simple_error_msg_and_die("unsupported cpio format, use newc or crc");
}

if (sscanf(cpio_header + 6,
Expand All @@ -50,7 +50,7 @@ char FAST_FUNC get_header_cpio(archive_handle_t *archive_handle)
&inode, &mode, &uid, &gid,
&nlink, &mtime, &size,
&major, &minor, &namesize) != 10)
bb_error_msg_and_die("damaged cpio file");
bb_simple_error_msg_and_die("damaged cpio file");
file_header->mode = mode;
/* "cpio -R USER:GRP" support: */
if (archive_handle->cpio__owner.uid != (uid_t)-1L)
Expand Down
Loading

0 comments on commit 6937487

Please sign in to comment.