c - 论据腐败
问题描述
在某些生成的代码中将数据传递给某个函数时,我遇到了奇怪的行为。只要启用优化(-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
. 它可能是编译器中的错误吗?还是在生成的代码中?
解决方案
推荐阅读
- python - 导入自定义函数时出错
- powershell - 我正在尝试使用变量自动添加邮箱权限
- python-3.x - Sqlalchemy 在将更新放入 for 循环时给出数据库锁定错误
- android - 如何使 EditText 在 X 行后自动滚动
- javascript - 有没有一种简单的方法可以在 Javascript 中完全冻结对象及其子对象(Deep Freeze)?
- excel - 减少单元格中的换行数/chr(10)
- pandas - Pandas read_csv 错误分隔符识别
- jquery - 为什么我只能检查复选框?
- python-3.x - 使用 sklearn 的 Imputer 时如何解决 DeprecationWarning
- c# - 在 C# 中压缩多个类似的 if 语句