2009-08-22 7 views
8

Я пытаюсь найти способ глобально переопределить malloc и связанные функции в visual C++ (2005). Моя установка - это dll со статически связанной библиотекой времени выполнения, которая состоит из моего собственного кода на C++, внешнего кода C++ и c. То, что я хочу сделать, - разрешить пользователю dll устанавливать собственные реализации функций распределения памяти.Глобально переопределить malloc в visual C++

Решения, которые я не могу использовать:

  • Перекрытие новые и удалять во всем мире, существует множество внешних библиотек C в моей базе кода, что означает это будет не захват многих распределений.
  • определение malloc для другого символа. Это заставит меня подтолкнуть это определение к настройкам сборки всех используемых внешних библиотек, и я действительно хочу этого избежать.

Вещи, которые я не заботятся о

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

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

В google perf-tools кажется, что они исправляют код функций вручную во время выполнения, чтобы вызвать функцию hook для вызова перед вызовом исходной функции. Это действительно лучший способ сделать это?

+0

Вы пытаетесь сделать то же самое, что LD_PRELOAD в Linux? – LB40

+0

Я не знаком с LD_PRELOAD, но, похоже, это связано с динамической связью, в моем случае malloc, free и их друзья статически связаны. – Laserallan

+0

Не могли бы вы объяснить, почему вы думаете, что вам нужно это сделать? – 2009-08-22 15:40:26

ответ

2

Вы можете использовать Detours от Microsoft (заплатить за рекламу) или переписать таблицы импорта для используемых библиотек DLL.

+0

Это может определенно работать, если я использовал динамически связанную библиотеку времени выполнения. Тем не менее, я беспокоюсь, что переопределяю функции для исполняемого файла, используя мою библиотеку. – Laserallan

+0

Да, вы бы. Это процесс в целом. –

5

В Linux существует следующее: оно может быть применимо и для визуального C++ Win's.

  1. Malloc funciton предоставляется системной библиотекой glibc. Исполняемый файл по умолчанию связан с ним.

  2. Когда программа запускается, динамический загрузчик замечает, что исполняемый файл нуждается в функции malloc и ищет первую библиотеку, которая ее предоставляет.

  3. Поскольку glibc является (по умолчанию) последним в этом списке, найденная библиотека может быть не glibc.

Если вы не статически Glibc в исполняемый файл, очевидное решение, чтобы связать исполняемый файл с библиотекой, которая предоставляет свой собственный таНос, и убедитесь, что он делает переопределить один системы.

+0

Это правильный ответ – pgast

+1

Не работает в Windows. Импорт не только по названию. Импорт указан для каждой DLL, которая должна его предоставить. Формат PE позволит вам импортировать одно и то же имя функции из двух DLL. – MSalters

+0

Прохладный, то это просто немного _superior_, чем в Linux. Фактически вы можете напрямую назначить функцию библиотеке, чтобы пользовательский malloc загрузился из определенной библиотеки. Это то, что мы хотим, не так ли? –

1

К сожалению, я недостаточно знаю о компоновщике Microsoft. Но ld имеет «--wrap», который вы можете использовать для чего угодно, например, malloc или бесплатно или что-то еще (я это делаю).

все вызовы в malloc будут перенаправлены на функцию с именем __wrap_malloc, которую вы внедрили, затем вы можете вызвать реальный malloc с __real_malloc.Это позволяет извлекать любые маллоки, используемые во внешних библиотеках. Я уверен, что линкер Microsoft может иметь аналогичную функцию.

+0

Я не нашел ничего подобного в линкере визуальной студии, и ближайший я нашел, используя инструмент lib.exe (http://msdn.microsoft.com/en-us/library/7ykb2k5f(VS.71). ASPX). Он может извлекать и добавлять файлы .obj в статическую библиотеку. Технически я мог создать свою собственную версию стандартного библиотечного .lib-файла с исправленными функциями malloc/calloc/free/realloc. Если бы я нашел инструмент, который может переименовывать функции внутри .obj-файла, можно было бы переименовать старые версии и убедиться, что мои функции переопределения называет их. – Laserallan

1

Вы можете удалить эти .obj файлы с помощью lib.exe из lib. Я не могу быть более конкретным, но я помню, как это делалось, когда я строил Chromium из источника.

+0

Вы не предлагаете манипулировать встроенной библиотекой времени выполнения Microsoft C++? – rustyx

5

Я также хочу найти для этого опрятное решение. Мы компилируем для нескольких платформ, поэтому на стороне, отличной от окон, мы можем использовать --wrap счастливо. Нам просто нужно создать функции замены, и все это работает без каких-либо ошибок или взломов.

На стороне окна мы переопределяем вызовы malloc, но затем используем /FORCE:MULTIPLE для устранения ошибок компоновщика. Он работает, функции памяти называются и все отслеживается, но это похоже на хак.

Из MSDN:

A file created with this option may not run as expected. The linker will not link incrementally when the /FORCE option is specified.

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

Опция /FORCE:MULTIPLE может решить ваши проблемы, но я не предлагаю это как лекарство, я все еще пытаюсь это найти.

MSDN /FORCE Documentation

: D

+0

Это выглядит полезно. Какой порядок разрешения используется? Всегда ли мой собственный malloc - тот, который используется, когда есть конфликт со стандартной библиотекой? Вы маршрутизируете вызовы через свой пользовательский malloc в исходное определение или полностью ли выбрали стандартную библиотечную версию malloc? – Laserallan

+0

Мы используем dlmalloc для выполнения фактических распределений. У меня создается впечатление, что он всегда будет принимать переопределенные функции, но теперь вы задали вопрос, я не уверен. : D –

1

Удалить все .obj файлы, которые содержат функции управления памятью из библиотеки во время выполнения с помощью инструмента LIB, то используйте опцию «Игнорировать библиотеки по умолчанию» в IDE и вручную вместо этого укажите «свою» библиотеку времени исполнения. Затем скомпилируйте; вы должны получить несколько ошибок компоновщика о неопределенных malloc и free и так далее. Здесь вы заходите!

(Вы, вероятно, также хотят, чтобы сделать что-то похожее на C++ библиотеки, если вы используете их, хотя я думаю, что по умолчанию operator new Призыв malloc, чтобы вы могли быть хорошо идти прямо.)

Визуальный Установка Studio поставляется с исходным кодом времени выполнения (посмотрите в vc/crt/src в папке установки Visual Studio), поэтому поиск полного набора функций управления памятью довольно прост. У меня нет точных данных (предыдущий работодатель ...), но, как я помню, потребовалось всего полдня, чтобы разобраться, хотя функции распределения памяти были гораздо больше, чем я ожидал.

+0

Спасибо, это, кажется, добавляет последний кусочек головоломки. – Laserallan

2

Решение, которое я использовал, состоит в том, чтобы перестроить библиотеку времени выполнения Visual C++ C (crt) из исходного кода.

Он может быть найден здесь, в этой папке:

C: \ Program Files \ Microsoft Visual Studio 9.0 \ VC \ Crt

Убедитесь, что вы запускаете командную строку студии Визуальная построить его. Запуск nmake достаточно, чтобы запустить его, хотя вы можете захотеть разработать, какой целью построить, а это значит, что вам нужно будет понять make-файл.

Он может принять усилия, чтобы понять, как построить ЭЛТ, но как только вы его строительства вы можете добавить свой собственный код в таНос, бесплатно и перераспределить и т.д.

К сожалению, я слышал слух, что мы не сможет построить crt из исходного кода, начиная с Visual Studio 2010.

Смежные вопросы