Отслеживание того, какая зависимость содержит инструкции SSE

#c #visual-c #sse

#c #visual-c #sse

Вопрос:

Одному из наших клиентов требуется сборка нашей программы без SSE, поскольку он работает на довольно старом оборудовании. Моя проблема в том, что даже если я изменю настройки нашего проекта по всем направлениям, чтобы отключить SSE для всех библиотек и двоичных файлов, может показаться, что где-то все еще существует зависимость, которая скомпилирована с инструкциями SSE, что приводит к сбою приложения.

Мои вопросы: Есть ли способ взять двоичный файл или библиотеку и определить, содержит ли он инструкции SSE определенной версии SSE или нет?

Мы используем VS, а язык — C , поэтому любой инструмент, применимый к этому набору инструментов, был бы потрясающим.

Комментарии:

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

2. Мы статически связываемся со всеми нашими библиотеками, вероятно, следовало упомянуть об этом.

3. вы все равно должны упомянуть об этом, отредактировав его в своем вопросе.

4. А как насчет библиотек, которые проверяют доступность кода операции перед их использованием? Простая проверка наличия инструкций SSE приведет к их ошибочному отображению.

Ответ №1:

Разберите все задействованные двоичные файлы, затем выполните поиск мнемоники инструкций SSE в дизассембликах.

Комментарии:

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

2. Командная строка и хорошая оболочка — ваши друзья. В среде Unix вы могли бы сделать это с помощью ‘for f в LIST_OF_BINARIES; do objdump -d $ f > $ f.S ; done; grep -e SSE_MENOMONIC_REGEXP *.S’

3. VS не запускается в Unix. В Windows это было бы for %f in (*.obj) do dumpbin /disasm:nobytes %f >> disasm.txt . Трудно найти инструкцию SSE с помощью regexp; именование не согласовано.

4. Не проще ли использовать grep для регистров? для любой инструкции SSE потребуется регистр xmm.

5. Скрипт для анализа используемых расширений процессора — использует perl objdump и некоторый другой мусор unix, но в нем есть хороший список мнемоник команд, на которые стоит обратить внимание.

Ответ №2:

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

  1. Разберите .файлы lib или .obj, на которые вы ссылаетесь. На самом деле это не простое решение, если у вас нет доступа к специализированным инструментам. Как правило, дизассемблирование — это очень сложный процесс, поскольку инструмент должен вычислять все пути выполнения в коде, фактически не запуская его. Это делается для отделения данных от кода. Лучшим инструментом для таких задач является IDA Pro. После разборки вы можете выполнить поиск инструкций SSE, либо написав макрос внутри IDA Pro, либо экспортировав результаты в текстовые файлы и просто используя grep.
  2. Более простой подход заключается в запуске программы и выяснении, где происходит сбой. Для продолжения вам понадобятся две вещи: выяснить адрес инструкции, которая вызывает сбой, и «файл карты», чтобы выяснить, к чему он принадлежит. Последнее просто: в Visual Studio вам нужно установить параметры отладки компилятора И компоновщика для создания файла карты. Этот файл в основном сообщит вам адрес всех функций в исполняемом файле. Найти адрес сбоя обычно несложно, поскольку Windows выдаст вам запрос и сообщит что-то вроде Ошибка приложения В инструкции «0x635de077» …. Вы используете этот адрес и просматриваете файл map, чтобы увидеть, к какой функции он относится. В качестве альтернативы вы можете запустить программу внутри отладчика. При сбое программы отладчик показывает вам, где программа остановилась.

редактировать: Другой метод для получения дизассемблирования a .для создания lib-файлов используется утилита DUMPBIN, которая поставляется с Visual Studio. Кроме того, метод minidump, предложенный STATUS_ACCESS_DENIED, является отличной идеей.

Комментарии:

1. Я большой поклонник (и клиент) IDA Pro, но я думаю, что это перебор для текущей задачи. Подойдет любая наполовину сложная библиотека сборщика. Также мне больше нравится ваш второй подход, поскольку он даст более точный результат за меньшее время. 1 за это.

2. На самом деле, чтобы добавить к пункту 2: также было бы возможно взять мини-дамп при сбое (даже на сайте клиента), а затем проанализировать мини-дамп, чтобы увидеть это. Т.е. post-mortem, который лучше подходит.

3. Да, первое решение действительно излишне. Я только что упомянул об этом, поскольку другой ответ просто кратко предложил это. Хотя у IDA Pro раньше была бесплатная версия, этого могло бы быть достаточно для этой задачи. В общем, программистам, имеющим дело с низкоуровневым кодом, полезно привыкнуть смотреть на дизассемблирование своего кода.

4. Мини-дамп — отличная идея. Он, вероятно, не хотел бы просить клиента запускать отладчик! Тем не менее, возможно, клиенту достаточно сделать скриншот с диалоговым окном сбоя Windows.

5. @AlefSin: у них все еще есть бесплатная версия. Текущая бесплатная версия — 5.0. Однако раньше она разбирала только 32-битные PE-файлы. Не уверен, что он также обрабатывает файлы LIB / COFF.

Ответ №3:

Используйте метод, как описано здесь, чтобы получить файл мини-дампа от клиента. Т.е. попросите клиента запустить вашу сборку. После сбоя должен быть создан файл мини-дампа, который вы можете использовать — post-mortem — для точного анализа того, где произошел сбой. Который вместе с символами отладки (и / или файлом карты) фактически укажет вам точную библиотеку, которая вызвала хаос.

Это сводится к пункту 2 в решении, предложенном AlefSin. Однако клиенту не придется запускать отладчик. Для драйверов режима ядра это обычно даже единственный способ получить значимую информацию о проблемах. Однако для кода пользовательского режима существует такая же возможность. Используйте это.