Re[7]: Самый хитрый баг
От: adontz Грузия http://adontz.wordpress.com/
Дата: 29.03.06 13:30
Оценка:
Здравствуйте, Tom, Вы писали:

A>>А много ноликов? Может проще найти места где пишется много ноликов? Все ZeroMemory для начала?

Tom>Нереально, обьём кода огромный, да и написан при помощи spagetti style

Нет, просто пусть ZeroMemory не только обнуляет память но и журналирует адрес/размер облулённого участка. Учитывая что это макрос, "перехватить" его можно простым #define.
A journey of a thousand miles must begin with a single step © Lau Tsu
Re[8]: Самый хитрый баг
От: Plutonia Experiment Беларусь http://blogs.rsdn.org/ikemefula
Дата: 29.03.06 13:37
Оценка:
Здравствуйте, adontz, Вы писали:

A>Здравствуйте, Tom, Вы писали:


A>>>А много ноликов? Может проще найти места где пишется много ноликов? Все ZeroMemory для начала?

Tom>>Нереально, обьём кода огромный, да и написан при помощи spagetti style

A>Нет, просто пусть ZeroMemory не только обнуляет память но и журналирует адрес/размер облулённого участка. Учитывая что это макрос, "перехватить" его можно простым #define.


Простого дефайна скорее всего не хватит, потому как эта функция(на самом деле это макрос) может вызыватся откуда угодно.
Re[9]: Самый хитрый баг
От: adontz Грузия http://adontz.wordpress.com/
Дата: 29.03.06 13:47
Оценка:
Здравствуйте, Plutonia Experiment, Вы писали:

PE>Простого дефайна скорее всего не хватит, потому как эта функция(на самом деле это макрос) может вызыватся откуда угодно.


Ну, во-первых, можно ключик /D компилятора использовать, а, во-вторых, ради такого и windows.h подправить не жалко.
A journey of a thousand miles must begin with a single step © Lau Tsu
Re[10]: Самый хитрый баг
От: Plutonia Experiment Беларусь http://blogs.rsdn.org/ikemefula
Дата: 29.03.06 13:54
Оценка:
Здравствуйте, adontz, Вы писали:

A>Здравствуйте, Plutonia Experiment, Вы писали:


PE>>Простого дефайна скорее всего не хватит, потому как эта функция(на самом деле это макрос) может вызыватся откуда угодно.


A>Ну, во-первых, можно ключик /D компилятора использовать, а, во-вторых, ради такого и windows.h подправить не жалко.


Это то же самое что и дефайн и этого мало.
Re: Самый хитрый баг
От: McQwerty Россия  
Дата: 29.03.06 14:38
Оценка:
Здравствуйте, Tom, Вы писали:

Tom>Уж незнаю в какой этот форум, модераторы если что поправят.


Tom>Опишу ситуацию, есть некоторое распределённое/клиент серверное приложение, и живёт в нём хитрый и злой мега баг. Хитрый мега баг проявляется тем, что иногда срёт в чужую память нулями (любя мы называем его засранцем ). А хитрый и злой он потому, что мы только видим его последствия — испорченная память, и НИКОГДА не видим кто именно какает. В приложении при каждом системном исключении создаются дампы памяти, так что мы контролируем каждый AV (создаём дампы внутри Vectored Exceptions Handler-а). Много гоняли под Application Verifier, не очень много под Dev Partner-ом, под Dev Partner-ом не можем сильно гонять, так как он убивает всю производительность. Собсно нужны какие то принципиальные идеи как его может быть и как енту каку выловить.


А можно подробности. А то я тут две недели ловил схожэий баг (правдо, "везло" не КОМу).
Дело было в связке. многопоточность + stl от 6-й стидии (дело было под виндой).
Если окружение схожее — свисти, расскажу.
Re: Самый хитрый баг
От: rus blood Россия  
Дата: 29.03.06 14:58
Оценка:
Здравствуйте, Tom, Вы писали:

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

