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