C ++ - использование оператора «new» невозможно во время отладки - PullRequest
0 голосов
/ 07 марта 2012

Приложение COM +, сборка с MS Visual Studio 6, SP 6 на Windows XP SP 3 и удаленная отладка.

Мой главный вопрос таков;почему я не смогу войти в «новое», если смогу «удалить»?Я в основном ищу идеи о том, на что мне следует обратить внимание.

Я работаю над довольно крупным проектом, с которым я только знакомлюсь.Текущая проблема - проблема повреждения кучи, в которой сборка выпуска в конечном итоге исчерпает свой рабочий набор и вылетает.Проблема настолько распространена, что следующий код повреждает кучу:

int * iArray = new int [100];
delete [] iArray;

Я говорю «повредить кучу», потому что выходные данные отладки отображают «heap [dllhost.exe]: неверный адрес, указанный для rtlvalidateheap» в'delete'.

Я могу перейти к штрафу "delete", и он, кажется, вызывает правильный вызов (находится в DELOP.cpp в ... \ Microsoft Visual Studio \ VC98 \ CRT \ SRC) но по какой-то причине я не могу вступить ни в один призыв к «новому».Я хватаюсь за соломинку здесь, но у меня есть ощущение, что где-то в базе кода кто-то отвергает оператор 'new', и код, на который я смотрю, непреднамеренно использует его.Симптомы релизной сборки кажутся выделением памяти для одной кучи и попыткой удаления из другой, по крайней мере, это моя догадка.

РЕДАКТИРОВАТЬ: Ack!Извините всех, я отправил слишком рано, должен был дать больше информации.

Я искал базу кода и нашел несколько переопределений, но они все в классах, не определены глобально.Единственное, чего нет в классе, это следующее:

struct _new_selector 
{

};

inline void* operator new(size_t, void *ptr, _new_selector)
{
    return (ptr); 
}

Но это новое место размещения, и я уверен, что в этой ситуации это не считается.В какую библиотеку я должен вступить для создания оригинального «нового»?Я предполагаю, что это то же самое, что и «удалить», но если нет, может быть, у меня просто нет отладочной информации для него?

РЕДАКТИРОВАТЬ 2: Возиться с этим я нашел это в отладочной сборкеэта проблема не существует.Я уже изучил библиотеки времени выполнения, для отладки используются / MD и / MDd.Мало того, но я собрал релизную версию с / MDd, чтобы убедиться, что изменений по-прежнему не было.Глядя на карты как отладочной, так и выпускной версий, новый оператор (с его искажениями) выглядит следующим образом:

Релиз:

0001: 00061306 ?? 2 @ YAPAXI @ Z10062306 f MSVCRTD: MSVCRTD.dll

0002: 00000298 _ imp ?? 2 @ YAPAXI @ Z 1006e298 MSVCRTD: MSVCRTD.dll

Отладка:

0001: 00077d06 ?? 2 @ YAPAXI @ Z 10078d06 f MSVCRTD: MSVCRTD.dll

0004: 00000ad4 _ imp ?? 2 @ YAPAXI @ Z 100b5ad4 MSVCRTD: MSVCRTD.dll

Я также проверил оператор удаления:

Выпуск:

0001: 000611f0 ?? 3 @ YAXPAX @ Z 100621f0 f msvcprtd: delop_s.obj

Отладка:

0001: 00077bf0 ?? 3 @ YAXPAX @ Z 10078bf0 f msvcprtd: delop_s.obj

Кроме того, у меня нет распечатки, но я могу получить ее, если она будетПомогите, разборка нового оператора выглядит одинаково при выпуске и отладке.Так что, я думаю, это не переопределение?Будет ли внутреннее переопределение оператора сделать это неверным?

Кроме того, будучи приложением COM +, которое порождает несколько процессов dllhost.exe, возможно ли, чтобы вызов нового оператора перешел в другую DLL или exe, а вызов на удаление перейти на противоположный?

Ответы [ 2 ]

3 голосов
/ 07 марта 2012

Если учесть, что где-то в коде может быть перегружено новое, мало что можно проверить

  1. дизассемблирование кода и поиск имени библиотеки в этом файле, обычно в сборке есть что-то, что даст вам подсказку
  2. Если вы не можете узнать имя библиотеки, проверьте адрес в сборке, которую вы вводите. Затем в окне вывода отладки проверьте адреса загрузки для различных библиотек - это может дать вам подсказку, какую библиотеку проверять
  3. Если вышеизложенное не помогает, проверьте, можете ли вы создать файл карты для всего проекта. Если вы можете, то вы можете посмотреть адрес в файле карты, и это может помочь
  4. Попробуйте использовать отладочную версию библиотек времени выполнения. Не могу вспомнить, какая опция включала debug_malloc. Это может помочь вам понять, что происходит в куче

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

2 голосов
/ 20 марта 2012

Ладно, вот что получилось.

В программе, над которой я работаю, около тридцати или около того проектов. Некоторые создают libs, другие dll, третьи exes. В любом случае, все это смешалось. Добавьте к этому тот факт, что мы используем ATL и COM, и он начинает быстро сходить с ума. Конечным результатом является то, что некоторые, а не все проекты строятся с определением компилятора _ATL_MIN_CRT, даже если это приложение для настольного компьютера, а не веб-приложение, в котором клиенту необходимо загрузить несколько модулей.

Вот некоторая информация о _ATL_MIN_CRT:

http://support.microsoft.com/default.aspx?scid=kb;EN-US;q166480

http://msdn.microsoft.com/en-us/library/y3s1z4aw%28v=vs.80%29.aspx

Обратите внимание, из первой ссылки, что это также исключит использование подпрограмм выделения памяти. Я не уверен, каков был первоначальный мотив использования этого или действительно ли он был намеренным, но это, безусловно, вызывает проблемы с выделением памяти. Кроме того, это влияет только на сборки Release, поэтому было так трудно найти.

По сути, модуль A был построен с _ATL_MIN_CRT, а модуль B был построен без него, но имел зависимость от модуля A. Поскольку он также использует COM, и все было запущено в dllhost.exe, когда модуль B пытался использовать новый оператор похоже, он вышел из своей библиотеки DLL, чтобы попытаться выделить память в куче. Затем, при вызове удаления, он попытался удалить его в своей DLL. Таким образом, у нас сумасшедшая утечка памяти.

Запомните, устранение _ATL_MIN_CRT исправляет это, но то, что я упоминаю выше, это только мое понимание этого. Это вполне может быть более / менее сложным, но, тем не менее, это была проблема.

Спасибо всем, они действительно помогли мне найти эту вещь!

...