Например, из-за того, что где-то аргументы для форматирования строк неправильные?
Имею скафандр — готов путешествовать!
Re[2]: Самый хитрый баг
От: adontz Грузия http://adontz.wordpress.com/
Дата: 29.03.06 15:04
Оценка:
Здравствуйте, rus blood, Вы писали:

RB>Здравствуйте, Tom, Вы писали:


RB>Возможно, некая ошибка вызывает порчу стека и точек возврата из функций соответственно. После чего, код начинает "гулять" по произвольным местам... Поэтому, не можете заловить, кто это делает (может не раскручиваться стек функций или не вызываться какие-то catch-блоки).


Ого, гуляющий код, это круто! Я вообще склоняюсь к мысли, что надо всё переписать под .Net
P.S. Кажется я опять отнял чей-то хлеб
A journey of a thousand miles must begin with a single step © Lau Tsu
Re[3]: Самый хитрый баг
От: rus blood Россия  
Дата: 29.03.06 15:08
Оценка:
Здравствуйте, adontz, Вы писали:

A>Ого, гуляющий код, это круто! Я вообще склоняюсь к мысли, что надо всё переписать под .Net

A>P.S. Кажется я опять отнял чей-то хлеб

Поверь, буквально недавно такое наблюдал.
Можешь сам попробовать. Пример сделать несложно.
Имею скафандр — готов путешествовать!
Re[4]: Самый хитрый баг
От: Tom Россия http://www.RSDN.ru
Дата: 29.03.06 19:39
Оценка:
RB>Поверь, буквально недавно такое наблюдал.
RB>Можешь сам попробовать. Пример сделать несложно.

Ээээ а разве возможно порчей стека добиться того, что "Vectored Exceptions Handler" будет не вызываться? Мне кажется он к стеку совсем не относится...
... << RSDN@Home 1.1.4 beta 4 rev. 303>>
Народная мудрось
всем все никому ничего(с).
Re[5]: Самый хитрый баг
От: Andrew S Россия http://alchemy-lab.com
Дата: 29.03.06 21:14
Оценка:
RB>>Поверь, буквально недавно такое наблюдал.
RB>>Можешь сам попробовать. Пример сделать несложно.

Tom>Ээээ а разве возможно порчей стека добиться того, что "Vectored Exceptions Handler" будет не вызываться? Мне кажется он к стеку совсем не относится...


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

А вообще, конечно, если серьезно, самый лучший вариант в таких случаях — дихотомия. Как говорится, гильотина — лучее средство от головной боли. Располовинивать, пока не выявится хотя бы модуль, ответственный за баг. Впрочем, и этот метод часто не приносит никаких результатов. Сам недавно общался с таким проектом
http://www.rusyaz.ru/pr — стараемся писАть по-русски
Re: Самый хитрый баг
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 30.03.06 07:21
Оценка:
Здравствуйте, Tom, Вы писали:

Tom>Хитрый мега баг проявляется тем, что иногда срёт в чужую память нулями


Мне в свое время подобные глюки удалось свести практически к нулю таким вот комплексом мер:


Таким образом практически сразу ловятся всяческие недоинициализации и порчи, без контроля приводящие к отдаленным эффектам типа Вашего. Собственно, многое из этого есть в перечисленных сторонних тулзах, но мне было удобнее реализовать гибкий встроенный контроль, введя переменную для глубины контроля, чтобы понапрасну не тормозило.

Еще имеет смысл проверить функции на побочные эффекты. Я как-то около месяца не мог найти, отчего портились некоторые поля в двухпроцессорной конфигурации, но только в отладочной сборке — релиз работал безупречно. В итоге выяснилось, что IsBadWritePtr, который я на автомате пользовал еще с 16-разрядного кода, проверяет тупой перезаписью, и при отсутствии синхронизации может испортить данные, которые меняет параллельный поток.

