2017-07-26 9 views
0

Dans ma bibliothèque (qui remplace les opérateurs globaux new/delete), j'utilise une autre bibliothèque externe (casablanca pplx). Cette bibliothèque externe n'inclut pas les opérateurs new/delete remplacés (j'ai vérifié en utilisant l'option show includes de Visual studio).new/delete mismatch

Certains objets de cette bibliothèque externe (comme flux ou exceptions) sont créées en utilisant la valeur par défaut new[] opérateur (qui appelle mon opérateur new remplacé) et sont détruits à l'aide de la valeur par défaut delete[] opérateur (qui doesn ne pas appeler mon opérateur delete remplacé). Ceci entraîne une erreur de protection générale .

Qu'est-ce qui peut expliquer ce comportement?

J'utilise Visual Studio 2012.

Exemple code source (google.fr obtenir en utilisant le casablanca client http):

web::http::client::http_client_config config; 
config.set_timeout(std::chrono::seconds(10)); 
utility::string_t uri = L"http://www.google.fr"; 
web::http::client::http_client client(uri, config); 
web::http::http_request request(web::http::methods::GET); 

client.request(request).then([uri](web::http::http_response response) { 
    unsigned short statusCode = response.status_code(); 
    if (statusCode == 200) 
    { 
     concurrency::streams::stringstreambuf stream; 
     return response.body().read_to_end(stream).then([stream](size_t) { 
      std::string responseText = stream.collection(); 
     }); // crash here (stream destructor) 
    } 
}); 

Nouveau callstack:

Application64_d.dll!operator new(unsigned __int64 iSize) Line 262 C++ // My replaced new operator 
Application64_d.dll!operator new[](unsigned __int64 count) Line 7 C++ // C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\crt\src\newaop.cpp 
Application64_d.dll!Concurrency::streams::details::basic_producer_consumer_buffer<unsigned char>::_block::_block(unsigned __int64 size) Line 437 C++ 
Application64_d.dll!std::_Ref_count_obj<Concurrency::streams::details::basic_producer_consumer_buffer<unsigned char>::_block>::_Ref_count_obj<Concurrency::streams::details::basic_producer_consumer_buffer<unsigned char>::_block><unsigned __int64 & __ptr64>(unsigned __int64 & _V0) Line 873 C++ 
Application64_d.dll!std::make_shared<Concurrency::streams::details::basic_producer_consumer_buffer<unsigned char>::_block,unsigned __int64 & __ptr64>(unsigned __int64 & _V0) Line 972 C++ 
Application64_d.dll!Concurrency::streams::details::basic_producer_consumer_buffer<unsigned char>::_alloc(unsigned __int64 count) Line 165 C++ 
Application64_d.dll!Concurrency::streams::details::streambuf_state_manager<unsigned char>::alloc(unsigned __int64 count) Line 651 C++ 
Application64_d.dll!Concurrency::streams::streambuf<unsigned char>::alloc(unsigned __int64 count) Line 993 C++ 
Application64_d.dll!web::http::client::details::winhttp_client::completion_callback(void * hRequestHandle, unsigned __int64 context, unsigned long statusCode, void * statusInfo, unsigned long statusInfoLength) Line 1167 C++ 
winhttp.dll!00007ff83259db67() Unknown 
winhttp.dll!00007ff83259d87a() Unknown 
winhttp.dll!00007ff832599fe5() Unknown 
Application64_d.dll!web::http::client::details::winhttp_client::read_next_response_chunk(web::http::client::details::winhttp_request_context * pContext, unsigned long bytesRead, bool firstRead) Line 693 C++ 
Application64_d.dll!web::http::client::details::winhttp_client::completion_callback(void * hRequestHandle, unsigned __int64 context, unsigned long statusCode, void * statusInfo, unsigned long statusInfoLength) Line 1156 C++ 
winhttp.dll!00007ff83259db67() Unknown 
winhttp.dll!00007ff8325c653d() Unknown 
Application64_d.dll!web::http::client::details::winhttp_client::completion_callback(void * hRequestHandle, unsigned __int64 context, unsigned long statusCode, void * statusInfo, unsigned long statusInfoLength) Line 1051 C++ 
winhttp.dll!00007ff83259db67() Unknown 
winhttp.dll!00007ff8325a20b7() Unknown 
winhttp.dll!00007ff8325958a0() Unknown 
winhttp.dll!00007ff832594699() Unknown 
ntdll.dll!00007ff839723021() Unknown 
ntdll.dll!00007ff839721989() Unknown 
kernel32.dll!00007ff8392c2774() Unknown 
ntdll.dll!00007ff839750d51() Unknown 

Supprimer callstack:

