Отладка большого двойного массива - PullRequest
0 голосов
/ 12 января 2010

Я использую библиотеку C ++, которая предоставляет объект, который для простоты более или менее похож на это:

class ExampleSO {
    public double* narray;
};

У меня есть экземпляр ExampleSO, у которого narray около 200. Другой метод ExampleSO::method() выполняет множество арифметических функций с этим массивом и назначает его различным элементам массива:

ExampleSO::method() {
     // a lot of operations
     narray[50] = narray[1] * narray[2] / narray[40];
     // and so on

Этот код сгенерирован другой программой и использует набор определений для обработки элементов массива, поэтому код выглядит следующим образом:

#define A narray[0]
#define X narray[1]
#define Y narray[2]
// ...
#define Z narray[40]
// ....
#define U narray[50]
// ... more, until narray[199]
ExampleSO::method() {
     // a lot of operations
     U = X * Y / Z;
     // and so on
}

Моя проблема в том, что в конечном итоге некоторые элементы массива становятся NaN, и я пытаюсь отладить код, чтобы понять, почему. Я уже обнаружил некоторые из них, которые в основном вызваны делением на ноль, другие - возведением в степень очень маленькими числами (маленькими, например, между 0 и +/- 0,1).

С моим небольшим знанием магии GDB мне удалось увидеть элементы массива по display *(this->narray) @ 200, но этот массив очень большой и, следовательно, нечитаемый.

Так что отладка этого фрагмента кода оказалась непростой задачей, потому что #defines скрывает мне положение элемента, массив слишком велик и потому, что так много элементов становятся NaN, я теряюсь.

Мой вопрос: какие идеи / предложения у вас есть, чтобы помочь мне отладить этот код? Возможно, была бы полезна условная точка останова, когда первый элемент массива становится NaN? Как я мог сделать это с такой структурой?

Спасибо!

Ответы [ 3 ]

4 голосов
/ 12 января 2010
  1. Перепишите его. Структура, которую вы описываете, ужасна за пределами описания.
  2. Напишите скрипт на python, чтобы превратить #defines в псевдонимы переменных gdb, чтобы вы могли ссылаться на них символически.
  3. Использовать синтаксис массива в gdb: p narray[12]
  4. Добавьте некоторые вспомогательные функции отладки и вызовите их из отладчика: p printMyFavoriteValues(narray)
  5. Узнайте, как включить сигнальные NaN. В Windows и Mac он отличается от Linux.


#ifdef DARWIN
    _mm_setcsr( _MM_MASK_MASK &~
              (_MM_MASK_OVERFLOW|_MM_MASK_INVALID|_MM_MASK_DIV_ZERO) );
#else
    feenableexcept(FE_DIVBYZERO | FE_UNDERFLOW | FE_OVERFLOW | FE_INVALID);
#endif
1 голос
/ 12 января 2010

Что касается определений, вы можете запустить файл через препроцессор, а затем скомпилировать и отладить сам предварительно обработанный файл.

Макросы X, Y, Z будут разрешены таким образом, и вы увидите фактический индекс. Как вызвать сам препроцессор, зависит от вашего компилятора. Для gcc это команда cpp Документация .

Что касается выяснения, когда назначается NaN, должен быть переключатель компилятора, который заставит программу выдать исключение, когда это произойдет.

0 голосов
/ 12 января 2010

Если вам нужно отладить большой объем кода, сгенерированного вызовами макросов, и вы не можете выполнить рефакторинг для удаления макросов, один из вариантов - временно обработать файл, скопировать код, созданный макросами, и вставить его в макрос звонки. После этого вы сможете скомпилировать уже предварительно обработанный код и правильно выполнить отладку. Когда вы закончите, просто верните код.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...