Хотя заниматься всем перечисленным в спагетти-коде — врагу не пожелаю
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[5]: Самый хитрый баг
От: rus blood Россия  
Дата: 30.03.06 07:32
Оценка: 9 (2)
Здравствуйте, Tom, Вы писали:

Tom>Ээээ а разве возможно порчей стека добиться того, что "Vectored Exceptions Handler" будет не вызываться? Мне кажется он к стеку совсем не относится...


Ну представь, вызвался твой handler, а на выходе из него команда ret переносит исполнение кода не обратно в систему и на вызов следующего handler-а, а куда-то в [censored]. И другие handler-ы могут не вызываться...

Ну вот пример. На коленке и работает только под отладкой, но м.б. будет понятно, что я хочу сказать...
Если модификацию стека в VectoredHandler2 не делать, то вызываются оба хандлера.
Если испортить стек в VectoredHandler2, то можно сделать так, чтобы VectoredHandler1 не вызовется.

long WINAPI VectoredHandler1(PEXCEPTION_POINTERS pstEI)
{
    // не вызывается...
    return EXCEPTION_CONTINUE_SEARCH;
}

long WINAPI VectoredHandler2(PEXCEPTION_POINTERS pstEI)
{
    // Пример для отладки - типа меняем адрес возврата на мусор. 
    // В моем случае точка 0x00416B75 - вызов первой RemoveVectoredExceptionHandler в main.
    DWORD dw;
    __asm mov dw, ebp;
    dw += sizeof(DWORD);
    *(DWORD*)(void*)dw = 0x00416B75;

    return EXCEPTION_CONTINUE_SEARCH;
}

int _tmain(int argc, _TCHAR* argv[])
{
    void* p1 = AddVectoredExceptionHandler(1, VectoredHandler1);
    void* p2 = AddVectoredExceptionHandler(2, VectoredHandler2);

    __try
    {
        int x = 1;
        int y = 0;
        int z = x / y;
    }
    __except(EXCEPTION_EXECUTE_HANDLER)
    {
    }

    RemoveVectoredExceptionHandler(p1);
    RemoveVectoredExceptionHandler(p2);

    return 0;
}
Имею скафандр — готов путешествовать!
Re[6]: Самый хитрый баг
От: rus blood Россия  
Дата: 30.03.06 07:38
Оценка:
Здравствуйте, Andrew S, Вы писали:

AS>Порчей стека можно добиться теоретически чего угодно. Например, есть шанс, что стек попортится, сформировав валидный с\с++ компилятор + код драйвера, все это дело откомпилится, установится и будет писать нолики куда захочет. Вероятность подобного события оставляю посчитать вам



Ну я не про причину появления ноликов, а про то, что поймать не удается...
Да и вообще, м.б. где-то есть ошибка, не связананная с ноликами, а появление ноликов — результат перехвата этой ошибки.
Имею скафандр — готов путешествовать!
Re[4]: Самый хитрый баг
От: _devdi_  
Дата: 30.03.06 08:41
Оценка:
Здравствуйте, rus blood, Вы писали:

RB>Можешь сам попробовать. Пример сделать несложно.


Тема интересная. Не расскажешь по пунктам как такой примерчик сделать?
... << RSDN@Home 1.1.3 stable >>
Re[2]: Самый хитрый баг
От: Valery A. Boronin Россия linkedin.com/in/boronin
Дата: 30.03.06 15:11
Оценка:
Здравствуйте, Евгений Музыченко, Вы писали:

ЕМ>
ага и добавлю, что все это в настоящее время делает Driver Verifier & Application Verifier
Автор: Valery A. Boronin
Дата: 02.01.06
в ядре и user mode соотв.

так что городить все вышеприведенное имеет смысл на ОС раньше 2000, где еще такого счастья не было

да и App Verifier автору топика не помог, он сразу это написал