msvcr110d.dll!operator delete(void * pUserData) Line 52 C++ // C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\crt\src\dbgdel.cpp 
msvcr110d.dll!operator delete[](void * p) Line 22 C++ // C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\crt\src\delete2.cpp 
Application64_d.dll!Concurrency::streams::details::basic_producer_consumer_buffer<unsigned char>::_block::~_block() Line 443 C++ 
Application64_d.dll!Concurrency::streams::details::basic_producer_consumer_buffer<unsigned char>::_block::`scalar deleting destructor'(unsigned int) C++ 
Application64_d.dll!std::_Ref_count_obj<Concurrency::streams::details::basic_producer_consumer_buffer<unsigned char>::_block>::_Destroy() Line 885 C++ 
Application64_d.dll!std::_Ref_count_base::_Decref() Line 121 C++ 
Application64_d.dll!std::_Ptr_base<Concurrency::streams::details::basic_producer_consumer_buffer<unsigned char>::_block>::_Decref() Line 347 C++ 
Application64_d.dll!std::shared_ptr<Concurrency::streams::details::basic_producer_consumer_buffer<unsigned char>::_block>::~shared_ptr<Concurrency::streams::details::basic_producer_consumer_buffer<unsigned char>::_block>() Line 624 C++ 
Application64_d.dll!std::shared_ptr<Concurrency::streams::details::basic_producer_consumer_buffer<unsigned char>::_block>::`scalar deleting destructor'(unsigned int) C++ 
Application64_d.dll!std::allocator<std::shared_ptr<Concurrency::streams::details::basic_producer_consumer_buffer<unsigned char>::_block> >::destroy<std::shared_ptr<Concurrency::streams::details::basic_producer_consumer_buffer<unsigned char>::_block> >(std::shared_ptr<Concurrency::streams::details::basic_producer_consumer_buffer<unsigned char>::_block> * _Ptr) Line 624 C++ 
Application64_d.dll!std::allocator_traits<std::allocator<std::shared_ptr<Concurrency::streams::details::basic_producer_consumer_buffer<unsigned char>::_block> > >::destroy<std::shared_ptr<Concurrency::streams::details::basic_producer_consumer_buffer<unsigned char>::_block> >(std::allocator<std::shared_ptr<Concurrency::streams::details::basic_producer_consumer_buffer<unsigned char>::_block> > & _Al, std::shared_ptr<Concurrency::streams::details::basic_producer_consumer_buffer<unsigned char>::_block> * _Ptr) Line 758 C++ 
Application64_d.dll!std::_Wrap_alloc<std::allocator<std::shared_ptr<Concurrency::streams::details::basic_producer_consumer_buffer<unsigned char>::_block> > >::destroy<std::shared_ptr<Concurrency::streams::details::basic_producer_consumer_buffer<unsigned char>::_block> >(std::shared_ptr<Concurrency::streams::details::basic_producer_consumer_buffer<unsigned char>::_block> * _Ptr) Line 910 C++ 
Application64_d.dll!std::deque<std::shared_ptr<Concurrency::streams::details::basic_producer_consumer_buffer<unsigned char>::_block>,std::allocator<std::shared_ptr<Concurrency::streams::details::basic_producer_consumer_buffer<unsigned char>::_block> > >::pop_front() Line 1476 C++ 
Application64_d.dll!Concurrency::streams::details::basic_producer_consumer_buffer<unsigned char>::update_read_head(unsigned __int64 count) Line 644 C++ 
Application64_d.dll!Concurrency::streams::details::basic_producer_consumer_buffer<unsigned char>::read(unsigned char * ptr, unsigned __int64 count, bool advance) Line 620 C++ 
Application64_d.dll!<lambda_1f1656160f66eb3ff369c30cc6352caf>::operator()() Line 279 C++ 
Application64_d.dll!std::_Callable_obj<<lambda_1f1656160f66eb3ff369c30cc6352caf>,0>::_ApplyX<void>() Line 431 C++ 
Application64_d.dll!std::_Func_impl<std::_Callable_obj<<lambda_1f1656160f66eb3ff369c30cc6352caf>,0>,std::allocator<std::_Func_class<void,std::_Nil,std::_Nil,std::_Nil,std::_Nil,std::_Nil,std::_Nil,std::_Nil> >,void,std::_Nil,std::_Nil,std::_Nil,std::_Nil,std::_Nil,std::_Nil,std::_Nil>::_Do_call() Line 239 C++ 
Application64_d.dll!std::_Func_class<void,std::_Nil,std::_Nil,std::_Nil,std::_Nil,std::_Nil,std::_Nil,std::_Nil>::operator()() Line 514 C++ 
Application64_d.dll!Concurrency::streams::details::basic_producer_consumer_buffer<unsigned char>::_request::complete() Line 543 C++ 
Application64_d.dll!Concurrency::streams::details::basic_producer_consumer_buffer<unsigned char>::fulfill_outstanding() Line 424 C++ 
Application64_d.dll!Concurrency::streams::details::basic_producer_consumer_buffer<unsigned char>::_close_write() Line 360 C++ 
Application64_d.dll!Concurrency::streams::details::streambuf_state_manager<unsigned char>::close(int mode) Line 413 C++ 
Application64_d.dll!Concurrency::streams::streambuf<unsigned char>::close(int mode) Line 960 C++ 
Application64_d.dll!Concurrency::streams::basic_ostream<unsigned char>::close() Line 151 C++ 
Application64_d.dll!web::http::details::http_msg_base::_complete(unsigned __int64 body_size, const std::exception_ptr & exceptionPtr) Line 181 C++ 
Application64_d.dll!web::http::client::details::request_context::complete_request(unsigned __int64 body_size) Line 119 C++ 
Application64_d.dll!web::http::client::details::winhttp_client::completion_callback(void * hRequestHandle, unsigned __int64 context, unsigned long statusCode, void * statusInfo, unsigned long statusInfoLength) Line 1194 C++ 
winhttp.dll!00007ff83259db67() Unknown 
winhttp.dll!00007ff83259d87a() Unknown 
winhttp.dll!00007ff832599fe5() Unknown 
Application64_d.dll!web::http::client::details::winhttp_client::read_next_response_chunk(web::http::client::details::winhttp_request_context * pContext, unsigned long bytesRead, bool firstRead) Line 693 C++ 
Application64_d.dll!web::http::client::details::winhttp_client::completion_callback(void * hRequestHandle, unsigned __int64 context, unsigned long statusCode, void * statusInfo, unsigned long statusInfoLength) Line 1231 C++ 
winhttp.dll!00007ff83259b6aa() Unknown 
Application64_d.dll!web::http::client::details::winhttp_client::completion_callback(void * hRequestHandle, unsigned __int64 context, unsigned long statusCode, void * statusInfo, unsigned long statusInfoLength) Line 1174 C++ 
winhttp.dll!00007ff83259db67() Unknown 
winhttp.dll!00007ff8325955e7() Unknown 
winhttp.dll!00007ff832594699() Unknown 
ntdll.dll!00007ff839723021() Unknown 
ntdll.dll!00007ff839721989() Unknown 
kernel32.dll!00007ff8392c2774() Unknown 
ntdll.dll!00007ff839750d51() Unknown 

