Что означают шестнадцатеричные числа в сообщениях об исключениях первого шанса?

Например, в сообщении:

Исключение первого шанса по адресу 0x757bd36f в foo.exe: исключение Microsoft C++: _ASExceptionInfo в ячейке памяти 0x001278cc..

Что означают 0x757bd36f и 0x001278cc? Я думаю, что 0x757bd36f будет означать EIP на момент создания исключения, но как насчет второго числа?


person sashoalm    schedule 24.07.2012    source источник
comment
Я предполагаю, что это место, где был выделен объект исключения.   -  person Alexandre C.    schedule 24.07.2012
comment
Было бы круто, если бы это было так. Затем мы могли бы просмотреть данные брошенного объекта в окне памяти. Это особенно полезно для исключений, которые вызываются и обрабатываются внутри библиотеки.   -  person sashoalm    schedule 24.07.2012
comment
@satuon: Проведя небольшое тестирование, похоже, это так.   -  person Jerry Coffin    schedule 24.07.2012


Ответы (1)


Как вы уже догадались, первым является EIP, когда произошло исключение (или RIP, для кода 64-it).

При проведении некоторого тестирования второе число — это адрес перехваченного объекта исключения. Однако имейте в виду, что это не то же самое, что и адрес сгенерированного объекта исключения. Например, я написал следующий фрагмент тестового кода:

#include <iostream>
#include <conio.h>

class XXX { } xxx;

void thrower() { 
    throw xxx;
}

int main() {
    try {
        std::cout << "Address of xxx: " << (void *)&xxx << "\n";
        thrower();
    }
    catch(XXX const &x) {
        std::cout << "Address of x: " << (void *)&x << "\n";
    }
    getch();
    return 0;
}

По крайней мере, в моем тестировании второй адрес, который VS показывает в своем сообщении «исключение первого шанса», совпадает с адресом, который я получаю для x в приведенном выше коде.

person Jerry Coffin    schedule 24.07.2012
comment
Мы с вами оба написали одно и то же, но это относится только к нарушению прав доступа. Это исключение C++ (throw blah;) - person Ben Voigt; 24.07.2012
comment
@BenVoigt: я только что провел небольшое тестирование и отредактировал ответ. Если бы вы могли взглянуть и посмотреть, кажется ли это лучше, я был бы признателен (и я также ценю ваш комментарий). - person Jerry Coffin; 24.07.2012
comment
Подождите, разве это исключение не выбрасывается в стек? Итак, вы получаете в своем catch указатель на адрес в стеке, который уже раскручен? - person sashoalm; 24.07.2012
comment
@satuon: выделение объектов исключений немного сложно. Стандарт в значительной степени держит руки подальше, говоря, что то, как выделяется объект исключения, не указано (§15.2/3, для всех, кто заботится). Разные компиляторы работают по-разному, и в последнее время я недостаточно внимательно изучал, как это делает VC++, чтобы точно сказать, как это работает. Windows XP добавила VEH к предыдущему SEH, что, вероятно, повлияло на некоторые из них, но я не уверен, насколько сильно. - person Jerry Coffin; 24.07.2012
comment
@Jerry: Да, после редактирования это хорошее объяснение адреса, показанного для первой обработки исключений Microsoft C++. +1 - person Ben Voigt; 24.07.2012
comment
@satuon: объект исключения определенно не может храниться в стеке. Правила времени жизни для объектов исключений сложны, и люди даже использовали их для реализации полноценного локального хранилища потока, используя только переносимый C++. - person Ben Voigt; 24.07.2012
comment
@BenVoigt: У вас есть указатель на локальное хранилище потока? - person Alexandre C.; 26.07.2012