如果在调用堆栈中显示块,则内部变量,即使if语句未被评估为true

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如果在调用堆栈中显示块,则内部变量,即使if语句未被评估为true相关的知识,希望对你有一定的参考价值。

我在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处理核心转储后,我们得到如下的调用堆栈:

#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_pathmyFunction1()调用myFunction2()

check_for_ir_path内部,如果像checkfunc1() && !checkfunc2()这样的区块内有一个支票。如果该检查的计算结果为TRUE,则会触发SIGSEGV,并且该进程会故意崩溃。并且只有在条件通过时才声明变量temp

现在,如果查看调用堆栈,您可以看到甚至在StackFrame_1中显示的局部变量temp。然而它没有在功能myFunction2内崩溃。怎么可能这样呢?

如果我声明另一个变量,在声明int temp = INTRPT_FORCE_DUMMY_STACK;之后说'int temp',那就不会显示为bt full的一部分

怎么可能这样呢?

答案

允许编译器以任何不改变程序结果的方式重新组织代码。所以,如果你写:

void foo()
{
    if (something)
    {
        int sv;
        ...
    }
}

允许编译器将其更改为等效于:

void foo()
{
    int sv;
    if (something)
    {
        ...
    }
}

无论something是真还是假。

但编译器必须确保这将无法编译:

void foo()
{
    if (something)
    {
        int sv;
        ...
    }
    sv = whatever;  // Compiler error....
}

以上是关于如果在调用堆栈中显示块,则内部变量,即使if语句未被评估为true的主要内容,如果未能解决你的问题,请参考以下文章

在 if 语句块中使用 let 定义尚未定义的变量的替代方法是啥?

条件判断语句

Python流程控制语句

trycatchfinally详解,你不知道秘密

除非在 [重复] 之前打印条件,否则不会调用 if 语句

为啥在 bash if 语句中未设置的变量被评估为 0