Нужна помощь в поиске нелегальной записи.Валгринд не замечал этого - PullRequest
1 голос
/ 06 января 2012

У меня есть C-программа, которая попадает в цикл for, чего не должно быть, запуск ее с

valgrind --tool=memcheck --leak-check=yes a.out

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

спасибо заранее

вот этот цикл

int clockstate=0;
int clocklength=0;
int datalength=0;
int datastate=0;
int dataloc = 9;

((((some other code that i don't think is important to this part))))

int dataerr[13] = {0};
int clockerr[13] = {0};     // assumes that spill does not change within an event.
int spill=0;
int k = 0;

spill = Getspill(d+4*255+1);                // get spill bit from around the middle
//printf("got spill: %d \n", spill);            // third breakpoint
for( k = 0; k < 512; k++)
{
    // Discardheader(d);      // doesnt actually do anything, since it's a header.f
    int databit = Getexpecteddata(d+4*k+1);
    printf("%d ",k);
    int transmitted = Datasample(&datastate, &datalength, d+4*k+2,dataerr,dataloc, databit);
    printf("%d ",k);
    Clocksample(&clockstate, &clocklength, d+4*k+3,clockerr, transmitted); 
    printf("%d \n",k);
    // assuming only one error per event (implying the possibility of multi-error "errors"
    // we construct the final error at the very end of the (outside this loop)


}

и цикл повторяется после печати

254 254 254

255 255 255

256 256 1 <- это проблема </p>

2 2 2

3 33

edit **, поэтому я отследил, где это происходит, и в какой-то момент в

void Clocksample (int* state, int* length, char *d, int *type, int transbit);

у меня есть код, который говорит *length = 1;, поэтомукажется, что эта команда каким-то образом пишет на int k.Теперь мой вопрос: как это произошло, почему он не меняется length обратно на тот, который я хочу, и как мне это исправить.если вы хотите, я могу опубликовать весь код на Clocksample

Ответы [ 3 ]

2 голосов
/ 08 января 2012

Обратите внимание, что Valgrind является чрезвычайно слабым, когда дело доходит до обнаружения стек переполнения буфера (что, по-видимому, и происходит).

Google address-sanitizer намного лучше обнаруживает переполнение стека, и я предлагаю вам попробовать его вместо этого.

2 голосов
/ 06 января 2012

Как и в прошлый раз, что-то в одной из этих функций, Clocksample() на этот раз, записывает в память, которая не принадлежит данным / массивам, которые должна использовать функция. Скорее всего, запись в массив вне границ. Примечание: это не утечка памяти, которая выделяет, а затем теряет дорожку блоков памяти, которые должны быть освобождены.

Установите точку останова при вызове на Clocksample(), когда k равно 256. Затем перейдите к Clocksample(), сохраняя часы на k (или памяти, используемой k). Возможно, вы также можете просто установить аппаратную точку прерывания записи в память, выделенную для k. Как вы это сделаете, зависит от того, какой отладчик вы используете.

Теперь одношаговый (или просто запустить до возврата Clocksample(), если у вас установлена ​​аппаратная точка останова), и когда k изменится, у вас будет преступник.

1 голос
/ 06 января 2012

Таким образом, ваш вывод отладки показывает, что k изменяется во время вызова вашей функции Clocksample.Я вижу, что вы передаете адреса как минимум двух переменных, &clockstate и &clocklength в этот вызов.Мне кажется вполне вероятным, что в Clocksample имеется переполнение массива или какой-то другой дикий указатель, который в итоге перезаписывает область памяти, в которой хранится k.

Возможно, можно сузить ошибкуесли вы разместите код, где объявлено k (и любые другие переменные, объявленные поблизости в той же области видимости).Например, если clocklength объявлено прямо перед k, возможно, у вас есть ошибка в использовании значения указателя &clocklength, которое приводит к записи после конца clocklength и повреждению k.Но трудно знать наверняка, не имея фактического расположения переменных, которые вы используете.

valgrind не улавливает это, потому что, скажем, clocklength и k находятся рядом друг с другом наВ стеке valgrind не может определить, есть ли у вас совершенно правильный доступ к k или нет доступа с ошибкой после окончания clocklength, поскольку все, что он проверяет, - это то, к какой памяти вы фактически обращаетесь.

...