отладчик для многопоточных приложений

yolki

пишу свой отладчик, есть проблема.
Win32DebugApi : CreateProcess(..DEBUG_ONLY_THIS_PROCESS..) WaitForDebugEvent, и т.п.
загружаю процесс, расставляю брейкпоинты и жду..
при срабатывании чуток подделываю код в районе брейка и продолжаем процесс.
для однопоточных приложений проблем нет.
есть проблемы для многопоточных. такое впечатление, что при возникновении брейка суспензится только тот тред, в котором сработал брейкпоинт. при подделывании кода рядом с брейком ломается соседний тред (который работает по тому же коду).
гугления по словам debugger и multithread дают статьи не про то как написать отладчик, а как использовать существующий..
подскажите, куда копать?

kokoc88

подскажите, куда копать?
Я не разрабатывал дебаггеры, но что если перечислить все потоки и вызвать SuspendThread? Кстати, в MSVS есть опция для блокировки всех или только одного потока. Попробуй, работает ли при этом редактирование кода на лету.
Возможно, после изменения кода, они просто заменяют указатель на функцию во всех местах, где она вызывается. Думаю, что такое решение не очень просто сделать.

ava3443

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

SetThreadPriority(GetCurrentThread THREAD_PRIORITY_TIME_CRITICAL);
HANDLE hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
DWORD ctid = GetCurrentThreadId;
DWORD cpid = GetCurrentProcessId;
if (hProcessSnap != INVALID_HANDLE_VALUE) {
THREADENTRY32 te32 = {0};
HANDLE th;
te32.dwSize = sizeof(THREADENTRY32);
if (Thread32First(m_hProcessSnap, &te32 {
do {
if te32.th32OwnerProcessID == cpid) && (te32.th32ThreadID != ctid {
if th = OpenThread(THREAD_SUSPEND_RESUME, FALSE, te32.th32ThreadID != NULL) {
SuspendThread(th);
CloseHandle(th);
}
}
} while(Thread32Next(hProcessSnap, &te32;
}
}

Serab

что если перечислить все потоки и вызвать SuspendThread?
это никак не приближает к решению задачи. Потому что race condition все равно возникает. Надо какой-то барьер придумывать по ситуации. Чтобы править точно то, что частично не выполнилось.

kokoc88

это никак не приближает к решению задачи. Потому что race condition все равно возникает. Надо какой-то барьер придумывать по ситуации. Чтобы править точно то, что частично не выполнилось.
Весь мой пост вполне приближает решение задачи. Кроме этого надо ещё понимать, что есть возможность проверить, какие потоки сейчас находятся в заданной функции.

Serab

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

Andbar

это никак не приближает к решению задачи
Прежде чем модифицировать, проанализировать контексты всех приостановленных потоков.

yolki

покурил отцов - в первую очередь John Robbins. посмотрел исходники WinDBG..
Там надо тоньше и аккуратнее делать. Будем стараться..

kokoc88

Там надо тоньше и аккуратнее делать.
Обычно в таком случае пишут, как именно надо делать. Дабы сохранить ответ в архиве и удовлетворить потребности страждущих.

yolki

лог из общений по аське.
КТ=контрольная точка = брейкпоинт.
(12:51:47) : пусть у нас стоят КТ на адресах А1 и А2. и есть два треда, которые идут мимо А1 и А2.
срабатывает А1, пациент приостанавливается, я устанавливаю трассировку для треда, который идёт мимо А1 и возобновляю пациента
пациент, возобновившись, продолжает не первый тред, а второй, который идёт мимо А2. там останавливается, я устанавливаю ему трассировку, возобновляю.
возобновляется А1, но адрес КТ у меня сохранён от А2. поэтому восстанавливаю я А2 и продолжаю выполнение. по адресу А1 остаётся огрызок инструкции, который и выполняется
(12:53:57) : проблема в том, что у меня сейчас отладчик может работать только с одной активной КТ
при срабатвании DebugEvent пациент суспензится полностью. все его треды приостанавливаются. который из них запустится после того, как его отпустит отладчик - неизвестно.
Оставить комментарий
Имя или ник:
Комментарий: