2011-10-06 21 views
9

孔是否有GCC或鏗鏘的方式(或任何其他編譯器)吐約一個結構是否有孔(內存對齊 - 明智的)信息呢?查找C中的結構,由於對準

謝謝。

PS:如果有另一種方式來做到這一點,請你告訴我。

+0

存在已知的技術來寫的結構,所以你可以幾乎肯定的是他們做的不包含填充。如果這有幫助,請告訴我,我會填寫你的詳細信息。 – Lindydancer

+0

出於好奇,爲什麼? – detly

回答

0

您可以通過使用sizeof&編寫特定struct的探針代碼來探索此問題;如果sizeof第n個成員不等於下一成員減去成員的地址的地址,有一個洞。

0

可以檢測這樣的經由offsetof宏「洞」:

#include <stddef.h> 

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

如果這個打印多於1b顯然有對準要求,編譯器在生成之間的間隙。

很明顯,這發生在運行時,而不是編譯時,但您可以編寫一個腳本生成類似的源文件,在您的項目其餘部分之前編譯並運行它,然後根據輸出結果決定如何建立你的項目。

我不認爲任何編譯器提供了一種機制來通知你有關。

+0

有沒有辦法讓這個自動化? – John

+0

調查結構可能還不夠,在代碼中甚至在CFLAGS中都有對齊選項。你在說多少行代碼?這些結構可能是用來將數據存儲在文件中的嗎? –

+1

我的問題主要是學術性質,但我想測試幾百萬LOC。這些工具主要是CAD/CAE對象。 – John

0

在不分析源代碼的情況下找到這種漏洞的一種方法是,使用offsetof()等)來從對象/可執行文件/符號文件中提取符號/調試信息看看它們中定義的結構和成員,它們的偏移量和大小,看看是否所有東西都加起來了。不過,工會會讓事情變得複雜。

+0

所以我想沒有編譯器開關:)。然而,這對我來說很有意思(至少對我而言)。如果我想分析目標文件,我會從哪裏開始? – John

+0

@John:首先看看是否有任何工具可以讀取符號/調試信息並以某種人類可讀形式轉儲它。如果沒有,請查看哪些工具(您擁有源代碼)會使用這些數據並基於此開發您自己的數據。和往常一樣,請參閱有關文件格式的文檔。 –

+0

這就是'pahole'等人做的 –

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); 

*注意:您必須在您的卡每兩個成員這樣做。

1

金培爾的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 
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; 
}