c/2547: GCC generate wrong size struct
flus@cesar.org.br
flus@cesar.org.br
Fri Apr 13 12:46:00 GMT 2001
>Number: 2547
>Category: c
>Synopsis: GCC generate wrong size struct
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: unassigned
>State: open
>Class: wrong-code
>Submitter-Id: net
>Arrival-Date: Fri Apr 13 12:46:00 PDT 2001
>Closed-Date:
>Last-Modified:
>Originator: Fabio Urquiza <flus@cesar.org.br>
>Release: gcc2.96 egcs1.1.2 gcc3.0(from CodeSourcery's Online Test Compilation)
>Organization:
>Environment:
Red Hat 7.0
Rpms:
gcc-2.96-69
glibc-2.1.92-14
compat-egcs-6.2-1.1.2.9
compat-glibc-6.2-2.1.3.2
>Description:
The struct "View" in the union "messagem" are created with
a size bigger than it was suppose to have. It's suppose to
have 18 bytes but are created with 20. The two adicional
bytes are inserted in the middle of the struct, so when I
have to use the others members of the union the information
becomes useless.
Some debugging that I did:
[fabio@firewall muo]$ gcc -Wall -O0 -o dec2 -g dec2.c
dec2.c: In function `main':
dec2.c:229: warning: implicit declaration of function `strcpy'
[fabio@firewall muo]$ gdb dec2
GNU gdb 5.0
Copyright 2000 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 "i386-redhat-linux"...
(gdb) break 230
Breakpoint 1 at 0x8048477: file dec2.c, line 230.
(gdb) run
Starting program: /home/fabio/muo/dec2
Breakpoint 1, main () at dec2.c:230
230 return 0;
(gdb) ptype mensagem
type = union serverMsgs {
unsigned char buffer[1024];
struct {
unsigned int m_UID;
unsigned int m_unk_5_8;
short unsigned int m_id;
short unsigned int m_x;
short unsigned int m_y;
short unsigned int m_z;
unsigned char m_dir;
unsigned char m_unk_18;
unsigned int m_unk_19_22;
short unsigned int m_unk_23_24;
short unsigned int m_unk_25_26;
short unsigned int m_mode;
short unsigned int m_unk_29_30;
unsigned char m_unk31[6];
} Start;
struct {
unsigned char m_Arg;
} Pause;
struct {
unsigned char m_warmode;
unsigned char m_unk2[3];
} War;
struct {
unsigned char m_level;
} Light;
struct {
unsigned char m_type;
short unsigned int m_ext;
} Weather;
struct {
unsigned int m_UID;
short unsigned int m_id;
unsigned char m_zero7;
short unsigned int m_color;
unsigned char m_mode;
short unsigned int m_x;
short unsigned int m_y;
short unsigned int m_zero15;
unsigned char m_dir;
unsigned char m_z;
} View;
struct {
short unsigned int m_len;
unsigned int m_UID;
short unsigned int m_id;
short unsigned int m_x;
short unsigned int m_y;
unsigned char m_z;
unsigned char m_dir;
short unsigned int m_color;
unsigned char m_mode;
---Type <return> to continue, or q <return> to quit---q
Quit
(gdb) p /x mensagem.buffer
$1 = {0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73,
0x74, 0x75, 0x76, 0x78, 0x79, 0x7a, 0x77, 0x0 <repeats 998 times>}
(gdb) p /x mensagem.View
$2 = {m_UID = 0x64636261, m_id = 0x6665, m_zero7 = 0x67, m_color = 0x6a69, m_mode = 0x6b, m_x = 0x6e6d, m_y = 0x706f,
m_zero15 = 0x7271, m_dir = 0x73, m_z = 0x74}
(gdb)
The struct seem ok but theres is two members hiding that gdb don't show
One get the 8th byte of mensagem.buffer
Other get the 12th byte of mensagem.buffer
Thanks,
Fabio Urquiza
>How-To-Repeat:
#include <stdio.h>
#include <strings.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#define MAX_NAME_SIZE 30 // imposed by client for protocol
#define START 0x1b
#define PAUSE 0x33
#define WAR 0x72
#define LIGHT 0x4f
#define WEATHER 0x65
#define VIEW 0x20
#define CHARS 0x78
#define REDRALL 0x55
#define TIME 0x5b
#define SOUND 0x54
#define CHATBLE 0xb9
#define SPEAK 0x1c
#define SCROLL 0xa6
#define PUT 0x1a
#define CHARMOVE 0x77
#define REMOVE 0x1D
#define CHARANI 0x6e
#define CONTADD 0x25
#define DRAGANIM 0x23
//#define 0x
union serverMsgs {
unsigned char buffer[1024];
struct { // size = 37 // start up player
// unsigned char m_Cmd; // 0 = 0x1B
unsigned int m_UID; // 1-4
unsigned int m_unk_5_8; // 5-8 = 0
unsigned short m_id; // 9-10
unsigned short m_x; // 11-12
unsigned short m_y; // 13-14
unsigned short m_z; // 15-16
unsigned char m_dir; // 17
unsigned char m_unk_18; // 18
unsigned int m_unk_19_22; // 19-22
unsigned short m_unk_23_24; // 23-14
unsigned short m_unk_25_26; // 23-14
unsigned short m_mode; // 27-28
unsigned short m_unk_29_30; // 29-30
unsigned char m_unk31[6];
} Start;
struct { // size = 2
// BYTE m_Cmd; // 0 = 0x33
unsigned char m_Arg; // 1 = (1=pause,0=restart)
} Pause;
struct { // size = 5 // put client to war mode.
// BYTE m_Cmd; // 0 = 0x72
unsigned char m_warmode; // 1 = 0 or 1
unsigned char m_unk2[3]; // 2 = 00 32 00
} War;
struct { // size = 2
// BYTE m_Cmd; // 0 = 0x4f
unsigned char m_level; // 1=0-19, 19=dark, On t2a 30=dark
} Light;
struct { // size = 4
// m_Cmd; // 0 = 0x65
unsigned char m_type; // 1 = type. 0=dry, 1=rain, 2=snow
unsigned short m_ext; // 2 = other weather info (severity?)
} Weather;
struct { // size = 19 // set client player view x,y,z.
// unsigned char m_Cmd; // 0 = 0x20
unsigned int m_UID; // 1-4 = my UID.
unsigned short m_id; // 5-6
unsigned char m_zero7; // 7 = 0
unsigned short m_color; // 8-9
unsigned char m_mode; // 10 = 0=normal, 4=poison, 0x40=attack, 0x80=hidden
unsigned short m_x; // 11-12
unsigned short m_y; // 13-14
unsigned short m_zero15; // 15-16 = noto ?
unsigned char m_dir; // 17 = high bit set = run
unsigned char m_z; // 18
} View;
struct { // size = 23 or var len // draw char
// unsigned m_Cmd; // 0 = 0x78
unsigned short m_len; // 1-2 = 0x0017 or var len?
unsigned int m_UID; // 3-6=
unsigned short m_id; // 7-8
unsigned short m_x; // 9-10
unsigned short m_y; // 11-12
unsigned char m_z; // 13
unsigned char m_dir; // 14 = DIR_TYPE
unsigned short m_color; // 15-16 = COLOR_TYPE
unsigned char m_mode; // 17 = CHARMODE_WAR
unsigned char m_noto; // 18 = NOTO_TYPE
struct { // This packet is extendable to show equip. size = 9
unsigned int m_UID; // 0-3 = 0 = end of the list.
unsigned short m_id; // 4-5 = | 0x8000 = include m_color.
unsigned char m_layer; // LAYER_TYPE
unsigned short m_color; // only if m_id | 0x8000
} *equip;
} Chars;
struct { // size = 4 // Set Game Time. not sure why the client cares about this.
// unsigned char m_Cmd; // 0 =0x5b
unsigned char m_hours;
unsigned char m_min;
unsigned char m_sec;
} Time;
struct { // size = 12
// unsigned char m_Cmd; // 0 = 0x54
unsigned char m_flags; // 1 = quiet, infinite repeat or single shot (0/1)
unsigned short m_id; // 2-3=sound id (SOUND_TYPE)
unsigned short m_speed; // 4-5=0 = (speed/volume modifier?)
unsigned short m_x; // 6-7
unsigned short m_y; // 8-9
unsigned short m_z; // 10-11
} Sound;
struct {// size = 3 // response to pressing the chat button
// BYTE m_Cmd; // 0 = 0xb9
unsigned short m_enable;
} ChatEnable;
struct {// size = 14 + 30 + var
// BYTE m_Cmd; // 0 = 0x1C
unsigned short m_len; // 1-2 = var len size.
unsigned int m_UID; // 3-6 = UID num of speaker. 01010101 = system
unsigned short m_id; // 7-8 = CREID_TYPE of speaker.
unsigned char m_mode; // 9 = TALKMODE_TYPE
unsigned short m_color; // 10-11 = COLOR_TYPE.
unsigned short m_font; // 12-13 = FONT_TYPE
char m_name[MAX_NAME_SIZE]; // 14
char m_text[1]; // var size.
} Speak;
struct {// size = 10 + var // Read scroll
// BYTE m_Cmd; // 0=0xA6
unsigned short m_len; // 1-2
unsigned char m_type; // 3 = form or gump = 0=tips,1=notice or 2 (SCROLL_TYPE)
unsigned int m_context; // 4-7 = context info passed from server
unsigned short m_lentext; // 8
char m_text[1]; // 10
} Scroll;
struct {// size = 19 or var len // draw the item at a location
// unsigned char m_Cmd; // 0 = 0x1a = XCMD_Put
unsigned short m_len; // 1-2 = var len = 0x0013 or 0x000e or 0x000f
unsigned int m_UID; // 3-6 = UID | UID_SPEC
unsigned short m_id; // 7-8
unsigned short m_amount; // 9-10 - only present if m_UID | UID_SPEC = pile (optional)
unsigned short m_x; // 11-12 - | 0x8000 = m_dir arg.
unsigned short m_y; // 13-14 = y | 0xC000 = m_color and m_flags fields.
unsigned char m_dir; // (optional)
unsigned char m_z; // 15 = signed char
unsigned short m_color; // 16-17 = COLOR_TYPE (optional)
unsigned char m_flags; // 18 = 0x20 = is it movable ? (direction?) (optional)
} Put;
struct {// size = 17 // simple move of a char already on screen.
//BYTE m_Cmd; // 0 = 0x77
unsigned int m_UID; // 1-4
unsigned short m_id; // 5-6 = id
unsigned short m_x; // 7-8 = x
unsigned short m_y; // 9-10
unsigned char m_z; // 11
unsigned char m_dir; // 12 = DIR_TYPE (| 0x80 = running ?)
unsigned short m_color; // 13-14 = COLOR_TYPE
unsigned char m_mode; // 15 = CHARMODE_WAR
unsigned char m_noto; // 16 = NOTO_TYPE
} CharMove;
struct {// sizeo = 5 // remove an object (item or char)
//BYTE m_Cmd; // 0 = 0x1D
unsigned int m_UID; // 1-4 = object UID.
} Remove;
struct {// size = 14 // Combat type animation.
//BYTE m_Cmd; // 0 = 0x6e
unsigned int m_UID; // 1-4=uid
unsigned short m_action; // 5-6 = ANIM_TYPE
unsigned char m_zero7; // 7 = 0 or 5 ?
unsigned char m_dir;
unsigned short m_repeat; // 9-10 = repeat count. 0=forever.
unsigned char m_backward; // 11 = backwards (0/1)
unsigned char m_repflag; // 12 = 0=dont repeat. 1=repeat
unsigned char m_framedelay; // 13 = 0=fastest.
} CharAction;
struct {// size = 20 // Add Single Item To Container.
//BYTE m_Cmd; // 0 = 0x25
unsigned int m_UID; // 1-4
unsigned short m_id;
unsigned char m_zero7;
unsigned short m_amount;
unsigned short m_x;
unsigned short m_y;
unsigned int m_UIDCont; // the container.
unsigned short m_color;
} ContAdd;
struct {// size = 26
//BYTE m_Cmd; // 0=0x23
unsigned short m_id;
unsigned short m_unk3; // 3-4 = 0
unsigned short m_unk5; // 5-9 = ?
unsigned char m_unk7; // 7 = 0, 72, 99, c1, 73
unsigned int m_srcUID; // NULL if from ground.
unsigned short m_src_x;
unsigned short m_src_y;
unsigned char m_src_z;
unsigned int m_dstUID;
unsigned short m_dst_x;
unsigned short m_dst_y;
unsigned char m_dst_z;
} DragAnim;
};
union serverMsgs mensagem;
int main() {
strcpy(mensagem.buffer,"abcdefghijklmnopqrstuvxyzw");
return 0;
}
>Fix:
>Release-Note:
>Audit-Trail:
>Unformatted:
More information about the Gcc-bugs
mailing list