I’m still having trouble with the same application as mentioned here
Delphi CopyMemory vs C++ memcpy
Whilst I had a satisfactory answer to my original question, I’m struggling to understand a subsequent crash…
I have a delphi app, that uses a networking library and a server app (that exists somewhere on the work) which uses the same networking library. The networking library appears to work correctly is written in C++ (not by me). The library handles all the communications for me, so I need only supply an array of bytes to the library. I can successfully send to, and receive data from my server – And the data is correct in both directions.
I receive data from the server in a helper procedure. The procedure runs correctly to the “end;” (quite literally). The procedure ends (I’m successfully through all comms at this stage and now solely concerned with Delphi), and the debugger takes me into _DynArrayClear – where my application crashes. From the help I read “The Delphi compiler automatically inserts calls to this function whenever appropriate.”
I’ll add some more background if it helps… The networking library populates a byte array which is defined as void *data in a content struct (see below)
struct content {
void *data;
int size;
}
I believe all I need to do, once this data is populated is perform a CopyMemory operation in Delphi…
Could someone please help me understand what I’ve done wrong?!
// should be: function THelper.ReceiveData: TBytes; -
// but my crash happens with either a function or a procedure
procedure THelper.ReceiveData;
var
lMsg: Pointer;
lSize: Integer;
lData: TBytes;
lRecvResult: Integer;
begin
lMsg := nil;
// Remote call to receive data returns an integer indicating success
lRecvResult := lib_receive_data(lMsg, Integer(Flags));
TUtils.CheckError(lRecvResult);
SetLength(lData, 5);
CopyMemory(@lData[0], lMsg, 5); // where 5 is the length of data to copy
end; // takes me into _DynArrayClear
// The application crashes after exiting _DynArrayClear
// For clarity @@noFinalize is entered at line 20795
// I get all the way to the 'end;' at line 20801 in System.pas
//
// Then from _DynArrayClear I press F7 and immediately get access violation at 0xcdcdcdcd: read address of 0xcdcdcdcd and the following is the call stack...
:7789fada ntdll.NtQueryInformationProcess + 0x12
:77890143 ntdll.KiUserExceptionDispatcher + 0xf
:778c6a8b ; ntdll.dll
:77890143 ntdll.KiUserExceptionDispatcher + 0xf
:778c6a8b ; ntdll.dll
:77890143 ntdll.KiUserExceptionDispatcher + 0xf
:778c6a8b ; ntdll.dll
:77890143 ntdll.KiUserExceptionDispatcher + 0xf
:778c6a8b ; ntdll.dll
:77890143 ntdll.KiUserExceptionDispatcher + 0xf
:778c6a8b ; ntdll.dll
:77890143 ntdll.KiUserExceptionDispatcher + 0xf
:778c6a8b ; ntdll.dll
:77890143 ntdll.KiUserExceptionDispatcher + 0xf
:778c6a8b ; ntdll.dll
What is the first parameter of
lib_receive_data()actually declared as? You are passing in a localPointervariable that is initially set tonil, so I assume the parameter is avarthat get assigned some meaningful memory address whenlib_receive_data()exits? What doeslib_receive_data()actually output?You meantion a
contentstructure, but I don’t see you using it anywhere. And you declare anlSizevariable, but you do not use it, either. What does the documentation forlib_receive_data()actually say?Are you absolutely sure that
lMsgalways points to a bufer that contains at least 5 bytes? What does the return value oflib_receive_data()represent? It is a byte count, or just a status code?The fact that you are getting errors at an address like
0xcdcdcdcdsuggests you are likely trampling theTBytesmemory, which would lead to a crash in_DynArrayClear()when theTBytesis being deallocated.