пятница, 9 декабря 2011 г.

PyKd: Boost.Python build cmd

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

::
:: Build x86/x64 Boost.Python library
::
call :ExecBjam 32
call :ExecBjam 64
pause
goto :EOF

::
:: Execute bjam.exe with required params
::
:ExecBjam
set arch=%1
set stagedir=stage

if "%arch%"=="64" set stagedir=stage64

bjam.exe ^
    -j 2 ^
    --toolset=msvc-9.0 ^
    release debug ^
    threading=multi link=static runtime-link=shared ^
    address-model=%arch% ^
    --with-python --with-date_time ^
    --stagedir=%stagedir% ^
    stage
goto :EOF

Краткое пояснение:
  • call :ExecBjam XX - сборка для i386 и amd64
  • -j N - задействовать N ядер
  • --toolset=msvc-9.0 - Visual Studio 2008
  • threading=multi - сборка с поддержкой многопоточности
  • --with-python - При сборке я предпочитаю использовать --with-libname вместо --without-libname, т.к. в этом случае будут скомпилированы только указанные библиотеки (что бы не собирать неиспользуемые библиотеки)
  • link=static - собрать статическую версию библиотек
  • runtime-link=shared - динамическая линковка с Visual C++ Runtime
  • --stagedir=stage%arch% - директория для выходных файлов (stage для x86 и stage64 для и x64)

вторник, 20 сентября 2011 г.

VMware + VirtualKD + WinDbg = Slow Snapshot Creation

Проблема

Запись снимка VM происходит очень долго (до 30 минут) если запущена отладочная сессия ядра.

Решение
  1. Закрыть отладчик.
  2. Сделать снимок.
  3. Запустить и подключить отладчик (Virtual Machine Monitor -> Run debugger).
Рабочая среда: VMware 6.x/7.x, WinDbg 6.12.0002.633, VirtualKD 2.5

воскресенье, 14 августа 2011 г.

FastStone Image Viewer


FastStone Image Viewer (FSViewer) - это бесплатная программа для просмотра, сортировки, конвертирования и редактирования изображений. Список возможностей весьма богат. Среди них, автоматический поворот изображения в соответствии с EXIF данными. Присутствует portable версия, обучающее руководство и онлайн-советы.

Программа имеет удобный и хорошо продуманный интерфейс. Автор регулярно исправляет найденные ошибки и добавляет новую функциональность.

На мой взгляд одна из лучших программ в своём классе!

пятница, 22 июля 2011 г.

MFC: Third Party Controls

Недавно потребовалось разработать GUI с помощью MFC (последний раз сталкивался около четырёх лет назад). Т.к. Microsoft, на мой взгляд, ничего особо не улучшила за это время, провёл поиск решений от независимых разработчиков. В результате, были найдены и апробированы такие классы:

  • CWndResizer - MFC/C++ Helper Class for Window Resizing
    Как видно из названия, класс предназначен для поддержки изменения размеров и положений контролов (кто сталкивался, тот знает насколько неудобно это делать силами MFC).

  • CGridListCtrlEx - Grid Control Based on CListCtrl
    Собственно, грид. Список возможностей впечатляет:
    - Сортировка
    - Навигация по ячейкам и поиск с помощью клавиатуры
    - Подсказки (Tooltips)
    - Скрытие и отображение столбцов
    - Редактирование ячеек
    - Раскраска строк и отдельных ячеек
    - Группировка
    - Копирование в буфер обмена
    - Сохранение ширины, расположения и видимости ячеек
    - Поддержка OLE Drag and Drop (включая переупорядочение элементов)

Результатом очень доволен. Спасбо авторам за их нелёгкий труд!

P.S. Дополнения списка приветствуются.

вторник, 5 июля 2011 г.

Visual Studio: Sort Build Output

Вопрос

Как упорядочить билд лог многопоточной сборки?
...
1>  queuedlock.c
2>  secedit.c
3>  sha.c
1>  ref.c
2>  support.c
...
Ответ
  • Если действие происходит на рабочей машине, в окне Output, выбрать Show output from: Build Order.

  • Если есть только копия лога (например, его прислали по почте), воспользоваться утилитой SortBuildOutput:
    1. Вставить содержимое лога в поле ввода.
    2. Нажать Sort.
    3. При необходимости, скопировать текст в буфер обмена.

