Bug 111284 - core dump when using strlen on x86_64
Summary: core dump when using strlen on x86_64
Keywords:
Status: CLOSED NOTABUG
Alias: None
Product: Red Hat Enterprise Linux 3
Classification: Red Hat
Component: glibc
Version: 3.0
Hardware: x86_64
OS: Linux
medium
medium
Target Milestone: ---
Assignee: Jakub Jelinek
QA Contact: Brian Brock
URL:
Whiteboard:
Depends On:
Blocks:
TreeView+ depends on / blocked
 
Reported: 2003-12-01 19:00 UTC by Ken Crandall
Modified: 2007-11-30 22:06 UTC (History)
0 users

Fixed In Version:
Doc Type: Bug Fix
Doc Text:
Clone Of:
Environment:
Last Closed: 2003-12-01 22:31:45 UTC
Target Upstream Version:
Embargoed:


Attachments (Terms of Use)

Description Ken Crandall 2003-12-01 19:00:27 UTC
From Bugzilla Helper:
User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.4) Gecko/20030922

Description of problem:
The following code breaks on Opteron RHE 3 WS.  It does not break on
SuSE.  It also works fine when compiled and run on RHEL 3 WS x86.

This is on an x86_64 box with "Everything" installed + all current
errata.  

#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>

typedef char            *String;
#define SY_OK           0
#define NIL(T)     	(T*)NULL
FILE                    *logFile = NIL(FILE);


int prInfo(String fmt, ...)
{
   va_list       args;

     va_start(args, fmt);
     vprintf(fmt, args);
     if (logFile) {
       vfprintf(logFile, fmt, args);
       fflush(logFile);
     }
     va_end(args);
   return SY_OK;
}

int
main()
{
   logFile = fopen("test.log", "w");
   prInfo("%s %s\n", "HELLO", "CORE");
   return SY_OK;
}

Version-Release number of selected component (if applicable):


How reproducible:
Always

Steps to Reproduce:
1. cc tes.c
2. ./test


    

Actual Results:  ./test
HELLO CORE
Segmentation fault (core dumped)

Expected Results:  ./test
HELLO CORE

Additional info:

[lennyd@linuxamd4 ~]$ gdb test
GNU gdb Red Hat Linux (5.3.90-0.20030710.40rh)
Copyright 2003 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you
are
welcome to change it and/or distribute copies of it under certain
conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB.  Type "show warranty" for
details.
This GDB was configured as "x86_64-redhat-linux-gnu"...(no debugging
symbols found)...Using host libthread_db library
"/lib64/tls/libthread_db.so.1".
 
 (gdb) run
Starting program: /home/lennyd/test
(no debugging symbols found)...(no debugging symbols found)...HELLO CORE
 
Program received signal SIGSEGV, Segmentation fault.
0x0000002a956e9890 in strlen () from /lib64/tls/libc.so.6
(gdb) bt
#0  0x0000002a956e9890 in strlen () from /lib64/tls/libc.so.6
#1  0x0000002a956b71b3 in vfprintf () from /lib64/tls/libc.so.6
#2  0x00000000004006a9 in prInfo ()
#3  0x00000000004006ef in main ()
(gdb)

Comment 1 Jakub Jelinek 2003-12-01 22:31:45 UTC
The testcase is buggy.
See ISO C99, 7.15:
"The object ap may be passed as an argument to another function; if that function
invokes the va_arg macro with parameter ap, the value of ap in the calling
function is indeterminate and shall be passed to the va_end macro prior to any further reference to ap.212)"
"212) It is permitted to create a pointer to a va_list and pass that pointer to another function,
in which case the original function may make further use of the original list
after the other function returns."

The vprintf function uses va_arg, so you can only pass args to va_end,
certainly not to another function which will do va_arg on it.

If you add va_end (args); va_start (args, fmt); right before the
vfprintf call, it will work just fine.


Note You need to log in before you can comment on or make changes to this bug.