Получение EBP потока в другом процессе

Мне было интересно, есть ли способ получить EBP потока в другом процессе (на С++ в Windows), кроме использования «GetThreadContext». Я подозреваю, что этот метод занимает слишком много времени (я часто его использую), и если бы я мог получить только EBP, а не все значения CONTEXT, это было бы быстрее.
Я думал об использовании «ReadProcessMemory», а затем получение EBP с остальной частью стека вызовов, но я не знаю, где должен быть стек и откуда его взять.
Если кто-нибудь знает лучший способ, я был бы рад услышать об этом.
спасибо :)


person Idov    schedule 03.12.2010    source источник
comment
Ты что пишешь, профайлер? Может быть, если вы объясните свою проблему, кто-то может дать вам более быстрый способ.   -  person Ben Voigt    schedule 05.12.2010


Ответы (2)


Текущее значение EBP другого потока, конечно, находится в регистре EBP, если поток выполняется. Если он не запущен, он сохраняется планировщиком в ядре. GetThreadContext извлекает то, что находится в ядре; ничто другое не будет быстрее.

Ситуация с производительностью хуже, чем я понял, когда писал это. Если поток запущен, ядро ​​использует механизм APC, чтобы получить для вас актуальное значение. Это не быстро, но другого альтернативного API нет.

person bmargulies    schedule 03.12.2010
comment
Нет, это не правильно. NtGetContextThread всегда ставит APC в очередь целевому потоку, если это не текущий поток. Затем он ожидает завершения APC. Не очень быстро. - person wj32; 04.12.2010
comment
Я бы чувствовал себя хуже, если бы на самом деле была какая-то другая более быстрая альтернатива. Есть ли один? - person bmargulies; 04.12.2010
comment
Нет. Если поток запущен, его регистры... в регистрах, что не очень полезно. Если он не запущен, регистры сохраняются в объекте KTHREAD. Таким образом, лучший способ убедиться, что регистры потока сохранены, чтобы мы могли их действительно прочитать, - это поставить в очередь APC, что вызовет прерывание процессора этого потока. - person wj32; 05.12.2010

GetThreadContext будет единственным способом, потому что EBP — это регистр; процессор сохраняет его при переключении контекста. Единственный способ прочитать регистры потока — это GetThreadContext.

Конечно, нет никакой гарантии, что EBP имеет нужное вам значение... функции, скомпилированные с пропуском указателя кадра, не будут надежно устанавливать EBP на указатель кадра текущего кадра вызова.

Если вы просто ищете трассировку стека (наиболее распространенная причина, по которой нужно начать с EBP), могу ли я предложить StackWalk64?

person John Doty    schedule 03.12.2010