【问题标题】:getting the following warning : The ABI of passing struct with a flexible array member has changed in GCC 4.4收到以下警告:使用灵活数组成员传递结构的 ABI 在 GCC 4.4 中已更改
【发布时间】:2012-01-16 16:57:07
【问题描述】:

当我尝试运行我的程序时,我收到了这个警告和一些奇怪的错误。 以下结构中的rmi_pdu 包含我要访问的可变大小数组。

struct rmi_message_s {  /* Queue element containing Rmi message */
  struct rmi_message_s          *hnext;
  struct rmi_message_s          *hprev;
  uint16_t                      gen_counter;   /* Generation counter */
  time_value                    send_time;
  uint8_t                       retry_count;
  TAILQ_ENTRY(rmi_message_s)    rmi_message_next;
  rmi_message_pdu               rmi_pdu; /* contains a variable sized array */ 
};

typedef struct {
  uint16_t        zero;
  uint16_t        type;
  uint8_t         version;
  uint8_t         len;
  uint8_t         protocol;
  uint16_t        edge_port;
  uint16_t        core_port;
  uint32_t        connexus_id;
  pi_ipv4_addr_t  edge_addr;
  pi_ipv4_addr_t  core_addr;
  uint16_t        gen_count;     /* Integer to identify a stale packet */
  uint8_t         payload[];
} rmi_message_pdu;

问题是当我试图释放我动态分配的内存时。内容在那里,但 free() API 是 abort()ing 。这就是核心的样子

in raise () from /lib64/libc.so.6
in abort () from /lib64/libc.so.6
in __libc_message () from /lib64/libc.so.6
in _int_free () from /lib64/libc.so.6
in free () from /lib64/libc.so.6
in free (p=0x2aaabc000fa0) at mallocdbg.cc:188
in rmi_hash_cleanup (rmi_msg=0x2aaabc000fa0) at tcpsvc_rmi.c:126
in rmi_process_response (response_packet=0x27422e00) at tcpsvc_rmi.c:239
in rmi_message_handle (pkt=0x27422e00 "", cnt=28) at tcpsvc_base.c:154
in udpif_worker (arg=0x2b01f7014340) at rumpnet_virtif/if_udp_netbsd_guest.c:573
in threadbouncer (arg=0x2b01f7016428) at rumpkern/emul.c:428
in clone () from /lib64/libc.so.6

这就是分配的样子。想要使用 rmi 的调用者会将大小作为参数传递。

struct rmi_message_s *rmi_msg;
rmi_msg = (struct rmi_message_s *) malloc (sizeof(struct rmi_message_s *) + len * sizeof(uint8_t));

len 作为参数传递。

【问题讨论】:

  • 您是否将使用旧版本 GCC 编译的代码与您的代码链接(并将该结构传递给/从它传递)?
  • 您是否使用 GCC 4.4 或更高版本重建了整个项目?仅当您的某些代码是使用旧版本的 GCC 编译并且您的某些代码是使用较新版本编译时,该警告才应该是相关的。如果不是这样不是,那么问题就出在其他地方了。
  • 你如何分配rmi_message_pdu?您如何计算要分配的大小?
  • 我已经编辑了这个问题。请在那里找到它

标签: c flexible-array-member


【解决方案1】:

你没有分配足够的内存:

struct rmi_message_s *rmi_msg ;
    rmi_msg = (struct rmi_message_s *) malloc
           (sizeof(struct rmi_message_s) + len * sizeof(uint8_t));

你有...sizeof(struct rmi_message_s *)...,但它应该是...sizeof(struct rmi_message_s)...

【讨论】:

  • 天哪!多么愚蠢的错误!非常感谢您指出这一点:)
  • 没问题,任何人都可能犯这个错误。这只是一个错误。不过,这个警告看起来也令人担忧。如果您仍然收到警告,您仍然应该询问它(我不是 ABI 专家)。
【解决方案2】:

您几乎肯定不想按值传递此对象。改为传递指向对象的指针或引用。

警告是因为如果您混合使用 GCC 4.3 或更早版本和 GCC 4.4 或更高版本的代码,它们在如何在堆栈上传递该结构方面是不兼容的。无论如何,我很确定您实际上并不想在堆栈上传递它。这会非常低效,并且你会丢失你的有效载荷。

【讨论】:

  • 回复:“并且你会丢失你的有效载荷”:这是有道理的,但是 . . .似乎有一个 ABI 的全部原因是它必须试图以某种方式传递有效负载。没有?
  • 没错..我正在使用 malloc 和指针来分配..一切似乎都很好..当我试图释放内存时,问题就在那里。当我试图释放这个块时它正在断言!
  • @Nikhil:听起来您需要为您遇到的实际问题添加更多细节。如果您不能具体说明问题所在,我们将无法为您提供帮助。
  • @ruakh:我不是 GCC 中 VLA 行为的专家,但我希望它只能在编译器知道大小的情况下正确传递 VLA(例如 C99 风格的 VLA)。但是,在这种情况下,我认为 GCC 无法知道有效负载的大小(结构没有信息;大小仅基于您向malloc 询问的缓冲区的大小)。
  • 我在问题中添加了更多信息
猜你喜欢
  • 2023-03-23
  • 1970-01-01
  • 2018-03-29
  • 1970-01-01
  • 2011-03-04
  • 2012-09-22
  • 1970-01-01
  • 2011-07-25
  • 1970-01-01
相关资源
最近更新 更多