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

Я отлаживаю некоторый JIT-код. Я присоединяю gdb к запущенному процессу. Я ищу способы установить точку останова (или любым другим способом), которая сделает gdb перерыв/паузу в каждом call instruction для конкретной функции. Я знаю имя функции.

Примечание. Я могу установить точку останова на взятой ветке для call instruction, т. е. gdb прерывается на функции, но я хочу, чтобы отладчик прервался перед тем, как взять эту ветвь, т. е. на call instruction.

Это возможно?

Спасибо


person abhi    schedule 25.12.2014    source источник
comment
Это очень сложно, граничащее с невозможным. Существует множество способов вызова функции, и они не всегда могут использовать инструкцию call, особенно если ваша функция находилась в хвостовой позиции. Если берется указатель функции на ваш JIT-код, он, вероятно, может быть вызван из любого места. И просто перечислить расположение call инструкций невозможно — возможно, они еще не были JIT-компилированы! Я хотел бы отметить, что, просто взглянув на адрес возврата, помещенный в стек call, вы можете найти своего вызывающего абонента (при условии, опять же, что оптимизации хвостового вызова не произошло) .   -  person Iwillnotexist Idonotexist    schedule 25.12.2014
comment
@IwillnotexistIdonotexist: Почему бы не сделать это ответом?   -  person alk    schedule 25.12.2014
comment
типичный метод - установить разрыв в начале функции (используя 'br имя_функции'), затем, когда код прерывается, используйте обратную трассировку (bt), чтобы отобразить, где/что вызвало эту функцию. Обратите внимание: не будет отображаться много полезной информации, если 1) исходный код не доступен, 2) код, скомпилированный (для gcc) с -g или -gdb, также лучше не использовать какую-либо оптимизацию, поэтому код и номера строк в исходниках будет линейка   -  person user3629249    schedule 25.12.2014


Ответы (1)


Я хочу, чтобы отладчик сломался, прежде чем перейти к этой ветке.

Но почему? Остановка перед выполнением ветки (в отличие от остановки сразу после) не дает вам абсолютно никакой дополнительной информации.

Как правильно заметил Iwillnotexist Idonotexist, существует много способов ВЫЗВАТЬ данную функцию, например.

CALL 0x8(%rax)
CALL %rbx
CALL *0x12345678

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

person Employed Russian    schedule 26.12.2014
comment
Спасибо за ответ. Можете ли вы также взглянуть на связанный вопрос, который я задал в другом посте, и внести свой вклад в него. Спасибо еще раз. stackoverflow.com/questions/27656270/ - person abhi; 26.12.2014