Может ли нарушение доступа быть замаскированной ошибкой нехватки памяти? - PullRequest
0 голосов
/ 16 января 2019

Я отлаживаю 64-битный аварийный дамп C ++ (управляемый) (нарушение прав доступа).

Общий размер дампа составляет 32,374,535 кб.

Приложение является многопоточным, и в соответствующем стеке вызовов упоминается только mscvrt.dll!memcpy (я не знаю, какой другой поток создает этот). Очевидно, что нет соответствующего исходного кода.

Окно Visual Studio Locals пусто.

Необработанное исключение упоминает Access violation writing location 0x000000F02A6BB000, но в этом месте, кажется, ничего нет:

0x000000F02A6BAF84  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ..............................................................
0x000000F02A6BAFC2  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ..............................................................
0x000000F02A6BB000  ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ??  .............................................................. <= here it is.
0x000000F02A6BB03E  ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ??  ..............................................................

Я не вижу причин, по которым запись в этом месте памяти может вызвать какие-либо проблемы, поэтому я считаю (исходя из размера дампа), что я имею дело с ошибкой памяти (то есть невозможно скопировать что-то в память, потому что так много памяти уже используется, что не осталось места). Однако, если это так, не должно ли быть что-то в этом месте памяти?

У кого-нибудь есть идеи по этому поводу?

Ответы [ 3 ]

0 голосов
/ 16 января 2019

Действительно возможно, что нарушение доступа на самом деле является ошибкой нехватки памяти (или другим видом ошибки, связанной с памятью), как упомянуто в комментариях Шеффа и Питера.

В этом конкретном случае большой размер дампа (± 33 ГБ) указывает на то, что приложение (вместе с другими приложениями) может потреблять слишком много памяти.

0 голосов
/ 17 января 2019

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

Метинкс, что вы получаете переполнение памяти, которое вызывает запись на страницу, которая не была отображена в адресное пространство.

0 голосов
/ 16 января 2019

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

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

Здесь адрес выглядит разумным. Но кто знает. Может быть, код выделяет новый буфер, освобождает старый и переключает старый адрес на новый, но при ошибке не переключает адреса, а освобождает старый адрес, вызывая доступ после освобождения. Без исходного кода узнать невозможно.

...