Почему моя программа x64 молча вылетает в Windows? - PullRequest
0 голосов
/ 09 октября 2018

Рассмотрим эту маленькую программу:

int main(int argc, char *argv[])
{
    *((int *) 0) = 1;
    return 0;
}

Очевидно, что запись в $ 0 вызывает ошибку доступа к памяти.При компиляции этой программы в виде 32-разрядного исполняемого файла с использованием Visual C и ее запуске Windows 7 ясно показывает, что программа аварийно завершилась: (Немецкая система)

Screenshot

Однако при компиляции программы как 64-битного исполняемого файла с Visual C она просто молча вылетает.Не появляется системное диалоговое окно, информирующее пользователя о том, что программа только что упала.

Это нормальное поведение для двоичных файлов x64 или что-то не так с моей конфигурацией Windows 7?Я думаю, что операционная система должна четко показывать пользователю, когда программы аварийно завершают работу, а не просто молча их убивать ...

РЕДАКТИРОВАТЬ : Для всех, кто утверждает, что компиляторможет просто оптимизировать доступ к нулевому указателю, вот сборка.Вы можете видеть, что там есть недопустимый доступ к памяти, и он также отображается в журнале приложений Windows после запуска программы.

; Listing generated by Microsoft (R) Optimizing Compiler Version 15.00.30729.01 

include listing.inc

INCLUDELIB LIBCMT
INCLUDELIB OLDNAMES

PUBLIC  main
; Function compile flags: /Odtp
_TEXT   SEGMENT
argc$ = 8
argv$ = 16
main    PROC
; File d:\test.c
; Line 2
    mov QWORD PTR [rsp+16], rdx
    mov DWORD PTR [rsp+8], ecx
; Line 3
    mov DWORD PTR ds:0, 1      ; here we go folks
; Line 4
    xor eax, eax
; Line 5
    ret 0
main    ENDP
_TEXT   ENDS
END

EDIT 2 :Я также проверил, что HKEY_CURRENT_USER\Software\Microsoft\Windows\Windows Error Reporting\DontShowUI установлено в 0. Таким образом, Windows явно настроена для сообщения о сбоях.Но это только для двоичных файлов x86, но не для двоичных файлов x64.Да, для двоичных файлов x64 о сбое сообщается в журнале приложения, но диалоговое окно ошибки (см. Скриншот выше) отображается только для двоичных файлов x86, но не для двоичных файлов x64, хотя для DontShowUI явно установлено значение 0.

РЕДАКТИРОВАТЬ 3 : Я провел тесты на разных системах Windows.Вот результаты:

Windows 7: x86 shows crash dialog, x64 doesn't (as described above)
Windows 8: both x86 and x64 show the crash dialog
Windows 10: neither x86 nor x64 show the crash dialog

Таким образом, единственная система, которая ведет себя здесь непоследовательно, на самом деле - Windows 7. На всех других системах диалоговое окно сбоя либо отображается, либо нет, тогда как в Windows 7 между сбоями происходит другое поведениепрограмм x86 и x64.Weird.

Ответы [ 2 ]

0 голосов
/ 09 октября 2018

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

Сам процесс может создать его с помощью SetErrorMode иWerRegisterRuntimeExceptionModule.Смотри также werapi.h.

0 голосов
/ 09 октября 2018

Поведение *((int *) 0) = 1; и, следовательно, всей вашей программы, равно undefined .

Различные сбои являются проявлением этого неопределенного поведения.

Некоторые компиляторывполне может оптимизировать ваш код до int main{}: gcc уже некоторое время оптимизирует неопределенные операторы при высоких настройках оптимизации.Возможно, это объясняет поведение 64-битной компиляции?

...