PS отмечу что подобные "свои" или стянутые у Руссиновича verifiers (MemAllocatePool and other MemXxx wrappers кто помнит) были практически у всех разработчиков в то время...
... << RSDN@Home 1.2.0 alpha rev. 648>>
Valery A. Boronin, RSDN Team, linkedin.com\in\boronin
R&D Mgmt & Security. AppSec & SDL. Data Protection and Systems Programming. FDE, DLP, Incident Management. Windows Filesystems and Drivers.
Re: Самый хитрый баг
От: Valery A. Boronin Россия linkedin.com/in/boronin
Дата: 30.03.06 15:11
Оценка: 9 (1)
Здравствуйте, Tom, Вы писали:

Tom>Опишу ситуацию, есть некоторое распределённое/клиент серверное приложение, и живёт в нём хитрый и злой мега баг. Хитрый мега баг проявляется тем, что иногда срёт в чужую память нулями (любя мы называем его засранцем ). А хитрый и злой он потому, что мы только видим его последствия — испорченная память, и НИКОГДА не видим кто именно какает. В приложении при каждом системном исключении создаются дампы памяти, так что мы контролируем каждый AV (создаём дампы внутри Vectored Exceptions Handler-а). Много гоняли под Application Verifier, не очень много под Dev Partner-ом, под Dev Partner-ом не можем сильно гонять, так как он убивает всю производительность. Собсно нужны какие то принципиальные идеи как его может быть и как енту каку выловить.


если известна область памяти которая затирается — если повезет и она одна и та же иногда, то есть решение

— подключите к машине отладчик удаленный (WinDbg + VM Ware сгодится)
— путем проигрывания проблемного сценария в виртуалке (чтобы шансы на воспроизведение были выше, лучше заснапшотить поближе к моменту падения и одно и тоже состояние проигрывать в надежде на те же адреса и т.п.), можно сделать так:
— сначала падаем и смотрим по какому адресу проблема, адрес-диапазон запоминаем
— перезапуск виртуалки и в отладчике ставим бряки на запись по этому адресу
— удим рыбу
... << RSDN@Home 1.2.0 alpha rev. 648>>
Valery A. Boronin, RSDN Team, linkedin.com\in\boronin
R&D Mgmt & Security. AppSec & SDL. Data Protection and Systems Programming. FDE, DLP, Incident Management. Windows Filesystems and Drivers.
Re[3]: Самый хитрый баг
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 30.03.06 15:41
Оценка:
Здравствуйте, Valery A. Boronin, Вы писали:

VAB>добавлю, что все это в настоящее время делает Driver Verifier & Application Verifier
Автор: Valery A. Boronin
Дата: 02.01.06
в ядре и user mode соотв.


Ага, щаз Их не иначе, как телепаты писали, и научили догадываться, как проверять целостность каждого объекта И статически размещенные объекты они тоже мусором прописывают, чтобы правильность инициализации в конструкторе проверить?

VAB>PS отмечу что подобные "свои" или стянутые у Руссиновича verifiers (MemAllocatePool and other MemXxx wrappers кто помнит) были практически у всех разработчиков в то время...


Только блоки памяти проверять — это меньшая часть заботы...
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re: Самый хитрый баг
От: Кирпа В.А. Украина  
Дата: 30.03.06 16:04
Оценка:
Здравствуйте, Tom, Вы писали:

Может поможет
Помню такую эпопею
Немодальный диалог созданый через new -> PostNcDestroy-> в нем delete this;
И в каком-то обработчике (сейчас хоть убей не помню толи WM_TIMER) без проверки на
::IsWindow(m_hWnd) модифицировалось int поле класса диалога уже после delete this;
Причем этот адрес был уже другим блоком (хотя не всегда)
Тоесть как ты говорищ какало в другие блоки
!0xDEAD
Re[2]: Самый хитрый баг
От: Danchik Украина  
Дата: 30.03.06 16:44
Оценка:
Здравствуйте, Valery A. Boronin, Вы писали:

