c/5351: function pass-by-value structure copy corrupts structure on stack

Tony Knaus awk@localhost.localdomain
Thu Jan 10 10:56:00 GMT 2002

>Number:         5351
>Category:       c
>Synopsis:       function pass-by-value structure copy corrupts structure on stack
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    unassigned
>State:          open
>Class:          wrong-code
>Submitter-Id:   net
>Arrival-Date:   Thu Jan 10 10:56:00 PST 2002
>Release:        3.1 20020110 (experimental)
System: Linux mgmt3 2.4.2-2 #1 Sun Apr 8 20:41:30 EDT 2001 i686 unknown
Architecture: i686
host: i686-pc-linux-gnu
build: i686-pc-linux-gnu
target: i686-pc-linux-gnu
configured with: ../gcc/configure --prefix=/home/tools/linux/compilers/gcc-3.1-new-spinos --enable-shared --enable-threads=posix --enable-version-specific-runtime-libs --enable-languages=c,c++,java
Passing a structure containing just an array of characters
into a function as a value is corrupt within the function.
Included is a gdb trace: 

[awk@mgmt3 ha_test]$ /home/awk/bin/gdb hat
GNU gdb 2001-09-21-cvs (MI_OUT)
Copyright 2001 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 "i686-pc-linux-gnu"...
(gdb) main'
13	void testfunc(logicalIFName_t ifName) {
14	  printf("ifName: %s\n", ifName.logicalIFName);
15	}
17	int main() {
19	    logicalIFName_t ifname;
20	    strcpy(ifname.logicalIFName, "this is a test string");
21	    testfunc(ifname);
(gdb) b 'main'
Breakpoint 1 at 0x8048226: file old.hatest.c, line 20.
(gdb) b 'testfunc' 
Breakpoint 2 at 0x80481fa: file old.hatest.c, line 14.
(gdb) l
22	}
(gdb) run
Starting program: /home/awk/src/ha_test/hat 

Breakpoint 1, main () at old.hatest.c:20
20	    strcpy(ifname.logicalIFName, "this is a test string");
(gdb) n
21	    testfunc(ifname);
(gdb) p ifname
$1 = {logicalIFName = "this is a test string", '\000' <repeats 103 times>, "\224\201\004\b"}
(gdb) s
memcpy (dstpp=0xbffff680, srcpp=0xbffff700, len=128) at ../sysdeps/generic/memcpy.c:40
40	../sysdeps/generic/memcpy.c: No such file or directory.
	in ../sysdeps/generic/memcpy.c
(gdb) s
33	in ../sysdeps/generic/memcpy.c
(gdb) s
34	in ../sysdeps/generic/memcpy.c
(gdb) s
35	in ../sysdeps/generic/memcpy.c
(gdb) s
40	in ../sysdeps/generic/memcpy.c
(gdb) s
43	in ../sysdeps/generic/memcpy.c
(gdb) s
44	in ../sysdeps/generic/memcpy.c
(gdb) s
55	in ../sysdeps/generic/memcpy.c
(gdb) s
61	in ../sysdeps/generic/memcpy.c
(gdb) p dstpp
$2 = (void *) 0xbffff680
(gdb) p (char*) dstpp
$3 = 0xbffff680 "this is a test string"
(gdb) s
63	in ../sysdeps/generic/memcpy.c
(gdb) s
64	in ../sysdeps/generic/memcpy.c
(gdb) p (char*) dstpp
$4 = 0xbffff680 "this is a test string"
(gdb) s

Breakpoint 2, testfunc (ifName={logicalIFName = "\000÷ÿ¿\224ã\b\b EDTst string", '\000' <repeats 103 times>, "\224\201\004\b"})
    at old.hatest.c:14
14	  printf("ifName: %s\n", ifName.logicalIFName);
(gdb) p ifName
$5 = {logicalIFName = "\000÷ÿ¿\224ã\b\b EDTst string", '\000' <repeats 103 times>, "\224\201\004\b"}
(gdb) p ifName
(gdb) p ifName
$6 = (logicalIFName_t *) 0xbffff680
(gdb) quit
The program is running.  Exit anyway? (y or n) y
[awk@mgmt3 ha_test]$ exit
Script done on Thu Jan 10 13:33:53 2002

compile and run the follow test example.

#include <stdio.h>
#include <string.h>

#define NAMESIZE 128

struct logicalifname {
        char logicalIFName[NAMESIZE];
typedef struct logicalifname logicalifname;

typedef logicalifname logicalIFName_t;

void testfunc(logicalIFName_t ifName) {
  printf("ifName: %s\n", ifName.logicalIFName);

int main() {

    logicalIFName_t ifname;
    strcpy(ifname.logicalIFName, "this is a test string");

You can work around the problem by adding a dummy variable 
to the contents of the structure logicalifname.

More information about the Gcc-bugs mailing list