Проблемы с отслеживанием потенциальной перезаписи памяти. Странность Windows - PullRequest
1 голос
/ 12 декабря 2008

Это сводит меня с ума. Я использую какой-то сторонний код в Windows .lib, который в режиме отладки вызывает ошибку, подобную следующей:

Run-Time Check Failure #2 - Stack around the variable 'foo' was corrupted.

Ошибка выдается, когда объект выходит из области видимости или удаляется. Простое выделение одного из этих объектов и последующее удаление приведет к ошибке. Поэтому я думаю, что проблема либо в одном из множества конструкторов / деструкторов, но, несмотря на то, что я перебираю все строки кода, я не могу найти проблему.

Однако это происходит только при создании одного из этих объектов в статической библиотеке. Если я создаю его в своем приложении EXE, ошибка не появляется. Сам сторонний код живет в статической библиотеке. Например, это не удается:

**3RDPARTY.LIB**

class Foo : public Base
{
    ...
};

**MY.LIB**

void Test()
{
    Foo* foo = new Foo;
    delete foo; // CRASH!
}

**MY.EXE**

void Func()
{
    Test();
}

Но это будет работать:

**3RDPARTY.LIB**

class Foo : public Base
{
    ...
};

**MY.EXE**

void Func()
{
    Foo* foo = new Foo;
    delete foo; // NO ERROR
}

Итак, вырезание «среднего» файла .lib устраняет проблему, и именно эта странность сводит меня с ума. EXE и 2 библиотеки используют одну и ту же библиотеку CRT. Нет ошибок при связывании. Сторонний код использует наследование и существует 5 базовых классов. Я закомментировал столько кода, сколько смогу, пока все еще готовил его, и я просто не вижу, что случилось.

Так что, если кто-нибудь знает, почему код в .lib будет работать по-разному с тем же кодом в .exe, я хотел бы услышать это. Так же любые советы по отслеживанию памяти перезаписывают! Я использую Visual Studio 2008.

Ответы [ 5 ]

2 голосов
/ 15 декабря 2008

ОК, я разобрался с проблемой, и это взломщик, если кому-то интересно. В основном мой .LIB, в котором выставлена ​​проблема. определил _WIN32_WINNT как 0x0501 (Windows 2000 и выше), но мой EXE и сторонняя LIB определили его как 0x0600 (Vista). Теперь один из заголовков, включенных в стороннюю библиотеку, - sspi.h, который определяет структуру с именем SecurityFunctionTable, которая включает в себя следующий фрагмент:

#if OSVER(NTDDI_VERSION) > NTDDI_WIN2K
    // Fields below this are available in OSes after w2k
    SET_CONTEXT_ATTRIBUTES_FN_W         SetContextAttributesW;
#endif // greater thean 2K

Короче говоря, это означало несоответствие размеров объектов между LIB, что приводило к сбою проверки во время выполнения.

Класс!

2 голосов
/ 12 декабря 2008

Возможно, это соглашение о вызовах несоответствие - убедитесь, что все библиотеки и исполняемые файлы настроены на использование одного и того же соглашения о вызовах по умолчанию (обычно __cdecl). Чтобы установить это, откройте свойства своего проекта и перейдите к Свойства конфигурации> C / C ++> Дополнительно и посмотрите на параметр Calling Convention . Если вы вызываете функцию с неправильным соглашением о вызовах, вы полностью испортите стек.

0 голосов
/ 13 декабря 2008

Ошибка выдается, когда объект выходит из области видимости или удаляется.

Всякий раз, когда я сталкивался с этим, это имело отношение к скомпилированной библиотеке, использующей другую версию среды выполнения C ++, чем остальная часть приложения.

0 голосов
/ 12 декабря 2008

Не видя больше кода, трудно дать вам твердый ответ. Однако для отслеживания перезаписи памяти я рекомендую использовать WinDbg (бесплатно от Microsoft, поиск « Средства отладки для Windows »).

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

0 голосов
/ 12 декабря 2008

Ваш файл .lib связан с библиотекой .lib? Я предполагаю из вашего примера, что вы включаете заголовок с объявлением деструктора; без него удаление такого типа разрешено, но может привести к UB (причудливым образом вопреки общему правилу, что что-то должно быть определено перед использованием). Если LIB-файлы не связаны друг с другом, возможно, что у пользовательского operator delete или деструктора есть какие-то странные проблемы с связью, и хотя этого не должно быть, вы никогда не сможете точно сказать, не произойдет ли это.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...