Створення мінідампа, блог
Час від часу, неважливо скільки зусиль витрачено на налагодження і тестування, програми все одно падає. Причому, падають не в тестовій середовищі або на комп'ютері розробника, а обов'язково у кінцевого користувача. При цьому непогано б дізнатися, з якого місця програми стався збій. Ось тут то на допомога і приходить Windows Debugging API, а точніше бібліотека Dbghlp, за допомогою якої можливе створення мінідампа.
Що таке мінідампа? Як правило, ті хто Новомосковскют це, вже знають що це таке, але все одно я повторюся :). Мінідампа це бінарний файл з інформацією про стан програми на певний момент часу, в нашому випадку на момент падіння. У нашому випадку в цьому мінідампа буде стан регістрів процесора, стек викликів у програмі призвів до її падіння, а також код помилки і причина падіння.
У DbgHlp є така чудова функція MiniDumpWriteDump. що дозволяє записувати дамп програми в файл. Далі, представлено готове рішення (код), що створює за допомогою цієї функції дамп програми. Код на чистому Сі, накакого C ++ (але зрозуміло в прогамма на C ++ цей код можна легко використовувати). Отже спочатку заголовки DebugHelplers.h):
А тепер реалізація DebugHelplers.c:
Зверніть увагу, в файлі реалізації, в рядку 1, підключається заголовки targetver.h - цей файл повинен містити визначення макросу PROGRAM_NAME. необхідного для формування імені файлу для дампа конкретної програми. Що я маю на увазі? Все не просто, а дуже просто - якщо у вас в рішенні (solution) є багато проектів (exe) в яких потрібно формувати дампи, зручно (щоб уникнути дублювання коду), винести все контекстно залежне (в нашому випадку ім'я конкретної програми) винести в файл відображає специфіку конкретного проекту, і потім підключати його в кожному проекті свій. Приклад такого файлу targetver.h для нашого випадку:
Даний код, при падінні програми (необробленому виключення), буде генерувати дамп в файл prg.exe.dmp. який буде записаний в той же каталог що і виконуваний файл. Як ви вже помітили, prg, визначається в targetver.h і зручно це визначення робити еквівалентним імені програми. Як це використовувати? Дуже просто, - ось приклад:
На самому початку функції main, необхідно встановити обробник (TopLevelFilter) на всі необроблені в програмі виключення. Робиться це за допомогою функції SetUnhandledExceptionFilter (визначена в Winbase.h). Зручно це робити тільки в остаточній (НЕ отладочной) версії програми (звідси умовна компіляція установки обробника), т. К. В налагоджувальної версії набагато краще щоб при необробленому виключення викликався відладчик, а не генерувався мінідампа.