nouvelles et supprimer les opérateurs:

inline void* operator new (::size_t size); 
inline void operator delete (void* ptr); 
inline void* operator new[] (::size_t size); 
inline void operator delete[] (void* ptr); 
+0

Si vous vérifiez la pile d'appel de l'incident, vous pouvez extraire la signature de l'opérateur d'effacement d'exécution. Peut-être n'avez-vous pas écrasé toutes les nouvelles fonctions possibles de suppression/suppression. – geza

+0

Oui j'ai ajouté les callstacks. Et j'ai ajouté les fichiers de nouveaux et supprimer des appels. Je ne comprends pas pourquoi le nouveau personnalisé est appelé, et la suppression personnalisée non. Je suppose que le nouvel op de runtime est compilé dans mon application (dans mon Application64_d.dll), mais pourquoi l'opération de suppression d'exécution n'est pas? –

+0

Avez-vous remplacé 'delete []'? – geza

Répondre

0

Dans Visual Studio 2013 (et plus), l'opérateur par défaut delete[] ne se construit pas dans le binaire de l'application (par opposition à la valeur par défaut new, new[] et Opérateurs delete). Il est appelé directement à partir de msvcr110d.dll.

Lorsque le mot-clé en ligne est utilisé, les opérateurs new[] et delete[] remplacés ne sont pas utilisés par défaut dans toute l'application (par opposition aux opérateurs new et delete) à moins que nous inclure explicitement l'en-tête.
L'opérateur par défaut new[](construit dans le binaire de l'application) appelle l'opérateur new remplacé.
Mais le défaut delete[] opérateur (appelé directement à partir msvcr110d.dll) ne trouve pas l'opérateur delete remplacé et utiliser la valeur par défaut delete opérateur (de msvcr110d.dll).

Pour ma solution, j'ai supprimé le mot-clé en ligne et ai placé les opérateurs dans un fichier source.
Ce bogue a été corrigé et ne devrait pas apparaître dans Visual Studio 2015 (et plus récent).