Собственно у меня на всю программу стоит финальный обработчик исключений, на случай критической не предусмотренной ошибке. Он выводит сообщение с некоторой информацией. Если внутри своего модуля то только информацию о исключении и общих регистрах, а иначе еще и стек раскручивает что бы можно было понять хоть, что то. Файл с частным случаем я прикрепил. Вот смотрю на его и понять не могу, а как найти мне инструкцию которая вызвала исключение? Или может кто подскажет как лучше собирать информацию при исключении, что бы было понятно, а чем оно вообще вызвано было?
hapr, > Вот смотрю на его и понять не могу, а как найти мне инструкцию которая вызвала исключение? Адрес исключения - по этому адресу расположена инструкция. Для #AV возвращает ядро все параметры - тип доступа(R/W/X), адрес инструкции и адрес выборки. У вас на скрине это есть. Ты вообще адекватный, справку покажите
Мда.... Вот скрин отладчика и какая же инструкция выдала исключение может просветите меня? Стрелка указывает на смещение вызвавшее исключение 6C8F. Но упс, это ведь память и как тут понять какая именно инструкция привела сюда? В данном случае у меня есть подозрение, где искать проблему и потом я проверю . Но, а что делать когда это не известно. Вот поэтому данным вопросом и озадачился, может можно в экран ошибки еще, что включить... или подход сменить?
hapr, 856C8F - по этому адресу инструкция вызвала исключение. В отладчике у вас совсем иные адреса - 40xxxx. Что значит "тут 6C8F" я хз. Кури матчасть короче и переформулируй вопрос.
Странно я выпал из ассемблирования чуть больше, чем на полгода, а тут такие изменения... Может конечно я все уже подзабыл, но в отладчике база программы 0x400000, а в скрине с ошибкой 0x850000. Соответственно 0x6C8F это смещение относительное базы, так что по идеи курить матчасть мне не надо.
У тебя на скрине адрес 0x856C8F, просто перейди по этому адресу в отладчике. Не по 0x400000 + 6C8F, а именно по тому, что тебе выдаёт эксепшн.
а почему базы разные? видимо ASLR рандомизация включена что ли? попробуй ещё раз запустить без отладчика - база поменяется в окне или нет?
Вообще-то есть такая штука как релоки и если они в программе то база при запуски зачастую разная. Но раз так проще всем будет, вот правильный "скрин" с "правильной базой". --- Сообщение объединено, 1 фев 2019 --- Такой адрес изо релокав тогда включенных.
hapr, а посмотри-ка, что лежит по адресу EIP (0x853004). Если адрес в твоём эксепшне верный, то значит, ты просто прыгнул не туда, и этот кусок памяти попытался выполниться, как код, потому на него и показывает.
У меня там точка входа и сразу выделяется память под локальные переменные. Я думал это и так видно по скрину, что это изо прыжка. Поэтому я и задал вопрос как найти где ошибка? Можно ли как не-будь упростить нахождение бага? В данном случае я имею представление где, хоть и глянул и вроде там все правильно, потом гляну конкретно - думаю найду. Но, а что если это ошибка в другом месте, как тогда находят такие баги? Просто я как представлю, что после того как выложу в интернет программу мне пришлют пару таких скринов, это ведь жуть. В данном случае я даже опять повторить не смог такую ошибку, прекрасно помня как она возникла. Поэтому мне очень интересен чужой опыт насчет нахождения таких ошибок в коде. Даже ведь от опечатки никто не застрахован, а потом например гадай почему пару раз в месяц вылитает...
hapr, никак их не находят. Снимают дамп, смотрят трейс, смотрят, откуда вызвали проблемную функцию, смотрят регистры. Эмпирически находят проблему.
Холера - этого я и боялся. Потом надо будет когда освобожусь(хех или когда баги посыплются) еще снятие дампа прикрутить, все же лучше чем ничего. Спасибо за объяснение.
hapr, > Соответственно 0x6C8F это смещение относительное базы, так что по идеи курить матчасть мне не надо. Относительно нулевой базы сегмента, да. Но не смещение от базы загрузки образа. В инфе про фаулт виртуальные адреса, а не смещения. Тут читай https://wasm.in/threads/oshibki-v-polzovatelskom-rezhime.20412/
Да, дамп - лучшее решение. Автоматически такие баги не найти, только вручную. А в целом, тот адрес и должен был показать тебе проблемную инструкцию
Прочитал, но с ДОСам связан не был, драйвера не писал, так что ссылку мне бесполезно курить. Так что и с терминологией у меня не очень. Да и как я понимаю суть нахождения места, на чем было вызвана исключение, от этого не меняется. Ну и плюс ответ на свой вопрос я уже получил.
hapr, Да тебе всё нитак". Начинать нужно с изучения материала, теории. А не скриптом собирать и не понимать свой же лог. Впрочем раз ответ есть, то и обсуждать больше нечего, расходимся.
Я лично считаю, что сама по себе теория без практики бесполезна. Так что я выбрал путь написания программы с параллельным обучением. Хоть сама правельно для знаний было бы начинать с изучения написания программ для ДОСа. Но сейчас уже это не актуально. В принципе как и сам ассемблер - в том смысле в первую очередь для написания программ. Даже если посмотреть на форумы по ассемблеру 10 лет назад они были очень активны, а сейчас(я тогда не начинал писать, а только любопытствовал) они полу-мертвые. Я лично пытаюсь начать на нем писать изо того, что он мне нравиться да и знаний больше даст не отнимая много времени. Но потом скорей всего придеться рано или поздно переходить на C или писать для себя IDE для FASM. А вот в логах своей программы я отлично разбираюсь. Просто не так называю, но в данный момент для меня это не так и важно. И вопрос я задал в надежде, что я что то упустил вдруг и можно как то автоматизировать нахождение таких багов, как у меня в примере, но увы и ах:
hapr, Есть методы, где можно автоматикой найти источник проблемы. Но такие методы не для вас, нужен соответствующий скилл. Так например обычно имея место крэша(адрес), как у вас в вопросе придётся вручную выполнить обратную трассировку - пройти по графу, который не только не линеен, но указатели нужно брать из стека. Получить полную трассу(все события и связать потоки данных) можно автоматикой, но для этого апп должно быть запущено под монитором(это визоры"). Но это тема не для новичков. Вначале нужно с простым разобраться. Кстати про дос я ничего не говорил. Если у вас понятие сегментации связано с досом - то это не верные понятия. Сегментация это механизм трансляции памяти. Это называется плоской моделью памяти - когда смещение в сегменте равно виртуальному адресу, поэтому вы и не знаете ничего про сегментацию, в ОС адресация абсолютная(от нулевой базы).
Согласен это мне рано. Плюс к моему вопросу отношения не имеет, потому что если баг я смогу воспроизведи у себя на компе то и отладчикам обойдусь. А когда баг не воспроизводимый и у меня будет только скрин присланный пользователям то тут и визор не поможет. Вот поэтому про ДОС я и написал, так как это самый лучший способ понять полностью сегментацию это писать под ним. Ну или начатть писать свой загрузчик или свою ОС и т.д., что еще хуже с практической точки зрения для меня.