0

I'm struggling with periodic access violations when setting up a TIdHTTP object. I'm using the following code:

TIdHTTP* httpClient = new TIdHTTP(Application->MainForm);
httpClient->HTTPOptions = (httpClient->HTTPOptions >> hoForceEncodeParams);
httpClient->HTTPOptions = (httpClient->HTTPOptions << hoKeepOrigProtocol);
httpClient->HTTPOptions = (httpClient->HTTPOptions << hoInProcessAuth);
httpClient->Request->ContentType = L"application/json";
httpClient->Request->CharSet = L"UTF-8";

TIdSSLIOHandlerSocketOpenSSL* sslIOHandler = new TIdSSLIOHandlerSocketOpenSSL;
sslIOHandler->SSLOptions->SSLVersions = TIdSSLVersions() << sslvTLSv1 << sslvTLSv1_1 << sslvTLSv1_2;

httpClient->IOHandler = sslIOHandler;

httpClient->Request->BasicAuthentication = false;
httpClient->Request->Authentication = new TIdSSPINTLMAuthentication;
httpClient->Request->Username = connectionInfo->AuthUsername;
httpClient->Request->Password = connectionInfo->AuthPassword;

// Make a request from a REST API

delete sslIOHandler;
delete httpClient;

This code runs in a thread (TThread). There could be several threads active at any given time, making seperate requests. As each request is completed, the thread is destroyed.

This code works most of the time, but after running for a seemingly random amount of time will start throwing access violations, usually in the form:

Access violation at address 5016C927 in module 'rtl210.bpl'. Read of address 00000008

Once access violations start, all subsequent threads will throw similar access violations. The only way to get things back on track is to shutdown the application and restart.

I'm using C++Builder XE7, with the version of Indy which shipped with the compiler (Indy 10.6.1.5182 ???)

So far I have been unable to replicate this problem in the debugger to get any additional information.

Any ideas what might be causing the access violation?

  • 1
    What does your debugger tell you? Also, I don't see why you need to use `new` and `delete` here. – Kevin Jun 19 '19 at 16:11
  • @Kevin I haven't been able to replicate the problem in the debugger. – Jonathan Wiens Jun 19 '19 at 16:15
  • _"I'm using C++Builder XE7"_ That's quite old. – πάντα ῥεῖ Jun 19 '19 at 16:15
  • 1
    There is no need to assign an `Owner` if you are going to manage the lifetime manually, *especially* if the `Owner` belongs to another thread. The RTL's object ownership model is not thread-safe. Set the `Owner` to NULL, and use a smart pointer (`std::auto_ptr` prior to C++11, `std::unique_ptr` in C++11 onwards). After making that change, if you are still getting the AV, the error message suggests a NULL pointer is being accessed, so debug your code to find it. You have the exact address of the code that causes the AV, jump to that address in the debugger and look at what code is running there – Remy Lebeau Jun 19 '19 at 16:18
  • Based on the address, I would guess that you're accessing something through a null pointer. The two most likely culprits are lack of synchronisation and flawed lifetime management. Actually, since you can't replicate in debug, the *three* most likely culprits are uninitialised variables and the two previous factors. – molbdnilo Jun 19 '19 at 16:19

1 Answers1

0

As per the comment by Remy Lebeau, the solution was to remove the owner from the TIdHTTP object:

Change

TIdHTTP* httpClient = new TIdHTTP(Application->MainForm);

to

TIdHTTP* httpClient = new TIdHTTP(NULL);