LINUX.ORG.RU

Поведение многопоточной программы под отладчиком

 ,


0

1

Подскажите, какие есть особенности при работе под отладчиком. Пытаюсь выносить некоторые вычисления во второй поток - падает. Лезу gdb посмотреть (без бряков, просто по стеку полазить когда упадёт) - вуаля! Работает! Как так? gdb как-то синхронизирует потоки?

★★★★★

Последнее исправление: eagleivg (всего исправлений: 1)

Пытаюсь выносить некоторые вычисления во второй поток - падает

Надо бы немного подробностей накинуть. Падать может по многим причинам. Кусок кода хоть кинь. Или псевдокода примерно как и что ты делаешь.

deep-purple ★★★★★
()

Поведение многопоточной программы (особенно при наличии ошибок) может различаться по множеству причин. Иногда вместо отладчика (ну или вместе) может пригодиться valgrind. Возможно покажет не только стек вызовов при падении, но и потенциально опасные места.

Elyas ★★★★★
()

если в gdb у вас не падает - то скорее всего у вас где-то происходит одновременный доступ к ресурсам - думаю копать надо туда

Silerus ★★★★
()

https://sourceware.org/gdb/current/onlinedocs/gdb/Thread-Stops.html#Thread-Stops

There are two modes of controlling execution of your program within the debugger. In the default mode, referred to as all-stop mode, when any thread in your program stops (for example, at a breakpoint or while being stepped), all other threads in the program are also stopped by GDB. On some targets, GDB also supports non-stop mode, in which other threads can continue to run freely while you examine the stopped thread in the debugger. 

Для отладки можно попробовать использовать thread-sanitizer.

xaizek ★★★★★
()

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

alysnix ★★★
()
Ответ на: комментарий от xaizek

Читал, но в том-то и прикол, что я ещё ничего не останавливал. Просто под отладчиком потоки не наступают друг другу на хвост. Вот и интересно, что приводит к такому поведению.

А так да, тред санитайзер наверное поможет.

eagleivg ★★★★★
() автор топика

Такое и с однопоточными бывает, сижка же.

ПоджаренныйБекон

stasolog
()

Дык если падает - смотри корку, нафиг воспроизводить ещё раз.

Про запуск под отладкой - @xaizek верно отписал, там есть варианты как фризятся потоки на тех же бряках, либо все, либо только поток в котором бряка сработала.

pon4ik ★★★★★
()

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

alysnix ★★★
()
Ответ на: комментарий от eagleivg

Как вариант ещё hellgrind, хотя, может уже и нет сценариев где он найдёт проблему вернее чем санитайзер.

pon4ik ★★★★★
()

Всегда использовала абстракции типа для работы с потоками. Отладчик ни разу не был нужен.

Lzzz
()
Ответ на: комментарий от Lzzz

абстракции типа для работы с потоками

что ж это за абстракции типа? поток уже сам по себе абстракция, ибо унутре себя есть переключение исполнения на след. поток с восстановлением контекста - то бишь всех регистров.

alysnix ★★★
()
Ответ на: комментарий от pon4ik

нафиг воспроизводить ещё раз

О, кстати, может ТСу rr пригодится. Хотя как он обрабатывает потоки я не знаю.

xaizek ★★★★★
()
Ответ на: комментарий от alysnix

Это нас так учили. Есть абстрактный тип ActiveObject, ты от него наследуешься и переопределяешь метод run(), в котором и будет твоя задача запущена на отдельной нити. Плюс получаешь доп. возможностей типа пула нитей. Ручное создание потоков через std::thread чреват массой ошибок.

Lzzz
()
Ответ на: комментарий от Lzzz

Есть абстрактный тип ActiveObject, ты от него наследуешься и переопределяешь метод run()

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

alysnix ★★★
()
Ответ на: комментарий от Lzzz

Не, если пишешь с нуля, то не вопрос. А вот когда пытаешься параллелить то, что написано давно, и в основном как однопоток…

eagleivg ★★★★★
() автор топика

У тебя где-то в программе состояния гонки. Отладчик меняет тайминги, и вот оно «работает», потому то что раньше происходило примерно в одно время, теперь по времени разнесено.

i-rinat ★★★★★
()
Ответ на: комментарий от xaizek

Хорошо отрабатывает, если гонку словил, то так же её и воспроизведёшь.

pon4ik ★★★★★
()
Ответ на: комментарий от Lzzz

Согласен. Достаточно просто не писать багов, и все получится.

Siborgium ★★★★★
()

Скорей всего data race где-то выскочил. Под gdb потоки успевают «разойтись» во времени, в реале - нет. valgrind –tool=helgrind(=DRD) иногда помогает.

SkyMaverick ★★★★★
()
Ответ на: комментарий от i-rinat

а когда работает - не трожь, как говорит известная мудрость…

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.