首页 > 解决方案 > 论据腐败

问题描述

在某些生成的代码中将数据传递给某个函数时,我遇到了奇怪的行为。只要启用优化(-O1和更高版本),就会出现问题。但不上-O0

C 代码由OpenModelica 1.13.0-dev生成,并使用 gcc 4.4.7 在 Centos 6.9 32 位上编译。我知道我的设置有点旧,但我不能这样做。

我能够使用 gdb 进入代码以获取错误函数的回溯-O0

__OMC_DIV_SIM (threadData=0x83bb7e0, a=0.90000000000000002, b=1, msg=0xac4f6024 "PMECH1 - D * SLIP / 1.0 + SLIP", equationIndexes=0xbfffd4a0,
    noThrowDivZero=1 '\001', time_=0, initial_=1 '\001')

这是相同功能的回溯-O2

__OMC_DIV_SIM (threadData=0x83bb7a8, a=-9.2559642734470712e+61, b=5.298772688916812e-315, msg=0x1 <Address 0x1 out of bounds>,
    equationIndexes=0x3ff00000, noThrowDivZero=-60 '\304', time_=3.7134892271125328e-314, initial_=0 '\000')

所有研究Address 0x1 out of bounds都指向堆栈或内存损坏。然后我通过 valgrind 运行我的可执行文件。

==5351== Invalid read of size 1
==5351==    [...]
==5351==    by 0x7EA13F4: __OMC_DIV_SIM (division.h:66)
==5351==    [...]
==5351==  Address 0x1 is not stack'd, malloc'd or (recently) free'd
==5351==
==5351==
==5351== Process terminating with default action of signal 11 (SIGSEGV)
==5351==  Access not within mapped region at address 0x1
==5351==    [...]
==5351==    by 0x7EA13F4: __OMC_DIV_SIM (division.h:66)
==5351==    [...]
==5351==  If you believe this happened as a result of a stack
==5351==  overflow in your program's main thread (unlikely but
==5351==  possible), you can try to increase the size of the
==5351==  main thread stack using the --main-stacksize= flag.
==5351==  The main thread stack size used in this run was 8388608.

该代码不是那么有用,因为它不是供用户阅读的。我对其进行了一些修改以使其更具可读性并查明确切的问题。

    double value = 0.0;
    if ((long)data->localData[0]->integerVars[0] /* TRIPI */ == ((long) 0))
    {
            double PMECH1 = data->localData[0]->realVars[24];
            double D = data->simulationInfo->realParameter[21];
            double SLIP = data->localData[0]->realVars[4];
            double TELEC = data->localData[0]->realVars[35];
            double H = data->simulationInfo->realParameter[24];

            double div_1 = 0.0;
            {
                    double a = PMECH1 - ((D) * (SLIP));
                    double b = 1.0 + SLIP;

                    div_1 = __OMC_DIV_SIM(threadData, a, b, "PMECH1 - D * SLIP / 1.0 + SLIP", equationIndexes, data->simulationInfo->noThrowDivZero, data->localData[0]->timeValue, initial());
            }
            // ...
    }

然后这是包含的文件__OMC_DIV_SIM

#define DIVISION_SIM(a,b,msg,equation) (__OMC_DIV_SIM(threadData, a, b, msg, equationIndexes, data->simulationInfo->noThrowDivZero, data->localData[0]->timeValue, initial()))

int valid_number(double a)
{
  return !isnan(a) && !isinf(a);
}

static inline modelica_real __OMC_DIV_SIM(threadData_t *threadData, const modelica_real a, const modelica_real b, const char *msg, const int *equationIndexes, modelica_boolean noThrowDivZero, const modelica_real time_, const modelica_boolean initial_)
{
  modelica_real res;
  if(b != 0.0)
    res = a/b;
  else if(initial_ && a == 0.0)
    res = 0.0;
  else
    res = a / division_error_equation_time(threadData, a, b, msg, equationIndexes, time_, noThrowDivZero);

  if(!valid_number(res))
    throwStreamPrintWithEquationIndexes(threadData, equationIndexes, "division leads to inf or nan at time %g, (a=%g) / (b=%g), where divisor b is: %s", time_, a, b, msg);
  return res;
}

我无法使用不同的 gcc 测试该代码,但我能够使用相同的环境测试另一个组件,并且它顺利通过了。我仍然不知道是什么破坏了提供给__OMC_DIV_SIM. 它可能是编译器中的错误吗?还是在生成的代码中?

标签: clinuxcorruptiongcc4

解决方案


推荐阅读