2010-11-03 2 views
2

В течение некоторого времени я с радостью использовал dlmalloc для кросс-платформенного проекта (Windows, Mac OS X, Ubuntu). В последнее время, однако, кажется, что использование dlmalloc приводит к сбою при выходе из Windows 7.dlmalloc crash on Win7

Чтобы убедиться, что это не было чем-то глупо в моем проекте, я создал суперминимумную тестовую программу - это не делает ничего, кроме возвращения из основного. Одна версия («malloctest») ссылается на dlmalloc, а другая («regulartest»). На WinXP оба работают нормально. В Windows 7, malloctest сбои. Вы можете увидеть скринкасты тестов here.

Вопрос: почему это происходит? Это ошибка в dlmalloc? Или изменился загрузчик в Windows 7? Есть ли обходной путь?

FYI, вот тестовый код (test.cpp):

#include <stdio.h> 

int main() { 
    return 0; 
} 

и вот NMAKE Makefile:

all: regulartest.exe malloctest.exe 

malloctest.exe: malloc.obj test.obj 
link /out:[email protected] $** 

regulartest.exe: test.obj 
link /out:[email protected] $** 

clean: 
del *.exe *.obj 

Для краткости я не буду включать источник dlmalloc в этот пост, но вы можете получить его (v2.8.4) here.

Edit: Смотрите эти другие relavent SO сообщения:

ответ

3

Похоже, ошибка в среде выполнения C. Используя Visual Studio 2008 в Windows 7, я воспроизвел ту же проблему. После некоторой быстрой отладки, поставив точки останова в dlmalloc и dlfree, я увидел, что dlfree получил вызов с адресом, который он никогда не возвращал ранее с dlmalloc, а затем вскоре после этого он нарушил нарушение доступа.

К счастью, исходный код среды исполнения C распространяется вместе с VS, поэтому я мог видеть, что этот вызов в free поступал из функции __endstdio в _file.c. Соответствующее распределение было в __initstdio, и он вызывал _calloc_crt для выделения своей памяти. _calloc_crt звонит _calloc_impl, который звонит HeapAlloc, чтобы получить память. _malloc_crt (с другой стороны, используется в другом месте в среде выполнения C, например, для выделения памяти для среды и для argv), а прямо на malloc, а _free_crt - прямо на free.

Итак, для памяти, которая выделяется с _malloc_crt и освобождена с _free_crt, все в порядке и денди. Но для памяти, которая распределяется по _calloc_crt и освобождается с _free_crt, происходят плохие вещи.

Я не знаю, поддерживает ли замена malloc, если это так, то это ошибка с ЭЛТ. Если нет, я бы предложил посмотреть на другое время выполнения C (например, MinGW или Cygwin GCC).

+0

Это не ошибка, а объяснение **, почему ** замена 'malloc' (или любой стандартной функции C) была указана как ** неопределенное поведение **. –

2

Использование dlmalloc в межплатформенном коде является оксюмороном. Замена любых стандартных функций С (особенно malloc и семейства) приводит к неопределенному поведению .Самое близкое к переносимому способу замены malloc - это поиск и замена (не #define; это также UB) на исходные файлы для вызова (например) my_malloc вместо malloc. Обратите внимание, что внутренние функции библиотеки C по-прежнему будут использовать свой стандарт malloc, поэтому, если эти два конфликта, все будет взорваться. В принципе, попытка заменить malloc просто ошибочна. Если ваша система действительно имеет сломанную реализацию malloc (слишком медленную, слишком много фрагментации и т. Д.), Вам необходимо выполнить свою замену в соответствии с реализацией и отключить замену во всех системах, кроме тех, где вы тщательно проверили, что ваша замена, специфичная для реализации, работает правильно.

+1

Вы заставляете это звучать так, как будто любой, кто хочет переопределить malloc, смешон. Многие проекты переопределяют malloc (см. Новые ссылки SO в моем вопросе). В нашем проекте наблюдался значительный прирост скорости за счет использования dlmalloc. Возможно, я делал это неправильно неправильно (поскольку его более сложно переопределить malloc для msvc, чем gcc), но это совершенно правильная вещь, которую вы хотите сделать. – paleozogt

+0

Что разумно сказать: «Я тестировал такую-то платформу и ее« malloc »отстой. Я также исследовал, как заменить« malloc »на этой платформе, и я делаю это правильно. В моих сценариях сборки я гарантировал, что замена «malloc» не будет предпринята ни в какой системе, кроме точной конфигурации, на которой я тестировал ее ». Что необоснованно: «Я собираюсь предположить, что система« malloc »всегда сосет и что моя замена обычно работает, и только отключить мою замену в системах, которые, как я знаю, имеют« хороший »' malloc'. Последнее поведение имеет имя: это называется ** не переносным **. –

+1

Мы протестировали его на Windows XP, а его malloc сосет. Я исследовал, как заменить malloc на этой платформе, и я сделал это правильно. Теперь мы изучаем, как это сделать работа над Windows 7, так как техническая переопределения Window XP malloc явно не работает. У вас есть реальный ответ на мой вопрос (как заставить его работать на Windows 7), или вы просто продолжаете спорить? – paleozogt