This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
c/8404: arguments/stack corrupted when passing non-byte aligned struct with attribute packed
- From: fredlwm at pervalidus dot net
- To: gcc-gnats at gcc dot gnu dot org
- Date: Wed, 30 Oct 2002 13:41:36 -0300
- Subject: c/8404: arguments/stack corrupted when passing non-byte aligned struct with attribute packed
>Number: 8404
>Category: c
>Synopsis: arguments/stack corrupted when passing non-byte aligned struct with attribute packed
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: unassigned
>State: open
>Class: wrong-code
>Submitter-Id: net
>Arrival-Date: Wed Oct 30 08:46:03 PST 2002
>Closed-Date:
>Last-Modified:
>Originator: Frédéric L. W. Meunier
>Release: 3.2
>Organization:
>Environment:
System: Linux pervalidus 2.4.19 #1 Sat Aug 17 13:14:00 BRT 2002 i686 unknown unknown GNU/Linux
Architecture: i686
host: i686-pc-linux-gnu
build: i686-pc-linux-gnu
target: i686-pc-linux-gnu
configured with: /usr/local/src/GNU/gcc-3.2/configure --prefix=/usr --libdir=/usr/lib --with-slibdir=/lib --mandir=/usr/share/man --infodir=/usr/share/info --enable-threads --enable-__cxa_atexit --enable-languages=c++ --disable-nls
>Description:
>How-To-Repeat:
// GCC 3.2 BUG REPORT
//
// This program demonstrates a bug in gcc version 3.2, when passing a
// structure with the "packed" attribute comtaining misaligned data.
// The data structure is actually from the ATA/ATAPI SMART data
// structures. I was working on some legacy code that passed these
// structures (not pointers to them!) as arguments. For myself, there
// is no urgency in this because I have modified the code to do what
// it should have done in the first place -- pass pointers. But it's
// a serious bug.
// Bruce Allen ballen@uwm.edu
// F.L.W. Meunier <0@pervalidus.net>
// Compile like this: cc -o bug bug.c
// It SHOULD print "These two values should be equal: 16 16
// GCC 3.2 output "These two values should be equal: 62104 16
// System is modified slackware
#include <stdio.h>
#define NUMBER_ATA_SMART_ATTRIBUTES 30
struct ata_smart_attribute {
unsigned char id;
union {
unsigned short all;
struct {
unsigned prefailure:1;
unsigned online:1;
unsigned performance:1;
unsigned errorrate:1;
unsigned eventcount:1 ;
unsigned selfperserving:1;
unsigned reserved:10;
} __attribute__ ((packed)) flag;
} status ;
unsigned char current;
unsigned char worst;
unsigned char raw[6];
unsigned char reserv;
} __attribute__ ((packed));
struct ata_smart_values {
unsigned short int revnumber;
struct ata_smart_attribute vendor_attributes [NUMBER_ATA_SMART_ATTRIBUTES];
unsigned char offline_data_collection_status;
unsigned char self_test_exec_status;
unsigned short int total_time_to_complete_off_line;
unsigned char vendor_specific_366;
unsigned char offline_data_collection_capability;
unsigned short int smart_capability;
unsigned char errorlog_capability;
unsigned char vendor_specific_371;
unsigned char short_test_completion_time;
unsigned char extend_test_completion_time;
unsigned char reserved_374_385 [12];
unsigned char vendor_specific_386_509 [125];
unsigned char chksum;
} __attribute__ ((packed));
struct ata_smart_threshold_entry {
unsigned char id;
unsigned char threshold;
unsigned char reserved[10];
} __attribute__ ((packed));
struct ata_smart_thresholds {
unsigned short int revnumber;
struct ata_smart_threshold_entry thres_entries[NUMBER_ATA_SMART_ATTRIBUTES];
unsigned char reserved[149];
unsigned char chksum;
} __attribute__ ((packed));
// This function is the problem. When it gets it's arguments passsd
// (a total of 2x512+4 bytes or 1028 bytes of argument!) the first
// seven bytes get messed up (according to ddd/gdb)
void problem(struct ata_smart_values data,
struct ata_smart_thresholds thresholds,
int onlyfailed){
printf("These two values should be equal: %d %d\n",
data.revnumber,onlyfailed);
return;
}
// Define two of these data structures
struct ata_smart_values smartval;
struct ata_smart_thresholds smartthres;
// Should print "16 16" but doesn't
int main(int argc, char **argv){
unsigned short i=16;
smartval.revnumber=smartthres.revnumber=16;
problem(smartval, smartthres, i);
return 0;
}
>Fix:
don't pass strutures, pass pointers. Seriously, don't know.
>Release-Note:
>Audit-Trail:
>Unformatted: