[Bug c/48797] New: GCC does inline variadic function, crashing on i386, when non-GNU stdarg.h is used
wkor97gy0eef1fr at i dot mintemail.com
gcc-bugzilla@gcc.gnu.org
Thu Apr 28 02:29:00 GMT 2011
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: unassigned@gcc.gnu.org
ReportedBy: wkor97gy0eef1fr@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>
More information about the Gcc-bugs
mailing list