我在C语言中有一段代码,如下所示-
在.c文件中-
1 custom_data_type2 myFunction1(custom_data_type1 a, custom_data_type2 b)
2 {
3 int c=foo();
4 custom_data_type3 t;
5 check_for_ir_path();
6 ...
7 ...
8 }
9
10 custom_data_type4 myFunction2(custom_data_type3 c, const void* d)
11 {
12 custom_data_type4 e;
13 struct custom_data_type5 f;
14 check_for_ir_path();
15 ...
16 temp = myFunction1(...);
17 return temp;
18 }
在头文件中-
1 void CRASH_DUMP(int *i)
2 __attribute__((noinline));
3
4 #define INTRPT_FORCE_DUMMY_STACK 3
5
6 #define check_for_ir_path() { \
7 if (checkfunc1() && !checkfunc2()) { \
8 int temp = INTRPT_FORCE_DUMMY_STACK; \
9 ...
10 CRASH_DUMP(&sv);\
11 }\
12 }\
在未知情况下,发生崩溃。 在使用GDB处理核心转储后,我们得到了--p的调用栈
#0 0x00007ffa589d9619 in myFunction1 [...]
(custom_data_type1=0x8080808080808080, custom_data_type2=0x7ff9d77f76b8) at ../xxx/yyy/zzz.c:5
temp = 32761
t = <optimized out>
#1 0x00007ffa589d8f91 in myFunction2 [...]
(custom_data_type3=<optimized out>, d=0x7ff9d77f7748) at ../xxx/yyy/zzz.c:16
temp = 167937677
f = {
...
}
如果看到代码,则check_for_ir_path
和myFunction1()
都将调用myFunction2()
。
在check_for_ir_path
内,是否有一个类似-checkfunc1() && !checkfunc2()
的块。如果该检查评估为TRUE,则将触发SIGSEGV,并且有意使进程崩溃。并且只有在该条件通过时才声明变量temp
。
现在,如果您查看调用堆栈,即使在 StackFrame_1 中,您也可以看到显示的局部变量temp
。但是,它并未在函数myFunction2
中崩溃。这怎么可能?
如果我声明了另一个变量,请在语句int temp = INTRPT_FORCE_DUMMY_STACK;
之后说'int temp',这不会显示为 bt full
怎么可能呢?
答案 0 :(得分:4)
允许编译器以不改变程序结果的任何方式重新组织代码。因此,如果您写:
void foo()
{
if (something)
{
int sv;
...
}
}
允许编译器将其更改为以下内容:
void foo()
{
int sv;
if (something)
{
...
}
}
不管something
是对还是假。
但是编译器必须确保这将无法编译:
void foo()
{
if (something)
{
int sv;
...
}
sv = whatever; // Compiler error....
}