четверг, 23 июня 2011 г.

Cmd: Detect 64-bit Windows

Windows 64-bit присутствует на рынке довольно давно, но несмотря на это, не перестаёт удивлять разнообразие методов (не всегда корректных) определения разрядности системы в cmd скриптах.

В качестве примера, рассмотрим популярные ответы на вопрос Detect Windows Server version 32/64-bit in CLI на сайте superuser.com:
  1. systeminfo | find /I "System type"
    
    Недостатки: Во первых, работает медленно. Во вторых, не будет работать если используется локаль отличная от английской. В третьих, необходимо дополнительно проводить разбор вывода.

  2. Arch=x86
    if exist "%ProgramFiles(x86)%" set Arch=x64
    
    Недостаток: Условие отработает некорректно если существует директория с таким именем. Редкий случай, но тем не менее возможный.

  3. reg.exe query "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion" | find "BuildLabEx"
    
    Недостаток: Необходим дополнительный разбор вывода.

  4. wmic OS get OSArchitecture
    
    Недостаток: Необходим дополнительный разбор вывода.

  5. set Arch=x64
    if "%PROCESSOR_ARCHITECTURE%" == "x86" ( 
        if not defined PROCESSOR_ARCHITEW6432 set Arch=x86
    )
    
    Недостатки: пока не обнаружены.
    Продолжительное время успешно использую данный метод. К тому же, при желании можно уточнить актуальную архитектуру: x86, amd64, ia64.
А какой способ используете Вы?

четверг, 16 июня 2011 г.

Cmd: reg.exe undocumented /reg switch

Задача

Из командного файла прочитать значение в реестре. В 64-х разрядной системе, в зависимости от условия читать из 32-х или 64-х битной ветки. Если используется 64-х битная версия cmd.exe, всё относительно просто: в зависимости от условия читать из HKLM\Software или HKLM\Software\Wow6432Node.

В 32-х битной версии командного интерпретатора (Post-Build Event в Visual Studio) этот способ не работает, т.к. запросы reg.exe перенаправляются подсистемой WOW64 в HKLM\Software\Wow6432Node.

Решение

Как подсказывает заголовок, reg.exe имеет недокументированный ключ /reg:. После двоеточия, без пробела, следует указать требуемую разрядность ("32" или "64"). Этот ключ работает в 32-х битной и 64-х битной версии утилиты, поэтому грамотно созданный командный файл будет корректно работать в интерпретаторе любой разрядности.

Пример использования (на всякий случай):
reg.exe query HKLM\Software\Python\PythonCore\2.6\InstallPath /ve /reg:64

Рабочая среда: Windows 7 x64

вторник, 7 июня 2011 г.

WinDbg: !error extension and locale

Проблема

WinDbg имеет весьма полезное расширение !error которое декодирует код ошибки и отображает соответствующее описание.

Но, порой, вместо описания можно увидеть ошибку <unable to get error code text> если отладка происходит в режиме пользователя:
0:000> !error 0xC000000D 1
Error code: (NTSTATUS) 0xc000000d - <unable to get error code text>
Так же, можно увидеть пустую строку или часть сообщения если запущена отладочная сессия ядра:
0: kd> !error 87
Error code: (Win32) 0x87 (135) -                              JOIN     SUBST          ,                          .
Последний вывод, кстати, наталкивает на мысль о том что проблема с локалью.

понедельник, 30 мая 2011 г.

Microsoft Certified Technology Specialist: Windows Internals

На днях сдал сертификационный экзамен 70-660: TS: Windows® Internals.

К экзамену не готовился. Во-первых, некогда; а, во-вторых, так даже интереснее. В итоге, набрал 783 балла из 1000 (необходимый минимум - 700).

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

Собственно, сертификат:

четверг, 26 мая 2011 г.

WinError.exe

