11

gcc 或 clang(或任何其他编译器)中是否有办法吐出有关结构中是否有孔(内存对齐方式)的信息?

谢谢你。

ps:如果有其他方法,请告知我。

4

7 回答 7

6

您可以使用pahole输出有关结构中的孔的信息,并可以选择尝试打包它们。

您可能想阅读“Poke-a-hole and friends”pahole 公告以获取更多信息

于 2011-10-06T13:17:06.633 回答
1

我不知道任何自动工具,但这可能是有用的示例:

#include <stddef.h>

struct test {
  typea a;
  typeb b;
  typec c;
};

int gapB = offsetof(struct test, b) - (offsetof(struct test, a) + sizeof(typea));
int gapC = offsetof(struct test, c) - (offsetof(struct test, b) + sizeof(typeb));

printf("Gap of b:%d/n", gapB);
printf("Gap of c:%d/n", gapC);

*注意:您必须为卡住的每两个成员执行此操作。

于 2011-10-06T13:02:11.883 回答
1

Gimpel 的 FlexeLint/PClint 可以做到这一点。

$ cat tst.c
int main (void)
{
    struct {
        char c;
        double d;
        short s;
    } f = { 1, 2.0, 3 };

    return f.c;
}

它会报告

$ flexelint -w1 +e95? tst.c
FlexeLint for C/C++ (Unix) Vers. 9.00L, Copyright Gimpel Software 1985-2014

--- Module:   tst.c (C)
                _
        double d;
tst.c  5  Note 958: Padding of 7 byte(s) is required to align member on 8 byte
    boundary
    _
    } f = { 1, 2.0, 3 };
tst.c  7  Note 959: Nominal struct size (18 bytes) is not an even multiple of
    the maximum member alignment (8 bytes)
tst.c  7  Note 958: Padding of 6 byte(s) is required to align end of struct on
    8 byte boundary
于 2015-06-18T14:37:45.643 回答
0

您可以通过为特定的struct使用sizeof和编写探测代码来探索这个问题&;如果sizeofn 个成员的地址不等于下一个成员的地址减去该成员的地址,则存在漏洞。

于 2011-10-06T12:20:59.907 回答
0

offsetof您可以通过宏检测此类“漏洞” :

#include <stddef.h>

struct test {
  char a;
  int b;
};
...
printf("%zu", offsetof(struct test, b));

如果这打印出超过1b则显然有对齐要求,并且编译器会在两者之间产生间隙。

显然,这发生在运行时,而不是编译时,但是您可以编写一个脚本来生成类似的源文件,在项目的其余部分之前编译并运行它,然后,根据输出,您可以进一步决定如何构建你的项目。

我认为任何编译器都没有提供通知您的工具。

于 2011-10-06T12:22:38.323 回答
0

在不分析源代码且不添加检查(使用 offsetof() 等)的情况下找到此类漏洞的一种方法是使用一些工具从对象/可执行文件/符号文件中提取符号/调试信息并查看定义结构和其中的成员,它们的偏移量和大小,看看是否一切都加起来了。不过,工会会使事情复杂化。

于 2011-10-06T12:26:49.210 回答
0

您需要一个能够理解 c/c++ 结构并包含必要的包含文件的解析器。

正如@roee-gavirel 所回答的,我认为更简单的解决方案是创建一个测试程序来打印出偏移量

#include <stdio.h>
#include <stddef.h>

typedef struct tData {
  long   id;       /* 8 bytes */
  char   name[8];  /* 8 bytes */
  float  salary;   /* 4 bytes */
} tData;

tData d;

int main()
{
  size_t s_tData  = sizeof(tData);
  size_t s_id     = sizeof(d.id);
  size_t s_name   = sizeof(d.name);
  size_t s_salary = sizeof(d.salary);

  printf("sizeof(tData) = %zu\n\n", sizeof(d));

  printf("'id'     is at = %3zu  occupies %zu bytes\n",
         offsetof(tData, id), s_id);
  printf("'name'   is at = %3zu  occupies %zu bytes\n",
         offsetof(tData, name), s_name);
  printf("'salary' is at = %3zu  occupies %zu bytes\n",
         offsetof(tData, salary), s_salary);

  printf("\n");

  if (s_tData != s_id + s_name + s_salary)
    printf("There is/are holes\n");

  return 0;
}
于 2018-03-10T10:21:26.783 回答