Модераторы: Partizan, gambit
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Heap corruption 
:(
    Опции темы
Lazin
Дата 10.7.2009, 15:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3820
Регистрация: 11.12.2006
Где: paranoid oil empi re

Репутация: нет
Всего: 154



Добрый день. 
Сегодня столкнулся с такой проблемой. Есть приложение, которое состоит из нативного ядра, которое используется из управляемого кода. 
В неуправляемой части поддерживается структура данных - строковый пулл. В общих чертах, это список 8Кб блоков памяти. В этих блоках памяти лежат строки, разделенные нулевыми символами. Что-то вроде "Foo\0Bar\0....\0". После любых манипуляций с данными, нативная часть проверяет целостность кучи с помощью _CrtCheckMemory. Управляемая часть периодически извлекает данные из этой структуры данных, с помощью ф-ии 
Код

int SelectData(int lower_bound, int count, MyStruct* p);

структура MyStruct содержит несколько полей типа int и указатель на строку из пулла. То есть, это адрес, который лежит внутри одного из буферов. Периодически, в Immediate window появляются такие сообщения:
Цитата

Heap corruption detected at 0E1A5D68
Heap corruption detected at 0E1A5D68
Heap corruption detected at 0E1A5D68
Heap corruption detected at 0E1A5D68
Heap corruption detected at 0E1A5CF0
Heap corruption detected at 0E1A5CF0
Heap corruption detected at 0E1A5CF0
Heap corruption detected at 0E1A5CF0

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

        [DllImport( "some.dll"
                  , CallingConvention = CallingConvention.StdCall
                  , CharSet = CharSet.Ansi
                  , EntryPoint = "some_entry_point" )
        ]
        public static extern int SelectData(int lower_bound, int count, [In, Out, MarshalAs(UnmanagedType.LPArray)] MyStruct[] dest);

маршалинг происходит правильно, данные передаются верно..
ошибка привязана к определенным адресам внутри буфера, к примеру, обращение к 0E1A5FD0 может происходить без проблем, а при обращении к 0E1A5CF0 будет выведено сообщение - Heap corruption detected at ...
Как это можно отлаживать?
PM MAIL Skype GTalk   Вверх
Lazin
Дата 13.7.2009, 17:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3820
Регистрация: 11.12.2006
Где: paranoid oil empi re

Репутация: нет
Всего: 154



помимо всего этого, при обращении к этому участку памяти происходит исключение:
Цитата

Attempted to read or write protected memory. This is often an indication that other memory is corrupt.

точнее оно происходит во время маршалинга
при этом буфер не был ни перезаписан, ни удален, я закомментировал все удаление и выделяю в 2 раза больше памяти что-бы исключить перезапись
PM MAIL Skype GTalk   Вверх
Lazin
Дата 14.7.2009, 14:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3820
Регистрация: 11.12.2006
Где: paranoid oil empi re

Репутация: нет
Всего: 154



В общем, проблему удалось исправить, но причину, из-за которой возникала ошибка я не нашел. Если добавить один дополнительный байт, между символами в буфере, то все работает нормально, т-е, вместо "Foo\0Bar\0....\0", нужно заполнять буфер так: "Foo\0\0Bar\0\0....\0".
Напомню, что в буфере находится массив строк, разделенных нулевыми символами. Эти строки передаются в управляемый код по очереди.
Никто не знает, в чем причина такого странного поведения?
PM MAIL Skype GTalk   Вверх
Любитель
Дата 14.7.2009, 15:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Программист-романтик
****


Профиль
Группа: Комодератор
Сообщений: 3645
Регистрация: 21.5.2005
Где: Воронеж

Репутация: 11
Всего: 92



Lazin, а можешь привести минимальный код, на котором это репродьюсится? А то - прям интересно стало smile Или проблема возникает только глобально, на новом проекте так просто не воспроизвести?


--------------------
PM MAIL ICQ Skype   Вверх
Lazin
Дата 17.7.2009, 08:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3820
Регистрация: 11.12.2006
Где: paranoid oil empi re

Репутация: нет
Всего: 154



Цитата(Любитель @  14.7.2009,  15:46 Найти цитируемый пост)
а можешь привести минимальный код, на котором это репродьюсится?

это будет сложно сделать, приложение многопоточное

в общем, проблема вернулась, когда я собрал релиз, помогло очень простое решение - передавать строку не как строку, а как IntPtr, а затем маршалить вручную: Marshal.PtrToStringAnsi
PM MAIL Skype GTalk   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Прежде чем создать тему, посмотрите сюда:
mr.DUDA
THandle

Используйте теги [code=csharp][/code] для подсветки кода. Используйтe чекбокс "транслит" если у Вас нет русских шрифтов.
Что делать если Вам помогли, но отблагодарить помощника плюсом в репутацию Вы не можете(не хватает сообщений)? Пишите сюда, или отправляйте репорт. Поставим :)
Так же не забывайте отмечать свой вопрос решенным, если он таковым является :)


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, mr.DUDA, THandle.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Общие вопросы по .NET и C# | Следующая тема »


 




[ Время генерации скрипта: 0.0709 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.