Кому из разработчиков не доводилось расшифровать коды ошибок WINERROR или NTSTATUS?

Для быстрого получения вменяемого описания, я, как правило, пользовался поиском в заголовочных файлах:
  • %WDKPATH%\inc\api\ntstatus.h для NTSTATUS.
  • %WDKPATH%\inc\api\WINERROR.H для WINERROR.

Но есть более простой и удобный способ - использовать WinError.exe из набора WDK. Утилита отображает название констант(ы) для указанного кода ошибки. Кроме этого, она так-же показывает соответствие между кодом ошибки WINERROR и NTSTATUS.

Пример использования (если передаваемое значение представляет собой NTSTATUS, следует указать ключ -s):
%WDKPATH%\tools\Other\i386\WinError.exe -s 0xC000000D
    87 ERROR_INVALID_PARAMETER <--> c000000d STATUS_INVALID_PARAMETER

Updated 7.06.2011

А так же можно воспользоваться расширением !error из WinDbg (спасибо Volodymyr Pikhur за подсказку).

Схожие публикации

понедельник, 23 мая 2011 г.

Установка pykd (updated)

Начиная с версии 0.0.17, расширения pykd, был существенно переработан инсталлятор. Не смотря на то, что релиз состоялся более месяца тому, данная публикация не утратила своей актуальности.

Попав в раздел Downloads, главной страницы проекта, можно немного растеряться. Поэтому, приведу краткое описание возможных вариантов:
  • pykd-0.0.XX-python-2.6.zip - расширение без каких-либо дополнительных файлов. Для работы требуется Microsoft Visual C++ 2005 SP1 Redistributable Package и Python 2.6.
  • pykd_x86_0.0.0.XX_setup.exe - инсталлятор для 32-х битной версии WinDbg.
  • pykd_x64_0.0.0.XX_setup.exe - инсталлятор для 64-х битной версии WinDbg.
  • pykd-0.0.XX-python-2.7-vc90.zip - то же что и первый пункт, но для работы требуется Microsoft Visual C++ 2008 Redistributable Package и Python 2.7.

Расширение из архива устанавливается вручную.

Далее будет рассмотрено как это сделать с помощью инсталлятора.

Перед тем как продолжить, хочу обратить особое внимание на то что разрядность pykd, соответственно, Python, VC++ Runtime и инсталлятора должна соответствовать разрядности WinDbg. Например, Вы ставите 64-х битную версию расширения и у Вас уже стоит Python для x86. Расширение не будет работать если не установить соответствующую версию Python как предложит инсталлятор.

Возможности инсталлятора:
  • Собственно, установка расширения.
  • Установка скриптов и примеров (в директорию Мои документы\pykd).
  • Добавление пути к директории скриптов в PYTHONPATH. Что бы не вводить полный путь к нужному скрипту.
  • Добавление пути к расширению в PYTHONPATH. Для использования pykd из интерпретатора Python.
  • Проверка наличия Python-а и VC++ Runtime. При необходимости автоматическая загрузка и установка.
  • Запоминание директории установки расширения.
Возможности деинсталлятора:
  • Удаление расширения.
  • Опционально, удаление Python и VC++ Runtime.

суббота, 7 мая 2011 г.

Cmd: Backup/Clear/Restore environment variables

Публикация в первую очередь будет интересна тем, кто использует WDK/DDK для сборки чего-либо (например, драйверов). Но возможно пригодится ещё кому-то.

Проблема

При сборке из командной строки setenv.bat устанавливает переменные окружения таким образом что повторный вызов этого командного файла генерирует сообщение:
ERROR: This window already has the DDK build environment set.  Please open 
       a new window if you want to change or reset your build environment.
Как правило, для сборки под несколько платформ из одного командного файла нужно создавать дополнительные скрипты, что не всегда удобно.

Решение

пятница, 22 апреля 2011 г.

VeriSign "Signtool Error: The provided cross certificate would not be present in the certificate chain."

Проблема

