падение dlmalloc на Win7 - PullRequest
       33

падение dlmalloc на Win7

3 голосов
/ 03 ноября 2010

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

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

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

Кстати, вот код теста (test.cpp):

#include <stdio.h>

int main() {
    return 0;
}

и вот makemaile nmake:

all: regulartest.exe malloctest.exe

malloctest.exe: malloc.obj test.obj
 link /out:$@ $**

regulartest.exe: test.obj
 link /out:$@ $**

clean:
 del *.exe *.obj

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

Редактировать: Смотрите эти другие соответствующие сообщения SO:

Ответы [ 2 ]

2 голосов
/ 03 ноября 2010

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

2 голосов
/ 03 ноября 2010

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

К счастью, исходный код среды выполнения 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, как это поддерживается - если это так, то это ошибка с CRT. Если нет, я бы посоветовал изучить другую среду выполнения C (например, MinGW или Cygwin GCC).

...