Hello Al, I tried to reproduce the issue and the relevant part of the crash seems here:
(gdb) bt #0 __strlen_sse2 () at ../sysdeps/x86_64/multiarch/../strlen.S:120 #1 0x00007ffff734446c in _IO_vfprintf_internal (s=s@entry=0x7fffffffe030, format=format@entry=0x5555556873e8 "[chuck](VM): sporking incoming shred: %i (%s)...", ap=ap@entry=0x7fffffffe178) at vfprintf.c:1643 #2 0x00007ffff7365191 in __IO_vsprintf (string=0x555555923260 <g_buffer> "[chuck](VM): sporking incoming shred: 0 (", format=0x5555556873e8 "[chuck](VM): sporking incoming shred: %i (%s)...", args=0x7fffffffe178) at iovsprintf.c:42 #3 0x0000555555573097 in EM_error3 (message=0x5555556873e8 "[chuck](VM): sporking incoming shred: %i (%s)...") at chuck_errmsg.cpp:215 #4 0x0000555555576cfb in Chuck_VM::process_msg (this=0x5555559b9770, msg=0x7ffff0000b50) at chuck_vm.cpp:915 #5 0x00005555555762f9 in Chuck_VM::compute (this=0x5555559b9770) at chuck_vm.cpp:631 #6 0x000055555557632d in Chuck_VM::run (this=0x5555559b9770, num_samps=-1) at chuck_vm.cpp:650 #7 0x0000555555576110 in Chuck_VM::run (this=0x5555559b9770) at chuck_vm.cpp:551 #8 0x00005555555d9662 in main (argc=3, argv=0x7fffffffe648) at chuck_main.cpp:702 void EM_error3( const char * message, ... ) { va_list ap; g_lasterror[0] = '\0'; g_buffer[0] = '\0'; va_start( ap, message ); vfprintf( stderr, message, ap ); vsprintf( g_buffer, message, ap ); va_end( ap ); strcat( g_lasterror, g_buffer ); fprintf( stderr, "\n" ); fflush( stderr ); } After some time looking into it I found that it crashes just on the second use of the ap variable and some further searching revealed that using a va_list twice is not guaranteed to be working. (Some of the references below.) Attached patch just calls between a va_end/va_start to enter vsprintf with a "fresh" va_list. What looks like the upstream git repository (no direct link found at the homepage), contains a commit [1] that mentions version 1.3.1.0, that contains a fix for this issue dating back to 3rd September 2012. Kind regards, Bernhard [1] https://github.com/ccrma/chuck/commit/e9c353bafce9115e7ee82687bdc07208526d454a#diff-0c7246fad1aef2b08e405117c8883323 https://gcc.gnu.org/bugzilla/show_bug.cgi?id=31484 You must call va_start/va_end whenever you want to reuse a va_list. https://bytes.com/topic/c/answers/215847-reusing-va_list In C89: you cannot. In C99: use va_copy() to make a copy of "ap" before passing it to the first vprintf(). https://stackoverflow.com/questions/9309246/repeated-use-of-a-variadic-function-argument-doesnt-work When a va_list value is passed to another function (vfprintf() and vprintf() in this code), you should assume that it is no longer usable in the current function. It is only safe to call va_end() on it. https://linux.die.net/man/3/va_start: Each call to va_arg() modifies ap so that the next call returns the next argument.
From 1cfeed433c4a5f6e73e82b7b271a9d852adf2f54 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bernhard=20=C3=9Cbelacker?= <bernha...@mailbox.org> Date: Mon, 30 Jul 2018 16:23:59 +0200 Subject: [PATCH] Avoid crash when va_list got used twice. Bug-Debian: https://bugs.debian.org/863926 Last-Update: 2018-07-30 --- src/chuck_errmsg.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/chuck_errmsg.cpp b/src/chuck_errmsg.cpp index 411cad0..f31bcf0 100644 --- a/src/chuck_errmsg.cpp +++ b/src/chuck_errmsg.cpp @@ -140,6 +140,8 @@ void EM_error( int pos, const char * message, ... ) strcat( g_lasterror, " " ); va_start(ap, message); vfprintf(stderr, message, ap); + va_end(ap); + va_start(ap, message); vsprintf( g_buffer, message, ap ); va_end(ap); fprintf(stderr, "\n"); @@ -166,6 +168,8 @@ void EM_error2( int line, const char * message, ... ) va_start( ap, message ); vfprintf( stderr, message, ap ); + va_end( ap ); + va_start( ap, message ); vsprintf( g_buffer, message, ap ); va_end( ap ); @@ -193,6 +197,8 @@ void EM_error2b( int line, const char * message, ... ) va_start( ap, message ); vfprintf( stderr, message, ap ); + va_end( ap ); + va_start( ap, message ); vsprintf( g_buffer, message, ap ); va_end( ap ); @@ -212,6 +218,8 @@ void EM_error3( const char * message, ... ) va_start( ap, message ); vfprintf( stderr, message, ap ); + va_end( ap ); + va_start( ap, message ); vsprintf( g_buffer, message, ap ); va_end( ap ); -- 2.18.0
apt install psmisc chuck chuck-dbgsym valgrind gdb dpkg-dev devscripts git apt build-dep chuck (mkdir chuck; cd chuck; apt source chuck) (mkdir glibc; cd glibc; apt source glibc) chuck --loop --silent chuck + /usr/share/doc/chuck/examples/basic/foo # gdb -q --args chuck --loop --silent directory /home/benutzer/chuck/chuck-1.2.0.8.dfsg/src directory /home/benutzer/glibc/glibc-2.27/stdio-common directory /home/benutzer/glibc/glibc-2.27/libio set height 0 set width 0 set pagination off (gdb) run Starting program: /usr/bin/chuck --loop --silent [Thread debugging using libthread_db enabled] Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1". [New Thread 0x7ffff6735700 (LWP 6485)] [New Thread 0x7ffff5f34700 (LWP 6486)] [chuck](VM): sporking incoming shred: 1 (foo)... Thread 1 "chuck" received signal SIGSEGV, Segmentation fault. __strlen_sse2 () at ../sysdeps/x86_64/multiarch/../strlen.S:120 120 movdqu (%rax), %xmm4 (gdb) bt #0 __strlen_sse2 () at ../sysdeps/x86_64/multiarch/../strlen.S:120 #1 0x00007ffff734446c in _IO_vfprintf_internal (s=s@entry=0x7fffffffe030, format=format@entry=0x5555556873e8 "[chuck](VM): sporking incoming shred: %i (%s)...", ap=ap@entry=0x7fffffffe178) at vfprintf.c:1643 #2 0x00007ffff7365191 in __IO_vsprintf (string=0x555555923260 <g_buffer> "[chuck](VM): sporking incoming shred: 0 (", format=0x5555556873e8 "[chuck](VM): sporking incoming shred: %i (%s)...", args=0x7fffffffe178) at iovsprintf.c:42 #3 0x0000555555573097 in EM_error3 (message=0x5555556873e8 "[chuck](VM): sporking incoming shred: %i (%s)...") at chuck_errmsg.cpp:215 #4 0x0000555555576cfb in Chuck_VM::process_msg (this=0x5555559b9770, msg=0x7ffff0000b50) at chuck_vm.cpp:915 #5 0x00005555555762f9 in Chuck_VM::compute (this=0x5555559b9770) at chuck_vm.cpp:631 #6 0x000055555557632d in Chuck_VM::run (this=0x5555559b9770, num_samps=-1) at chuck_vm.cpp:650 #7 0x0000555555576110 in Chuck_VM::run (this=0x5555559b9770) at chuck_vm.cpp:551 #8 0x00005555555d9662 in main (argc=3, argv=0x7fffffffe648) at chuck_main.cpp:702 (gdb) bt full #0 __strlen_sse2 () at ../sysdeps/x86_64/multiarch/../strlen.S:120 No locals. #1 0x00007ffff734446c in _IO_vfprintf_internal (s=s@entry=0x7fffffffe030, format=format@entry=0x5555556873e8 "[chuck](VM): sporking incoming shred: %i (%s)...", ap=ap@entry=0x7fffffffe178) at vfprintf.c:1643 len = <optimized out> string_malloced = 0 string = 0xfe80 <error: Cannot access memory at address 0xfe80> width = 0 signed_number = <optimized out> is_short = <optimized out> spec = 115 's' ptr = <optimized out> ptr = <optimized out> outc = <optimized out> step0_jumps = {0, 104, 2456, 2352, 2024, 1912, 3088, -304, 160, 2848, 2664, 2128, 2568, 2560, 3040, 2960, 3200, 2328, 1824, 1568, -616, 64, 512, -384, -960, -1392, 1288, -1488, -1488, 2224} base = <optimized out> pad = <optimized out> offset = <optimized out> offset = <optimized out> step1_jumps = {0, 0, 0, 0, 0, 0, 0, 0, 0, 2848, 2664, 2128, 2568, 2560, 3040, 2960, 3200, 2328, 1824, 1568, -616, 64, 512, -384, -960, -1392, 1288, -1488, -1488, 0} args_value = <optimized out> is_negative = <optimized out> number = <optimized out> use_outdigits = <optimized out> step2_jumps = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2664, 2128, 2568, 2560, 3040, 2960, 3200, 2328, 1824, 1568, -616, 64, 512, -384, -960, -1392, 1288, -1488, -1488, 0} alt = 0 left = 0 showsign = 0 group = 0 is_char = <optimized out> step3a_jumps = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2752, 0, 0, 0, 3040, 2960, 3200, 2328, 1824, 0, 0, 0, 0, -384, 0, 0, 0, 0, 0, 0} the_arg = {pa_wchar = -8816 L'\xffffdd90', pa_int = -8816, pa_long_int = 140737488346512, pa_long_long_int = 140737488346512, pa_u_int = 4294958480, pa_u_long_int = 140737488346512, pa_u_long_long_int = 140737488346512, pa_double = 6.953355807399436e-310, pa_long_double = <invalid float value>, pa_string = 0x7fffffffdd90 "\260\335\377\377\377\177", pa_wstring = 0x7fffffffdd90 L"\xffffddb0翿\x400db61", pa_pointer = 0x7fffffffdd90, pa_user = 0x7fffffffdd90} space = 0 is_long_double = <optimized out> is_long = <optimized out> step3b_jumps = {0 <repeats 11 times>, 2568, 0, 0, 3040, 2960, 3200, 2328, 1824, 1568, -616, 64, 512, -384, -960, -1392, 1288, 0, 0, 0} step4_jumps = {0 <repeats 14 times>, 3040, 2960, 3200, 2328, 1824, 1568, -616, 64, 512, -384, -960, -1392, 1288, 0, 0, 0} prec = <optimized out> _buffer = {__routine = 0x5555556873e8, __arg = 0x7fffffffe150, __canceltype = -7816, __prev = 0x7fffffffe640} _avail = <optimized out> thousands_sep = 0x0 grouping = 0xffffffffffffffff <error: Cannot access memory at address 0xffffffffffffffff> done = 41 f = 0x555555687413 "s)..." lead_str_end = 0x55555568740e "%i (%s)..." end_of_spec = <optimized out> work_buffer = " \334\377\377\377\177\000\000@\335\377\377\377\177\000\000\060\334\377\377\377\177\000\000\206\210YUUU\000\000@\334\377\377\377\177\000\000@\335\377\377\377\177\000\000P\334\377\377\377\177\000\000\273\214YUUU\000\000`\334\377\377\377\177\000\000@\335\377\377\377\177\000\000p\334\377\377\377\177\000\000ՌYUUU\000\000\200\334\377\377\377\177\000\000\200\337\377\377\377\177\000\000\240\334\377\377\377\177\000\000\002\000\000\000UU\000\000\240\334\377\377\377\177\000\000\000\000\000\000\377\177\000\000@\335\377\377\377\177\000\000\220^\270UUU\000\000\300\334\377\377\377\177\000\000ʉYUUU\000\000\037\337\377\377\377\177\000\000$\345\375\367\377\177\000\000\340\334\377\377\377\177\000\000#\002"... workstart = <optimized out> workend = <optimized out> ap_save = {{gp_offset = 24, fp_offset = 48, overflow_arg_area = 0x7fffffffe250, reg_save_area = 0x7fffffffe190}} nspecs_done = 1 save_errno = 0 readonly_format = 0 __PRETTY_FUNCTION__ = "_IO_vfprintf_internal" __result = <optimized out> #2 0x00007ffff7365191 in __IO_vsprintf (string=0x555555923260 <g_buffer> "[chuck](VM): sporking incoming shred: 0 (", format=0x5555556873e8 "[chuck](VM): sporking incoming shred: %i (%s)...", args=0x7fffffffe178) at iovsprintf.c:42 sf = {_sbf = {_f = {_flags = -72515583, _IO_read_ptr = 0x555555923260 <g_buffer> "[chuck](VM): sporking incoming shred: 0 (", _IO_read_end = 0x555555923260 <g_buffer> "[chuck](VM): sporking incoming shred: 0 (", _IO_read_base = 0x555555923260 <g_buffer> "[chuck](VM): sporking incoming shred: 0 (", _IO_write_base = 0x555555923260 <g_buffer> "[chuck](VM): sporking incoming shred: 0 (", _IO_write_ptr = 0x555555923289 <g_buffer+41> "", _IO_write_end = 0xffffffffffffffff <error: Cannot access memory at address 0xffffffffffffffff>, _IO_buf_base = 0x555555923260 <g_buffer> "[chuck](VM): sporking incoming shred: 0 (", _IO_buf_end = 0xffffffffffffffff <error: Cannot access memory at address 0xffffffffffffffff>, _IO_save_base = 0x0, _IO_backup_base = 0x0, _IO_save_end = 0x0, _markers = 0x0, _chain = 0x0, _fileno = 0, _flags2 = 128, _old_offset = 0, _cur_column = 0, _vtable_offset = 0 '\000', _shortbuf = "", _lock = 0x0, _offset = 0, _codecvt = 0x0, _wide_data = 0xffffffffffffffff, _freeres_list = 0x0, _freeres_buf = 0x0, __pad5 = 0, _mode = -1, _unused2 = "\377\177\000\000߹XUUU\000\000\002\004\000\000\060\001\000"}, vtable = 0x7ffff74a8360 <_IO_str_jumps>}, _s = {_allocate_buffer_unused = 0x0, _free_buffer_unused = 0x5841fe2a87072a00}} ret = <optimized out> #3 0x0000555555573097 in EM_error3 (message=0x5555556873e8 "[chuck](VM): sporking incoming shred: %i (%s)...") at chuck_errmsg.cpp:215 ap = {{gp_offset = 40, fp_offset = 48, overflow_arg_area = 0x7fffffffe250, reg_save_area = 0x7fffffffe190}} #4 0x0000555555576cfb in Chuck_VM::process_msg (this=0x5555559b9770, msg=0x7ffff0000b50) at chuck_vm.cpp:915 xid = 1 shred = 0x555555af8990 s = 0x7ffff0000be0 "/usr/share/doc/chuck/examples/basic/foo" retval = 4294967280 #5 0x00005555555762f9 in Chuck_VM::compute (this=0x5555559b9770) at chuck_vm.cpp:631 shred = 0x0 msg = 0x7ffff0000b50 event = 0x0 iterate = 0 #6 0x000055555557632d in Chuck_VM::run (this=0x5555559b9770, num_samps=-1) at chuck_vm.cpp:650 No locals. #7 0x0000555555576110 in Chuck_VM::run (this=0x5555559b9770) at chuck_vm.cpp:551 No locals. #8 0x00005555555d9662 in main (argc=3, argv=0x7fffffffe648) at chuck_main.cpp:702 compiler = 0x5555559c7b60 vm = 0x5555559b9770 code = 0x0 shred = 0x0 enable_audio = 0 vm_halt = 0 srate = 48000 buffer_size = 512 num_buffers = 8 dac = 0 adc = 0 dac_chans = 2 adc_chans = 2 dump = 0 probe = 0 set_priority = 0 auto_depend = 0 block = 1 enable_shell = 0 no_vm = 0 load_hid = 0 enable_server = 1 do_watchdog = 0 log_level = 1 deprecate_level = 1 filename = "" args = std::vector of length 0, capacity 0 files = 0 count = 1 i = 3 (gdb) print/x $rax $1 = 0xfe80 (gdb) disassemble 0x555555576c8e,0x555555576c8e+0x70 Dump of assembler code from 0x555555576c8e to 0x555555576cfe: => 0x0000555555576c8e <Chuck_VM::process_msg(Chuck_Msg*)+1902>: mov -0x90(%rbp),%rax 0x0000555555576c95 <Chuck_VM::process_msg(Chuck_Msg*)+1909>: mov 0x18(%rax),%rax 0x0000555555576c99 <Chuck_VM::process_msg(Chuck_Msg*)+1913>: test %rax,%rax 0x0000555555576c9c <Chuck_VM::process_msg(Chuck_Msg*)+1916>: je 0x555555576cb9 <Chuck_VM::process_msg(Chuck_Msg*)+1945> 0x0000555555576c9e <Chuck_VM::process_msg(Chuck_Msg*)+1918>: mov -0x90(%rbp),%rax 0x0000555555576ca5 <Chuck_VM::process_msg(Chuck_Msg*)+1925>: mov 0x18(%rax),%rax 0x0000555555576ca9 <Chuck_VM::process_msg(Chuck_Msg*)+1929>: add $0x140,%rax 0x0000555555576caf <Chuck_VM::process_msg(Chuck_Msg*)+1935>: mov %rax,%rdi 0x0000555555576cb2 <Chuck_VM::process_msg(Chuck_Msg*)+1938>: callq 0x55555556b5b0 <_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE5c_strEv@plt> 0x0000555555576cb7 <Chuck_VM::process_msg(Chuck_Msg*)+1943>: jmp 0x555555576cd0 <Chuck_VM::process_msg(Chuck_Msg*)+1968> 0x0000555555576cb9 <Chuck_VM::process_msg(Chuck_Msg*)+1945>: mov -0x90(%rbp),%rax 0x0000555555576cc0 <Chuck_VM::process_msg(Chuck_Msg*)+1952>: mov 0x10(%rax),%rax 0x0000555555576cc4 <Chuck_VM::process_msg(Chuck_Msg*)+1956>: add $0x58,%rax 0x0000555555576cc8 <Chuck_VM::process_msg(Chuck_Msg*)+1960>: mov %rax,%rdi 0x0000555555576ccb <Chuck_VM::process_msg(Chuck_Msg*)+1963>: callq 0x55555556b5b0 <_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE5c_strEv@plt> 0x0000555555576cd0 <Chuck_VM::process_msg(Chuck_Msg*)+1968>: mov %rax,-0x68(%rbp) --> this actually sets variable s 0x0000555555576cd4 <Chuck_VM::process_msg(Chuck_Msg*)+1972>: mov -0x68(%rbp),%rax 0x0000555555576cd8 <Chuck_VM::process_msg(Chuck_Msg*)+1976>: mov %rax,%rdi 0x0000555555576cdb <Chuck_VM::process_msg(Chuck_Msg*)+1979>: callq 0x5555555727f6 <mini(char const*)> 0x0000555555576ce0 <Chuck_VM::process_msg(Chuck_Msg*)+1984>: mov %rax,%rdx --> rdx contains now pointer to "foo" 0x0000555555576ce3 <Chuck_VM::process_msg(Chuck_Msg*)+1987>: mov -0x60(%rbp),%rax 0x0000555555576ce7 <Chuck_VM::process_msg(Chuck_Msg*)+1991>: mov %rax,%rsi --> rsi contains now content of variable xid 0x0000555555576cea <Chuck_VM::process_msg(Chuck_Msg*)+1994>: lea 0x1106f7(%rip),%rdi # 0x5555556873e8 0x0000555555576cf1 <Chuck_VM::process_msg(Chuck_Msg*)+2001>: mov $0x0,%eax 0x0000555555576cf6 <Chuck_VM::process_msg(Chuck_Msg*)+2006>: callq 0x555555572fc6 <EM_error3(char const*, ...)> 0x0000555555576cfb <Chuck_VM::process_msg(Chuck_Msg*)+2011>: mov -0x60(%rbp),%rax End of assembler dump. (gdb) disassemble EM_error3 Dump of assembler code for function EM_error3(char const*, ...): 0x0000555555572fc6 <+0>: push %rbp => 0x0000555555572fc7 <+1>: mov %rsp,%rbp 0x0000555555572fca <+4>: sub $0xe0,%rsp 0x0000555555572fd1 <+11>: mov %rdi,-0xd8(%rbp) --> put pointer to message to -0xd8(%rbp) == 0x7fffffffe168 0x0000555555572fd8 <+18>: mov %rsi,-0xa8(%rbp) --> put content of variable xid to -0xa8(%rbp) == 0x7fffffffe198 0x0000555555572fdf <+25>: mov %rdx,-0xa0(%rbp) --> put pointer to "foo" to -0xa0(%rbp) == 0x7fffffffe1a0 0x0000555555572fe6 <+32>: mov %rcx,-0x98(%rbp) 0x0000555555572fed <+39>: mov %r8,-0x90(%rbp) 0x0000555555572ff4 <+46>: mov %r9,-0x88(%rbp) 0x0000555555572ffb <+53>: test %al,%al 0x0000555555572ffd <+55>: je 0x55555557301f <EM_error3(char const*, ...)+89> 0x0000555555572fff <+57>: movaps %xmm0,-0x80(%rbp) 0x0000555555573003 <+61>: movaps %xmm1,-0x70(%rbp) 0x0000555555573007 <+65>: movaps %xmm2,-0x60(%rbp) 0x000055555557300b <+69>: movaps %xmm3,-0x50(%rbp) 0x000055555557300f <+73>: movaps %xmm4,-0x40(%rbp) 0x0000555555573013 <+77>: movaps %xmm5,-0x30(%rbp) 0x0000555555573017 <+81>: movaps %xmm6,-0x20(%rbp) 0x000055555557301b <+85>: movaps %xmm7,-0x10(%rbp) 0x000055555557301f <+89>: movb $0x0,0x389aba(%rip) # 0x5555558fcae0 <_ZL11g_lasterror> 0x0000555555573026 <+96>: movb $0x0,0x3b0233(%rip) # 0x555555923260 <_ZL8g_buffer> 0x000055555557302d <+103>: movl $0x8,-0xc8(%rbp) 0x0000555555573037 <+113>: movl $0x30,-0xc4(%rbp) 0x0000555555573041 <+123>: lea 0x10(%rbp),%rax 0x0000555555573045 <+127>: mov %rax,-0xc0(%rbp) 0x000055555557304c <+134>: lea -0xb0(%rbp),%rax 0x0000555555573053 <+141>: mov %rax,-0xb8(%rbp) 0x000055555557305a <+148>: mov 0x3afadf(%rip),%rax # 0x555555922b40 <stderr> 0x0000555555573061 <+155>: lea -0xc8(%rbp),%rdx 0x0000555555573068 <+162>: mov -0xd8(%rbp),%rcx 0x000055555557306f <+169>: mov %rcx,%rsi 0x0000555555573072 <+172>: mov %rax,%rdi 0x0000555555573075 <+175>: callq 0x55555556beb0 <vfprintf@plt> 0x000055555557307a <+180>: lea -0xc8(%rbp),%rdx 0x0000555555573081 <+187>: mov -0xd8(%rbp),%rax 0x0000555555573088 <+194>: mov %rax,%rsi 0x000055555557308b <+197>: lea 0x3b01ce(%rip),%rdi # 0x555555923260 <_ZL8g_buffer> 0x0000555555573092 <+204>: callq 0x55555556b630 <vsprintf@plt> 0x0000555555573097 <+209>: lea 0x3b01c2(%rip),%rsi # 0x555555923260 <_ZL8g_buffer> 0x000055555557309e <+216>: lea 0x389a3b(%rip),%rdi # 0x5555558fcae0 <_ZL11g_lasterror> 0x00005555555730a5 <+223>: callq 0x55555556c3a0 <strcat@plt> 0x00005555555730aa <+228>: mov 0x3afa8f(%rip),%rax # 0x555555922b40 <stderr> 0x00005555555730b1 <+235>: mov %rax,%rsi 0x00005555555730b4 <+238>: mov $0xa,%edi 0x00005555555730b9 <+243>: callq 0x55555556bde0 <fputc@plt> 0x00005555555730be <+248>: mov 0x3afa7b(%rip),%rax # 0x555555922b40 <stderr> 0x00005555555730c5 <+255>: mov %rax,%rdi 0x00005555555730c8 <+258>: callq 0x55555556bcd0 <fflush@plt> 0x00005555555730cd <+263>: nop 0x00005555555730ce <+264>: leaveq 0x00005555555730cf <+265>: retq End of assembler dump. ########### ########### ########### void EM_error3( const char * message, ... ) { va_list ap; g_lasterror[0] = '\0'; g_buffer[0] = '\0'; va_start( ap, message ); vfprintf( stderr, message, ap ); vsprintf( g_buffer, message, ap ); va_end( ap ); strcat( g_lasterror, g_buffer ); fprintf( stderr, "\n" ); fflush( stderr ); } https://gcc.gnu.org/bugzilla/show_bug.cgi?id=31484 You must call va_start/va_end whenever you want to reuse a va_list. https://bytes.com/topic/c/answers/215847-reusing-va_list In C89: you cannot. In C99: use va_copy() to make a copy of "ap" before passing it to the first vprintf(). https://stackoverflow.com/questions/9309246/repeated-use-of-a-variadic-function-argument-doesnt-work When a va_list value is passed to another function (vfprintf() and vprintf() in this code), you should assume that it is no longer usable in the current function. It is only safe to call va_end() on it. https://linux.die.net/man/3/va_start: Each call to va_arg() modifies ap so that the next call returns the next argument.