【问题标题】:Why C program compiled in Xcode has strange memory layout?为什么用 Xcode 编译的 C 程序有奇怪的内存布局?
【发布时间】:2020-11-04 10:56:24
【问题描述】:

我有以下 C 代码:

// test.c
#include <stdio.h>
#include <stdlib.h>

int main() {
  printf("location of code    : %p\n", (void *)main);
  void *heap = malloc(1);
  printf("location of heap    : %p\n", heap);
  int stack = 3;
  printf("location of stack   : %p\n", (void *)&stack);
  return 0;
}

我通过gccclang 编译这段代码:

gcc test.c -o test1
clang test.c -o test2

两个程序都按预期运行,输出如下内容:

location of code    : 0x101b95ec0
location of heap    : 0x7fecde5041c0
location of stack   : 0x7ffeee06a6b8

这表明,堆的起始位置更接近堆栈而不是代码。

但是,如果我使用 Xcode GUI 编译此代码,则输出类似于:

location of code    : 0x100000ec0
location of heap    : 0x100610b10
location of stack   : 0x7ffeefbff70c

我知道 Xcode 使用 clang 作为编译器,但输出令人困惑。 Xcode 会做一些事情来限制堆大小,还是做其他事情?

【问题讨论】:

  • &amp;stack 不是堆栈的开始,它是主函数堆栈帧中的局部变量的地址。这可能在任何地方,具体取决于命令行参数、环境变量和许多其他因素。然后是优化、调试标志、链接库等。这个比较有什么意义?
  • 还有地址空间布局随机化!
  • 这几乎肯定不是在 Xcode 中编译的结果,而是从 Xcode 运行它的结果。默认情况下,Xcode 在调试器下运行程序并故意改变某些行为。尝试更改方案设置以关闭调试器和所有其他诊断。

标签: c xcode memory-layout


【解决方案1】:

用函数调用修改它似乎是同样的问题。但是将堆大小增加到更大(10000000000 然后 100000000000 再增加一个零),您可能会注意到从 0xf... 变回 0x1... 仍然很奇怪。


#include <stdio.h> 
#include <stdlib.h>
#define HEAPSIZE 10000000000 // 100000000000 one more zero trigger 0x1 to 0x7


// https://www.geeksforgeeks.org/memory-layout-of-c-program/
// https://stackoverflow.com/questions/62906466/why-c-program-compiled-in-xcode-has-strange-memory-layout


//1
int global; /* Uninitialized variable stored in bss*/
int global2 = 10; 

void test1(int stack);

void test1(int stack){
    stack = 4;
    printf("location of stack      - %p and %d\n", (void *)&stack, stack);

}

void test2(int *stack);

void test2(int *stack){
    * stack = 4;
    printf("location of stack      - %p and %d\n", (void *)stack, *stack);

}

int main(void) 
{ 
    //2 
    static int i; /* Uninitialized static variable stored in bss */
    //3a
    static int j = 100; /* Initialized static variable stored in DS*/

    printf("location of global2    : %p\n", (void *)&global2);
    
    printf("location of static j   : %p\n", (void *)&j);
    
    printf("location of code       : %p\n", (void *)main);
    void *heap = malloc(HEAPSIZE * sizeof(int)); // malloc(1);
    printf("location of heap       : %p\n", heap);
    printf("location of heap end   : %p\n", heap + HEAPSIZE - 1);
    int var = 3;
    printf("location of var        : %p and %d\n", (void *)&var, var);

    test1(var);
    printf("location of test1(var) : %p and %d\n", (void *)&var, var);

    test2(&var);
    printf("location of test2(var) : %p and %d\n", (void *)&var, var);


    return 0; 

    // check size -xml M
} 

10000000000 例

location of global2    : 0x10ea54018
location of static j   : 0x10ea5401c
location of code       : 0x10ea52d40
location of heap       : 0x7fa29ac00000
location of heap end   : 0x7fa4eecbe3ff
location of var        : 0x7ffee11ada7c and 3
location of stack      - 0x7ffee11ada3c and 4
location of test1(var) : 0x7ffee11ada7c and 3
location of stack      - 0x7ffee11ada7c and 4
location of test2(var) : 0x7ffee11ada7c and 4

100000000000 例(多一个零)

location of global2    : 0x10cf8e018
location of static j   : 0x10cf8e01c
location of code       : 0x10cf8cd40
location of heap       : 0x115b3a000
location of heap end   : 0x185e2a87ff
location of var        : 0x7ffee2c73a7c and 3
location of stack      - 0x7ffee2c73a3c and 4
location of test1(var) : 0x7ffee2c73a7c and 3
location of stack      - 0x7ffee2c73a7c and 4
location of test2(var) : 0x7ffee2c73a7c and 4

你可能注意到函数变量(不使用指针的那个)仍然是 0x7ff...

尝试当行为是相同的变化。

但是额外 0 的变化不会触发 Xcode 的任何变化,并且总是 0x1....

Mac下docker ubuntu 20下试试 触发点是#define HEAPSIZE 10000 // 10000 0x5 // 100000 0x7

非常混乱。

root@4519bf65652d:/src/testxcode.c2# make m
cc -g -o M m.c 
root@4519bf65652d:/src/testxcode.c2# make mr
size -x ./M
   text    data     bss     dec     hex filename
  0x9e9   0x270    0x10    3177     c69 ./M
size ./M
   text    data     bss     dec     hex filename
   2537     624      16    3177     c69 ./M
./M
location of global2    : 0x5577dac6d010
location of static j   : 0x5577dac6d014
location of code       : 0x5577dac6a1f8
location of heap       : 0x7fa282247010
location of heap end   : 0x7fa28225f6af
location of var        : 0x7ffd1a9826dc and 3
location of stack      - 0x7ffd1a9826bc and 4
location of test1(var) : 0x7ffd1a9826dc and 3
location of stack      - 0x7ffd1a9826dc and 4
location of test2(var) : 0x7ffd1a9826dc and 4
root@4519bf65652d:/src/testxcode.c2# make m 
cc -g -o M m.c 
root@4519bf65652d:/src/testxcode.c2# make mr
size -x ./M
   text    data     bss     dec     hex filename
  0x9e9   0x270    0x10    3177     c69 ./M
size ./M
   text    data     bss     dec     hex filename
   2537     624      16    3177     c69 ./M
./M
location of global2    : 0x56297cec6010
location of static j   : 0x56297cec6014
location of code       : 0x56297cec31f8
location of heap       : 0x56297d9516b0
location of heap end   : 0x56297d953dbf
location of var        : 0x7ffe0bbaac8c and 3
location of stack      - 0x7ffe0bbaac6c and 4
location of test1(var) : 0x7ffe0bbaac8c and 3
location of stack      - 0x7ffe0bbaac8c and 4
location of test2(var) : 0x7ffe0bbaac8c and 4
root@4519bf65652d:/src/testxcode.c2# 

【讨论】:

    猜你喜欢
    • 2015-09-22
    • 1970-01-01
    • 1970-01-01
    • 2014-11-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-23
    相关资源
    最近更新 更多