Я новичок в GDB и не уверен, что кто-то из вас испытал: когда я использовал GDB для отладки программы с двумя потоками, я нашел выполнение шаговой линии на линия не является линейной или непредсказуема даже для одного потока, а распечатанное значение переменной также запутывает. Скажем, у меня есть программа (в C++) выглядит так:GDB Отладка многопоточности, выполнение непредсказуемо для одиночного потока
(Я отлаживаю командную строку ubuntu, используя режим gdb -tui
).
.....
70 for (int i = 0; i < MAX; i++) {
71 int foo = 1;
b+ 72 Bar *bar = f1();
73 int v1 = bar->doCalc();
74 int v2 = bar->get(foo);
75 }
.....
В начале, программа остановилась на line 72
, то я ступил построчно, пока она не достигнет line 74
. В этот момент я распечатал значение v1
, но, похоже, эта переменная все еще не имеет значимого значения. Затем, если я наберу «следующий», выполнение программы снова вернется к line 72
!! Это первое, что вызвало мое замешательство. Затем я продолжаю переход к следующей строке, пока не достигнет line 74
. В этот момент я распечатал v1
, и на этот раз он имеет какое-то значимое значение. Я дважды проверил итератор i
, его значение одно и то же, что означает, что оно находится в одном и том же i-м выполнении одного цикла. Я смущен, как это может произойти? Может ли кто-нибудь помочь мне? Спасибо!
Вы оптимизировали оптимизацию компилятора, да? –
При отладке многопоточных приложений часто лучше постоянно устанавливать точки останова на следующей строке, а не пытаться делать одношаговые. Одноступенчатый часто приводит к тому, что «следующий шаг» переходит к несвязанному коду, поскольку код, который вы использовали, делает syscall. Конечно, если у вас несколько потоков, работающих по одному и тому же коду, это еще более запутанно - команда с одним шагом иногда заставляет казаться, что код бежит назад :) –
Это кажется очень мало связанным с несколькими потоками, и все, что связано с компилятором оптимизаций. Для начала 'foo' фактически не нужно быть переменной; 'i' может быть полностью оптимизирован (или может обновляться только каждые итераций из-за разворачивания). Переменные назначения не должны быть в порядке; 'v1' и' v2' фактически не должны существовать или быть назначены вообще! –