http://gcc.gnu.org/bugzilla/show_bug.cgi?id=48797
Summary: GCC does inline variadic function, crashing on i386, when non-GNU stdarg.h is used Product: gcc Version: 4.4.5 Status: UNCONFIRMED Severity: major Priority: P3 Component: c AssignedTo: unassig...@gcc.gnu.org ReportedBy: wkor97gy0eef...@i.mintemail.com #include <stdarg.h> #include <stdio.h> #include <errno.h> #include <string.h> static const char* errmsg(int e, const char *em) { if (e == ENOENT || e == ENOTDIR) { return em; } return strerror(e); } void ash_vmsg(const char* msg, va_list ap) { vfprintf(stderr, msg, ap); } void ash_vmsg_and_raise(const char* msg, ...) { va_list ap; va_start(ap, msg); ash_vmsg(msg, ap); va_end(ap); } int main(int argc, char** argv) { int e = argc == 1000 ? 1 : ENOENT; ash_vmsg_and_raise("%s: %s", argv[0], errmsg(e, "not found")); return 0; } when above is compiled with -O3 using a NON-GNU libc (here musl 0.7.9 is used, where stdarg.h doesnt do some GNU_MAGIC), gcc will inline the errmsg call inside the variadic function and thus segfault. but only on i386 arch. clearly it should never inline a variadic function... Program received signal SIGSEGV, Segmentation fault. 0x08049a5d in memchr () (gdb) bt #0 0x08049a5d in memchr () #1 0x0804964c in printf_core () #2 0x0804995d in vfprintf () #3 0x080481c7 in ash_vmsg (argc=1, argv=0xbffff834) at test2.c:14 #4 ash_vmsg_and_raise (argc=1, argv=0xbffff834) at test2.c:20 #5 main (argc=1, argv=0xbffff834) at test2.c:26 (gdb) disas ash_vmsg Dump of assembler code for function ash_vmsg: 0x08048130 <ash_vmsg+0>: push %ebp 0x08048131 <ash_vmsg+1>: mov %esp,%ebp 0x08048133 <ash_vmsg+3>: sub $0x18,%esp 0x08048136 <ash_vmsg+6>: mov 0xc(%ebp),%eax 0x08048139 <ash_vmsg+9>: mov %eax,0x8(%esp) 0x0804813d <ash_vmsg+13>: mov 0x8(%ebp),%eax 0x08048140 <ash_vmsg+16>: mov %eax,0x4(%esp) 0x08048144 <ash_vmsg+20>: mov 0x804ac54,%eax 0x08048149 <ash_vmsg+25>: mov %eax,(%esp) 0x0804814c <ash_vmsg+28>: call 0x80498c6 <vfprintf> 0x08048151 <ash_vmsg+33>: leave 0x08048152 <ash_vmsg+34>: ret End of assembler dump. (gdb) disas ash_vmsg_and_raise Dump of assembler code for function ash_vmsg_and_raise: 0x08048160 <ash_vmsg_and_raise+0>: push %ebp 0x08048161 <ash_vmsg_and_raise+1>: mov %esp,%ebp 0x08048163 <ash_vmsg_and_raise+3>: sub $0x18,%esp 0x08048166 <ash_vmsg_and_raise+6>: lea 0xc(%ebp),%eax 0x08048169 <ash_vmsg_and_raise+9>: mov %eax,0x8(%esp) 0x0804816d <ash_vmsg_and_raise+13>: mov 0x8(%ebp),%eax 0x08048170 <ash_vmsg_and_raise+16>: mov %eax,0x4(%esp) 0x08048174 <ash_vmsg_and_raise+20>: mov 0x804ac54,%eax 0x08048179 <ash_vmsg_and_raise+25>: mov %eax,(%esp) 0x0804817c <ash_vmsg_and_raise+28>: call 0x80498c6 <vfprintf> 0x08048181 <ash_vmsg_and_raise+33>: leave 0x08048182 <ash_vmsg_and_raise+34>: ret End of assembler dump. (gdb) disas errmsg No function contains specified address. (gdb) disas main Dump of assembler code for function main: 0x08048190 <main+0>: push %ebp 0x08048191 <main+1>: mov %esp,%ebp 0x08048193 <main+3>: and $0xfffffff0,%esp 0x08048196 <main+6>: sub $0x20,%esp 0x08048199 <main+9>: cmpl $0x3e8,0x8(%ebp) 0x080481a0 <main+16>: je 0x80481d0 <main+64> 0x080481a2 <main+18>: lea 0x20(%esp),%eax 0x080481a6 <main+22>: mov %eax,0x8(%esp) 0x080481aa <main+26>: mov 0x804ac54,%eax 0x080481af <main+31>: movl $0x804a4a8,0x1c(%esp) 0x080481b7 <main+39>: movl $0x804a4a8,0x4(%esp) 0x080481bf <main+47>: mov %eax,(%esp) 0x080481c2 <main+50>: call 0x80498c6 <vfprintf> 0x080481c7 <main+55>: xor %eax,%eax 0x080481c9 <main+57>: leave 0x080481ca <main+58>: ret 0x080481cb <main+59>: nop 0x080481cc <main+60>: lea 0x0(%esi,%eiz,1),%esi 0x080481d0 <main+64>: movl $0x1,(%esp) 0x080481d7 <main+71>: call 0x804824c <strerror> 0x080481dc <main+76>: lea 0x0(%esi,%eiz,1),%esi 0x080481e0 <main+80>: jmp 0x80481a2 <main+18>