Попытка подписать драйвер сертификатом от VeriSign и кросс-сертификатом от Microsoft:
%WDKPATH%\Bin\x86\signtool.exe sign /v /ac MSCV-VSClass3.cer /f cert.pfx /p password /t http://timestamp.verisign.com/scripts/timtamp.dll driver.sys
Не увенчалась успехом:
Signtool Error: The provided cross certificate would not be present in the certificate chain.
Алгоритм подписания рабочий и проверенный. Изучение базы знаний US Home > Support > Code Signing Support с ходу результата не дало.

Решение

понедельник, 18 апреля 2011 г.

#pragma message + __LINE__

Проблема

Необходимо вывести сообщение во время компиляции с указанием номера строки в исходном файле:
#pragma message(__FILE__ " (" __LINE__ "): Some important message.")
Данный код генерирует ошибку:
warning C4081: expected ')'; found 'constant'
Решение

Дело в том что __LINE__ имеет целочисленный тип, а данная директива принимает только строки. Для того что-бы всё работало как нужно, следует использовать следующий приём:
#define STRING2(x) #x
#define STRING(x) STRING2(x)

#pragma message(__FILE__ " (" STRING(__LINE__) "): Some important message.")

воскресенье, 17 апреля 2011 г.

PYTHONPATH в Windows x64

Проблема

Для удобства создания скриптов на Python-е, в т.ч. для pykd, решил воспользоваться расширением pytools для Visual Studio.

Чтобы интерпретатор Python-а находил модуль pykd без указания полного пути, добавил в переменную окружения PYTHONPATH путь к 64-х битной и 32-х битной версии расширения. В моём случае C:\WinDDK\WinDbgX64\winext и C:\WinDDK\WinDbgX86\winext соответственно. После этого интерпретатор начал падать при попытке использования модуля (похоже что происходит сбой во время загрузки pykd.pyd не соответствующей разрядности).

Вывод очевиден. Если в системе одновременно установлен Python для x86 и x64, то переменную окружения PYTHONPATH лучше не использовать.

Решение

воскресенье, 10 апреля 2011 г.

Отладка STL контейнера map в WinDbg

Проблема

Довольно часто во время отладки или анализа креш-дампов требуется узнать содержимое контейнера map. Насколько мне известно, WinDbg для этого не предоставляет никаких средств.

Решение

Решить задачу можно несколькими способами:
  • Зная внутреннюю структуру контейнера вручную найти необходимые смещения структур в памяти;
  • Создать своё расширение отладчика;
  • Воспользоваться возможностями расширения pykd.

воскресенье, 20 марта 2011 г.

Макросы с переменным количеством аргументов

Проблема

Есть набор макросов:
#define DBGPRINT(Level, Prefix, Fmt)  \
{                                     \
    if ((Level) >= gDbgLevel)    \
    {                                 \
        DbgPrint(DBGPRINT_PREFIX": %s", Prefix); \
        DbgPrint Fmt;                 \
    }                                 \
}

#define TERSE_FN(Fmt) DBGPRINT(DBG_LEVEL_TERSE, __FUNCTION__"(): ", Fmt)
Данные макросы позволяют выводить отладочную информацию в формате:
MyPrefix: FunctionName(): FormattedMessage
На первый взгляд всё нормально. Но если TERSE_FN вызывается из двух потоков:
Thread 1: TERSE_FN(("Important message with status: %x\n", status));
Thread 2: TERSE_FN(("Another important message with status: %x\n", status));
вывод может быть неконсистентным из за асинхронного использования DbgPrint:
MyPrefix: MyPrefix: Function2(): Another important message with status: 00000000
Function1(): Important message with status: 00000000
Решение

суббота, 19 марта 2011 г.

Установка pykd (Python WinDbg extension)

Данный пост посвящён установке pykd. Что такое pykd и как им пользоваться можно узнать на домашней странице проекта а так же из блога разработчиков.

Начиная с версии 0.0.17 был обновлён инсталлятор, актуальное описание процесса установки здесь.

Инсталлятор присутствует для 2-х платформ: x86 и x64. Разрядность pykd и инсталлятора должна соответствовать разрядности WinDbg. В качестве примера будет рассмотрена установка 64-х битной версии pykd.