#c #access-violation #heap-corruption
#c #нарушение доступа #повреждение кучи
Вопрос:
Я получаю нарушение доступа в своей программе при запуске некоторого кода, который принадлежит библиотеке. Моя программа статически ссылается на библиотеку. Я могу запускать этот код в других проектах без проблем, но по какой-то причине он вылетает в моей программе. Я поместил код в самое начало программы, чтобы убедиться, что никакой другой код не был выполнен, и он все равно вылетает. Я не думаю, что это проблема с библиотекой, поскольку она отлично работает в других контекстах. Я понятия не имею, почему происходит сбой, и я пытаюсь выяснить это уже две недели. Вот более подробный пост, который я скопировал на страницу библиотеки github:
Я пытаюсь использовать http_listener в проекте MFC, созданном в Visual Studio 2017 с набором инструментов платформы v141. Он работает нормально до тех пор, пока не будет выполнен код, который ссылается на cpprestsdk. cpprestsdk был установлен с помощью vcpkg, который создал cpprestsdk с использованием набора инструментов платформы vc141.
В моем проекте нет известных ранее существовавших проблем с повреждением кучи, поэтому тот факт, что это вызывает повреждение кучи, сбивает с толку.
Вот нарушающая строка кода:
BOOL CAuthenticationServerApp::InitInstance()
{
CWinApp::InitInstance();
utility::string_t port = U("34568");
utility::string_t address = U("http://127.0.0.1:");
address.append(port);
web::uri_builder uri(address);
auto addr = uri.to_uri().to_string();
---->std::unique_ptr<http_listener> listener = std::make_unique<http_listener>(addr);
listener->open().wait();
...
Первое, что моя программа выполняет, это этот код. Перед ним нет другого кода, поэтому ничего, что потенциально могло бы привести к повреждению кучи, поэтому я думаю, что это как-то связано с самой библиотекой.
Сообщение об ошибке:
Исключение, вызванное 0x005B90F8 в AuthenticationServer.exe: 0xC0000005: место записи с нарушением доступа 0x0B39D000. Возникло необработанное исключение: нарушение доступа на запись.
Вот стек вызовов, в котором генерируется исключение. Происходит сбой при попытке объявить переменную в конструкторе http_listener_impl:
AuthenticationServer.exe!std::_Ptr_base<Concurrency::details::_Task_impl<unsigned char> >::_Ptr_base<Concurrency::details::_Task_impl<unsigned char> >() Line 1158 C
AuthenticationServer.exe!std::shared_ptr<Concurrency::details::_Task_impl<unsigned char> >::shared_ptr<Concurrency::details::_Task_impl<unsigned char> >(void * __formal) Line 1277 C
AuthenticationServer.exe!Concurrency::task<unsigned char>::task<unsigned char>() Line 2963 C
AuthenticationServer.exe!Concurrency::task<void>::task<void>() Line 3985 C
AuthenticationServer.exe!web::http::experimental::listener::details::http_listener_impl::http_listener_impl(web::uri address) Line 58 C
AuthenticationServer.exe!utility::details::make_unique<web::http::experimental::listener::details::http_listener_impl,web::uri>(web::uri amp;amp; arg1) Line 389 C
AuthenticationServer.exe!web::http::experimental::listener::http_listener::http_listener(web::uri address) Line 222 C
[External Code]
AuthenticationServer.exe!CAuthenticationServerApp::InitInstance() Line 79 C
AuthenticationServer.exe!AfxWinMain(HINSTANCE__ * hInstance, HINSTANCE__ * hPrevInstance, char * lpCmdLine, int nCmdShow) Line 37 C
AuthenticationServer.exe!WinMain(HINSTANCE__ * hInstance, HINSTANCE__ * hPrevInstance, char * lpCmdLine, int nCmdShow) Line 26 C
[External Code]
Этот код на самом деле работает нормально, если я помещаю его в новый проект MFC или другой проект MFC аналогичного размера. Возможно ли, что проблема в библиотеке, или это как-то связано с моим кодом? В программе есть некоторые глобальные переменные, которые я проверил, и ни одна из них не содержит кода, который выделяет или освобождает память в куче в их конструкторах. Итак, я не знаю, как повреждается куча. Проект ссылается на несколько других библиотек, и я позаботился о том, чтобы все они были созданы с использованием одного и того же набора инструментов платформы. Библиотеки не имеют известных проблем и используются годами. Я поместил код http_listener в другой проект, который почти идентичен этому, с теми же зависимостями, и он работает нормально.
Комментарии:
1. Можете ли вы рассказать нам о библиотеке, как вы ее вызываете, вашем компоновщике и ваших параметрах / процессе связывания?
2. что ж, вот полная ссылка на проблему. Я опубликовал это на странице github для библиотеки, которую я использую. github.com/Microsoft/cpprestsdk/issues/1092
3. Сможете ли вы отредактировать наиболее важные части этого непосредственно в теле вашего сообщения? Вопросы о переполнении стека должны быть полезны сами по себе, даже если связанные ресурсы становятся недоступными по какой-либо причине, например, из-за перегиба ссылок.
4. Я определенно видел повреждение кучи в результате связывания кода, скомпилированного с версией компилятора A, с объектными файлами или библиотеками, скомпилированными с версией компилятора B. В моем случае это произошло бы, когда код, скомпилированный с версией компилятора A, выделил бы объект, а затем код, скомпилированный с версией компилятора B, позже освободил бы объект (я предполагаю, что некоторые детали реализации кучи памяти, включенные статически, изменились между двумя версиями компилятора). Если у вас есть возможность скомпилировать все из исходного кода (вместо того, чтобы полагаться на предоставленные объектные файлы), я рекомендую это.
5. Если ваш код включает файл заголовка из версии, отличной от версии библиотеки, то это может легко вызвать сбой. Возможно, вы случайно поместили более новый / старый файл заголовка в каталог вашего проекта? Если там есть другое объявление http_listener, то все ставки отменяются