[Skip]

VAB>если известна область памяти которая затирается — если повезет и она одна и та же иногда, то есть решение


VAB>- подключите к машине отладчик удаленный (WinDbg + VM Ware сгодится)

VAB>- путем проигрывания проблемного сценария в виртуалке (чтобы шансы на воспроизведение были выше, лучше заснапшотить поближе к моменту падения и одно и тоже состояние проигрывать в надежде на те же адреса и т.п.), можно сделать так:
VAB>- сначала падаем и смотрим по какому адресу проблема, адрес-диапазон запоминаем
VAB>- перезапуск виртуалки и в отладчике ставим бряки на запись по этому адресу
VAB>- удим рыбу

Могу предложить даже готовое решение как выловить такое место.
Есть такой продукт SmartHeap, который реализует скоростной менеджер кучи (подменяются все New, Alloc, etc.). В нем есть Debug DLL со множествами способов отладки таких ситуаций:

1. К каждому выделенному указателю присобачивается вначале и в конце дополнительные контрольные байты. Если их кто то перетер то через секунд 5 (настривается) выскакивает диалжг "Типа AAA указатель такой то был перетерт" — типа переполнение буфера, с дикой информацией Время выделения, CallStack выделения, Поток, иеще куча всего.

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

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

4. Может и не все вспомнил... Читайте что можна тут: HeapAgent. Если заинтересовало, могу для теста выслать (продукт совсем и даже очень не бесплатный)
Re[3]: Самый хитрый баг
От: Tom Россия http://www.RSDN.ru
Дата: 30.03.06 17:49
Оценка:
Здравствуйте, Danchik, Вы писали:

D>Здравствуйте, Valery A. Boronin, Вы писали:


D>[Skip]


VAB>>если известна область памяти которая затирается — если повезет и она одна и та же иногда, то есть решение


VAB>>- подключите к машине отладчик удаленный (WinDbg + VM Ware сгодится)

VAB>>- путем проигрывания проблемного сценария в виртуалке (чтобы шансы на воспроизведение были выше, лучше заснапшотить поближе к моменту падения и одно и тоже состояние проигрывать в надежде на те же адреса и т.п.), можно сделать так:
VAB>>- сначала падаем и смотрим по какому адресу проблема, адрес-диапазон запоминаем
VAB>>- перезапуск виртуалки и в отладчике ставим бряки на запись по этому адресу
VAB>>- удим рыбу

D>Могу предложить даже готовое решение как выловить такое место.

D>Есть такой продукт SmartHeap, который реализует скоростной менеджер кучи (подменяются все New, Alloc, etc.). В нем есть Debug DLL со множествами способов отладки таких ситуаций:

D>1. К каждому выделенному указателю присобачивается вначале и в конце дополнительные контрольные байты. Если их кто то перетер то через секунд 5 (настривается) выскакивает диалжг "Типа AAA указатель такой то был перетерт" — типа переполнение буфера, с дикой информацией Время выделения, CallStack выделения, Поток, иеще куча всего.


D>2. Некоторые указатели можна поставить на мониторинг, система буте следить что бы в них ничего не изменилось, случайно Работает по принципу чеканья области памяти на CRC через определенное время


D>3. DeferFree — интересная штука. Вы освобождаете указатель, но система не отдает его обратно в кучу, а держит его определенное время, забивает его специальными символами и следит что бы в него никто не записал.


D>4. Может и не все вспомнил... Читайте что можна тут: HeapAgent. Если заинтересовало, могу для теста выслать (продукт совсем и даже очень не бесплатный)


Если можно — вышли

PS:
А чем вышеописанные действия отличаются от того, что делает DevPartner? Просто с ним воспроизвести данный баг — нереально, из за огромного падения производительности
... << RSDN@Home 1.1.4 beta 4 rev. 303>>
Народная мудрось
всем все никому ничего(с).
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.