Насколько медленна одноступенчатая функция отладки x86?

832
Brent Baccala

Архитектура x86 обеспечивает аппаратную одношаговую ловушку для отладки. На сколько это тормозит работающую программу?

Если, скажем, функция ядра Linux была создана, чтобы делать только один шаг процесса, насколько медленнее будет этот процесс? У кого-нибудь есть хорошая оценка?

Мне интересно это после того, как я провел неделю, выискивая ошибку в потоках. Было бы хорошо, если бы эти ошибки могли быть воспроизведены. Как насчет функции, которая выполняла два потока последовательно, чередуя выполнение команды в одном потоке и затем инструкции в другом, предсказуемым образом. Я имею в виду генератор псевдослучайных чисел, который будет генерировать строку битов - 0 означает выполнение инструкции в потоке 1, 1 означает выполнение инструкции в потоке 2.

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

Кто-нибудь слышал о чем-нибудь подобном?

Обновить:

Как это можно сделать?

Предположим, мы работаем на чем-то вроде Core i5, где у вас есть 4 состояния процессора и 2 ядра. Мы используем одношаговую ловушку для отскока процесса от его пользовательского пространства к его пространству ядра. Так что это два государства, верно? Тогда у нас есть другой поток, работающий на другом ядре с его пользовательским пространством и состояниями ядра, верно? Есть что-то вроде спин-блокировки (возможно, двух спин-блокировки), синхронизирующей два потока ядра. Каждый из них блокируется, в то время как другой выполняет несколько пользовательских инструкций, затем они синхронизируются и обмениваются ролями.

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

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

Все эти необычные вещи, которые делают эти новые фишки. Я был бы впечатлен и не совсем удивлен, если бы он бежал быстро.

3
Аппаратная одношаговая ловушка является функцией [архитектуры x86] (https://en.wikipedia.org/wiki/X86) и не относится к процессорам Intel. bwDraco 10 лет назад 0

2 ответа на вопрос

1
Jamie Hanrahan

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

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

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

Спасибо за ваш взгляд на доказуемый дизайн! Я не такой хороший программист. Я просто соединяю 15 000 строк путаницы из C, C ++, C ++ 11, потоковых примитивов Intel, смешанных с C ++ 11, встроенной сборки, всевозможных зависимостей GNU, и называю это [hoffman] (http: //freesoft.org/hoffman). Мне бы очень хотелось иметь инструмент отладки, как то, что я описываю! Brent Baccala 10 лет назад 0
Более серьезно, как я объяснил в обновлении к моему первоначальному посту, я не думаю, что трассировка / отладчик вообще должны быть задействованы. Требуется специализированный модуль ядра. Brent Baccala 10 лет назад 0
Инструмент отладки, который вы описываете, вовсе не плохая идея. Я просто говорю, что это не отличный способ попытаться найти, исправить или доказать несуществующие ошибки сериализации. Jamie Hanrahan 10 лет назад 0
... это если бы он работал на нормальной скорости. Как таковое, замедление вполне может маскировать проблемы сериализации. (Или это может вывести их ...) Jamie Hanrahan 10 лет назад 1
0
Roland Pihlakas

Ваш подход кажется полезным, и я задумался о подобной проблеме.
Как это может быть сделано? (Есть также несколько альтернативных способов, в том числе статический анализ или рефлексия и сопрограммы) .
Но ваш метод может быть значительно оптимизирован двумя альтернативными способами на случай, если вы случайно перейдете к нескольким инструкциям (возможно, даже ко многим инструкциям, что также кажется естественным):

1) Определите случайную длину следующей последовательности команд перед началом последовательности. Используйте дизассемблер и поместите int 3 в конце последовательности вместо одного шага.

2) Если вы по какой-то причине не хотите использовать int 3 или не полностью доверяете своему дизассемблеру, вы можете использовать один шаг, а затем скопировать выполненные инструкции в новую область памяти.
Теперь в следующий раз, когда генератор случайных чисел решит выполнить такое же количество последовательных шагов, начиная с той же позиции программы, просто перейдите в новую область памяти, содержащую скопированные инструкции, и продолжайте работу до конца этой последовательности без единого шага. В конце последовательности команд вам необходимо перезвонить в вашу среду отладки.

Для обоих подходов вам нужно добавить специальную обработку для вызовов, переходов и условных переходов.