全局变量在移植过程中跳转到函数时变为 null。

huangapple go评论108阅读模式
英文:

Global variable became null when jumping to a function during the porting process

问题

我正在尝试将在Linux上运行的程序移植到Windows上。这个程序是一个多线程程序,由于初始设计不够完善,许多全局变量散布在代码中。现在我遇到了一个非常棘手的问题:在跳转到某个函数时,一个未使用的全局变量被设置为0x0。

我在Linux上使用的编译器版本是gcc (GCC) 4.8.5 20150623 (Red Hat 4.8.5-44),而我在Windows 10上使用的编译器版本是gcc.exe (x86_64-win32-seh-rev2, Built by MinGW-W64 project) 12.2.0

通过检查内存内容,我发现这个全局变量的地址非常接近于跳转到的函数的地址(如下图所示):
查看图片描述

通过使用objdump命令检查可执行文件的段,内存布局如下(部分):
查看图片描述

我想知道这个问题的原因,并希望找到解决方法。

-----补充说明------

对不起,我的描述不是很清楚,这里有一个简化的示例:

// file1.h
extern struct ITEM *item;
void init();
// file1.c
struct ITEM *item;
void init() {
    item = (struct ITEM *) malloc(sizeof(struct ITEM));
    item->a = 1;
    item->b = 2;
    ...
}
// file2.h
void funcA() {
    // 从不使用item
    ...
}
// main.c
...
#include "file1.h"
#include "file2.h"
...

void main(void) {
    init();
    funcA();
}

在我调用init()函数之后,全局变量item被初始化并分配了一个值,但在调用funcA()函数时,在汇编中的call指令执行后,item指针变成了0x0

英文:

I am trying to port a program running on Linux to Windows. This program is a multi-threaded program, and due to the initial design not being perfect enough, many global variables are scattered throughout the code. Now I have encountered a very tricky problem: when jumping to a certain function, an unused global variable is set to 0x0.

The compiler version I'm using on Linux is gcc (GCC) 4.8.5 20150623 (Red Hat 4.8.5-44), while the compiler version I'm using on Windows 10 is gcc.exe (x86_64-win32-seh-rev2, Built by MinGW-W64 project) 12.2.0.

By examining the memory contents, I found that the address of this global variable is very close to the address of the function being jumped to (as shown in the figure below):
enter image description here
By using the objdump command to check the segment of the executable file, the layout of the memory is as follows(a part of):
enter image description here
I want to know the reason for this problem and hope to find a solution.

-----ADDITION------

Sorry, my description is not very clear, and here's a simplified example:

// file1.h
extern struct ITEM *item;
void init();
// file1.c
struct ITEM *item;
void init() {
    item = (struct ITEM *) malloc(sizeof(struct ITEM));
    item->a = 1;
    item->b = 2;
    ...
}
// file2.h
void funcA() {
    // never use item
  ...
}
// main.c
...
#include "file1.h"
#include "file2.h"
...

void main(void) {
    init();
    funcA();
}

After I call the init() function, the global variable item is initialized and assigned a value, but when calling the funcA() function, after the call instruction in assembly is executed, the item pointer becomes 0x0

答案1

得分: 2

> 在跳转到某个函数时,一个未使用的全局变量被设置为0x0。

"全局变量" - 具有 文件作用域 的变量,除非程序员明确初始化为其他值,否则始终会初始化为零,因为它们具有 静态存储期。您的程序表现如预期 - 所以似乎出现问题的是您的期望,而不是程序行为。

来源:C17 5.1.2 和 6.7.9 §10。

英文:

> when jumping to a certain function, an unused global variable is set to 0x0.

"Global variables" - variables with file scope, are always initialized to zero unless explicitly initialized to something else by the programmer, since they have static storage duration. Your program behaves as expected - so what's wrong appears to be your expectations, not the program behavior.

Sources: C17 5.1.2 and 6.7.9 §10.

huangapple
  • 本文由 发表于 2023年6月22日 15:41:05
  • 转载请务必保留本文链接:https://go.coder-hub.com/76529595.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定