Аргументы коррупции - PullRequest
       41

Аргументы коррупции

0 голосов
/ 24 апреля 2018

Я испытываю странное поведение, когда данные передаются определенной функции в некотором сгенерированном коде. Проблема возникает всякий раз, когда оптимизация включена (-O1 и выше). Но не на -O0.

Код C генерируется OpenModelica 1.13.0-dev и компилируется в 32,9 битах Centos 6.9 с использованием gcc 4.4.7. Я знаю, что мои настройки немного устарели, но я не могу поступить иначе.

Мне удалось войти в код с помощью 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. Может ли это быть ошибкой в ​​компиляторе? Или в сгенерированном коде?

...