Callback FB function lead to crush

General FreeBASIC programming questions.
Post Reply
Iczer
Posts: 99
Joined: Jul 04, 2017 18:09

Callback FB function lead to crush

Post by Iczer »

I used this FB callback for some time and up to curl 7.86.0 it worked without any problems. However after update to curl 7.88.1 it's use lead to crush on call to curl_easy_cleanup(). I'm almost sure it's curl problem but... to be sure:
FB 1.09.0

Code: Select all

Public Function MainDebug2() As Long Export
	' ........................................................................................
	'
	' ........................................................................................
	Dim cURLHandle As CURL Ptr, cURLSList As curl_slist Ptr = NULL, cURLRetValue As Long = 0
	Dim As ZString * 2048 sSourceURL, sCookiesFilePath
	' ........................................................................................
	'
	' ........................................................................................
	sSourceURL = "???"
	sCookiesFilePath = "C:\Temp\_CookiesFileInQuestion.txt"
	' ........................................................................................
	'
	' ........................................................................................
	curl_global_init(CURL_GLOBAL_ALL)
	
	cURLHandle = curl_easy_init()
	
	If cURLHandle = 0 Then
		Print	"x-> cURL Easy Init Fail"
		Return 1
	EndIf
	' ........................................................................................
	'
	' ........................................................................................
	Dim As tagcURLCallBackBuffer Ptr ptInfo = New tagcURLCallBackBuffer(65535)
	' ........................................................................................
	Dim As Long cURLErrorBufferSize		= CURL_ERROR_SIZE
	Dim As ZString Ptr cURLErrorBuffer	= Callocate(cURLErrorBufferSize + 1,1)
	' ........................................................................................
	curl_easy_setopt(cURLHandle, CURLOPT_DEBUGFUNCTION, @cURLCallbackFunc_DebugTraceFuncEL)
	curl_easy_setopt(cURLHandle, CURLOPT_DEBUGDATA, ptInfo)
	' ........................................................................................
	curl_easy_setopt(cURLHandle, CURLOPT_VERBOSE, 1L)
	' ........................................................................................
	curl_easy_setopt(cURLHandle, CURLOPT_URL, @sSourceURL)
	' ........................................................................................
	curl_easy_setopt(cURLHandle, CURLOPT_COOKIESESSION, 1L)
	curl_easy_setopt(cURLHandle, CURLOPT_COOKIEFILE, sCookiesFilePath)
	curl_easy_setopt(cURLHandle, CURLOPT_COOKIEJAR, sCookiesFilePath)
	' ----------------------------------------------------------------------------------------
	'
	' ----------------------------------------------------------------------------------------
	cURLRetValue = curl_easy_perform(cURLHandle)
	' ----------------------------------------------------------------------------------------
	'
	' ----------------------------------------------------------------------------------------
	Print "--> Connection Log Start :"
	Print "--------------------------------------------------------------------------------------------"
	Print *ptInfo->strbuf
	Print "--------------------------------------------------------------------------------------------"
	Print "--> Connection Log End :"
	' ........................................................................................
	Delete ptInfo
	' ----------------------------------------------------------------------------------------
	'
	' ----------------------------------------------------------------------------------------
	Print "> CleanUp - 0"
	
	curl_slist_free_all(cURLSList)
	Sleep(1000,1)
	Print "> CleanUp - 1"
	
	curl_easy_cleanup(cURLHandle) ' <---------------------- crush
	Sleep(1000,1)
	Print "> CleanUp - 2"
	
	DeAllocate(cURLErrorBuffer)	:	cURLErrorBuffer = 0
	Sleep(1000,1)
	Print "> CleanUp - 3"
	
	curl_global_cleanup()
	' ........................................................................................
	Print "--> Done"
	' ----------------------------------------------------------------------------------------
	'
	' ----------------------------------------------------------------------------------------
	return 0
End Function

Code: Select all

Type tagcURLCallBackBuffer
	
	strbuf		As zString Ptr
	size			As size_t = 0
	allocated	As size_t = 0
	
	Declare Sub Append(ByRef psBuffer As ZString Ptr, ByVal iBufferLengh As size_t)
	Declare Sub ReserveSpace(ByVal iBufferLengh As size_t)
	
	Declare Constructor()
	Declare Constructor(ByRef iSizeToAllocate As Integer)
	Declare Constructor(ByRef tcURLCallBackBuffer As tagcURLCallBackBuffer)
	Declare Operator Let(ByRef tcURLCallBackBuffer As tagcURLCallBackBuffer)
	Declare Destructor ()
End Type
' ............................................................................................................
Constructor tagcURLCallBackBuffer
	This.allocated = 7
	This.size		= 0
	This.strbuf		= Callocate(8,1)
End Constructor
' ............................................................................................................
Constructor tagcURLCallBackBuffer(ByRef iSizeToAllocate As Integer)
	This.allocated = iSizeToAllocate
	This.size		= 0
	This.strbuf		= Callocate(iSizeToAllocate + 1,1)
End Constructor
' ............................................................................................................
Constructor tagcURLCallBackBuffer(ByRef tcURLCallBackBuffer As tagcURLCallBackBuffer)
	This.allocated = tcURLCallBackBuffer.allocated
	This.size		= tcURLCallBackBuffer.size
	'This.strbuf		= Callocate(tcURLCallBackBuffer.size + 1,1)	:	memcpy(This.strbuf,tcURLCallBackBuffer.strbuf,tcURLCallBackBuffer.size)
	This.strbuf		= Callocate(tcURLCallBackBuffer.allocated + 1,1)	:	memcpy(This.strbuf,tcURLCallBackBuffer.strbuf,tcURLCallBackBuffer.size)
End Constructor
' ............................................................................................................
Operator tagcURLCallBackBuffer.Let(ByRef tcURLCallBackBuffer As tagcURLCallBackBuffer)
	
	If tcURLCallBackBuffer.size >= This.allocated Then
		This.strbuf		= ReAllocate(This.strbuf,tcURLCallBackBuffer.allocated + 1)	:	Clear(*This.strbuf,0,tcURLCallBackBuffer.allocated + 1)	:	memcpy(This.strbuf,tcURLCallBackBuffer.strbuf,tcURLCallBackBuffer.size)
		This.allocated = tcURLCallBackBuffer.allocated
	Else
		Clear(*This.strbuf,0,This.allocated + 1)	:	memcpy(This.strbuf,tcURLCallBackBuffer.strbuf,tcURLCallBackBuffer.size)
	EndIf
	
	This.size		= tcURLCallBackBuffer.size
	
End Operator
' ............................................................................................................
Destructor tagcURLCallBackBuffer
	This.allocated = 0	:	This.size		= 0	:	*This.strbuf		= ""
	DeAllocate(This.strbuf)	:	This.strbuf		= 0
End Destructor
' ............................................................................................................
It wont crush on cleanup if:
1. comment line : curl_easy_setopt(cURLHandle, CURLOPT_VERBOSE, 1L)
2. comment lines : curl_easy_setopt(cURLHandle, CURLOPT_DEBUGFUNCTION, @cURLCallbackFunc_DebugTraceFuncEL)
curl_easy_setopt(cURLHandle, CURLOPT_DEBUGDATA, ptInfo)
3. comment line : Delete ptInfo

Prototypes:
FB:

Code: Select all

type curl_debug_callback as function(byval handle as CURL ptr, byval type as curl_infotype, byval data as zstring ptr, byval size as uinteger, byval userptr as any ptr) as long
C:

Code: Select all

int debug_callback(CURL *handle,
                   curl_infotype type,
                   char *data,
                   size_t size,
                   void *userptr);

CURLcode curl_easy_setopt(CURL *handle, CURLOPT_DEBUGFUNCTION,
                          debug_callback);
What I want to ask - is there a some errors in function and tagcURLCallBackBuffer ?
Iczer
Posts: 99
Joined: Jul 04, 2017 18:09

Re: Callback FB function lead to crush

Post by Iczer »

Also - this version wont crush for some reason. I just not used NEW allocation and passed pointer to userdata as @tInfo

Code: Select all

Public Function MainDebug2() As Long Export
	' ........................................................................................
	'
	' ........................................................................................
	Dim cURLHandle As CURL Ptr, cURLSList As curl_slist Ptr = NULL, cURLRetValue As Long = 0
	Dim As ZString * 2048 sSourceURL, sCookiesFilePath
	' ........................................................................................
	'
	' ........................................................................................
	sSourceURL = "???"
	sCookiesFilePath = "C:\Temp\_CookiesFileInQuestion.txt"
	' ........................................................................................
	'
	' ........................................................................................
	'Dim As tagcURLCallBackBuffer Ptr ptInfo = New tagcURLCallBackBuffer(65535)
	Dim As tagcURLCallBackBuffer tInfo
	' ........................................................................................
	Dim As Long cURLErrorBufferSize		= CURL_ERROR_SIZE
	Dim As ZString Ptr cURLErrorBuffer	= Callocate(cURLErrorBufferSize + 1,1)
	' ........................................................................................	
	curl_global_init(CURL_GLOBAL_ALL)
	
	cURLHandle = curl_easy_init()
	
	If cURLHandle = 0 Then
		Print	"x-> cURL Easy Init Fail"
		Return 1
	EndIf
	' ........................................................................................
	'
	' ........................................................................................

	curl_easy_setopt(cURLHandle, CURLOPT_DEBUGFUNCTION, @cURLCallbackFunc_DebugTraceFuncEL)
	curl_easy_setopt(cURLHandle, CURLOPT_DEBUGDATA, @tInfo)
	' ........................................................................................
	curl_easy_setopt(cURLHandle, CURLOPT_VERBOSE, 1L)
	' ........................................................................................
	curl_easy_setopt(cURLHandle, CURLOPT_URL, @sSourceURL)
	' ........................................................................................
	curl_easy_setopt(cURLHandle, CURLOPT_COOKIESESSION, 1L)
	curl_easy_setopt(cURLHandle, CURLOPT_COOKIEFILE, sCookiesFilePath)
	curl_easy_setopt(cURLHandle, CURLOPT_COOKIEJAR, sCookiesFilePath)
	' ----------------------------------------------------------------------------------------
	'
	' ----------------------------------------------------------------------------------------
	cURLRetValue = curl_easy_perform(cURLHandle)
	' ----------------------------------------------------------------------------------------
	'
	' ----------------------------------------------------------------------------------------
	Print "--> Connection Log Start :"
	Print "--------------------------------------------------------------------------------------------"
	'Print *ptInfo->strbuf
	Print *tInfo.strbuf
	Print "--------------------------------------------------------------------------------------------"
	Print "--> Connection Log End :"
	' ........................................................................................
	'Delete ptInfo
	' ----------------------------------------------------------------------------------------
	'
	' ----------------------------------------------------------------------------------------
	Print "> CleanUp - 0"
	
	curl_slist_free_all(cURLSList)
	Sleep(1000,1)
	Print "> CleanUp - 1"
	
	curl_easy_cleanup(cURLHandle) ' <---------------------- crush
	Sleep(1000,1)
	Print "> CleanUp - 2"
	
	DeAllocate(cURLErrorBuffer)	:	cURLErrorBuffer = 0
	Sleep(1000,1)
	Print "> CleanUp - 3"
	
	curl_global_cleanup()
	' ........................................................................................
	Print "--> Done"
	' ----------------------------------------------------------------------------------------
	'
	' ----------------------------------------------------------------------------------------
	return 0
End Function
fxm
Moderator
Posts: 12107
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: Callback FB function lead to crush

Post by fxm »

Have you tried putting:
Delete ptInfo
just after:
curl_global_cleanup()
Iczer
Posts: 99
Joined: Jul 04, 2017 18:09

Re: Callback FB function lead to crush

Post by Iczer »

just tried and it not crashed

Code: Select all

	Print "> CleanUp - 0"
	
	curl_slist_free_all(cURLSList)
	Sleep(1000,1)
	Print "> CleanUp - 1"
	
	curl_easy_cleanup(cURLHandle)
	Sleep(1000,1)
	Print "> CleanUp - 2"
	
	DeAllocate(cURLErrorBuffer)	:	cURLErrorBuffer = 0
	Sleep(1000,1)
	Print "> CleanUp - 3"
	
	curl_global_cleanup()
	Sleep(1000,1)
	Print "> CleanUp - 4"
	
	
	Delete ptInfo
	Sleep(1000,1)
	Print "> CleanUp - 5"
	' ........................................................................................
	Print "--> Done"
produced:

Code: Select all

> CleanUp - 0
> CleanUp - 1
> CleanUp - 2
> CleanUp - 3
> CleanUp - 4
> CleanUp - 5
--> Done
Iczer
Posts: 99
Joined: Jul 04, 2017 18:09

Re: Callback FB function lead to crush

Post by Iczer »

I need some help to translate FB snippet to C to demonstrate crush, but my C-skills...

In FreeBasic:

Code: Select all

Type tagcURLCallBackBuffer
	
	strbuf		As ZString Ptr
	size			As ULong = 0
	allocated	As ULong = 0
	
	Declare Constructor()
	Declare Constructor(ByRef iSizeToAllocate As Integer)
	Declare Destructor ()
End Type

Constructor tagcURLCallBackBuffer
	This.allocated = 7
	This.size		= 0
	This.strbuf		= Callocate(8,1)
End Constructor

Constructor tagcURLCallBackBuffer(ByRef iSizeToAllocate As Integer)
	This.allocated = iSizeToAllocate
	This.size		= 0
	This.strbuf		= Callocate(iSizeToAllocate + 1,1)
End Constructor

Destructor tagcURLCallBackBuffer
	This.allocated = 0
	This.size		= 0
	DeAllocate(This.strbuf)	:	This.strbuf		= 0
End Destructor

Function cURLCallbackFunc_DebugTraceFuncEL Cdecl(ByVal handle As CURL Ptr, ByVal itype As curl_infotype, ByVal idata As ZString Ptr, ByVal iSize As size_t, ByVal zBuffer As tagcURLCallBackBuffer Ptr) as Long
	
	Select Case As Const itype
		
		case CURLINFO_TEXT, CURLINFO_HEADER_OUT, CURLINFO_HEADER_IN
			
			Clear(zBuffer->strbuf[zBuffer->size],0,iSize + 1)
			memcpy(@zBuffer->strbuf[zBuffer->size],idata,iSize)
			
			zBuffer->size += iSize
			
	End Select
	
	Return 0
End Function

Function MainDebug3() As Long
	
	Dim cURLHandle As CURL Ptr, cURLRetValue As Long = 0
	Dim As ZString * 256 sSourceURL, sCookiesFilePath
	Dim As tagcURLCallBackBuffer Ptr ptInfo = New tagcURLCallBackBuffer(1000000)
	
	sSourceURL = "???"
	sCookiesFilePath = "C:\Temp\_CookiesFileInQuestion.txt"
	
	remove(@sCookiesFilePath)
	
	Sleep(1000,1)
	
	curl_global_init(CURL_GLOBAL_ALL)
	
	cURLHandle = curl_easy_init()
	
	curl_easy_setopt(cURLHandle, CURLOPT_DEBUGFUNCTION, @cURLCallbackFunc_DebugTraceFuncEL)
	curl_easy_setopt(cURLHandle, CURLOPT_DEBUGDATA, ptInfo)
	curl_easy_setopt(cURLHandle, CURLOPT_VERBOSE, 1L)
	curl_easy_setopt(cURLHandle, CURLOPT_URL, @sSourceURL)
	curl_easy_setopt(cURLHandle, CURLOPT_COOKIESESSION, 1L)
	curl_easy_setopt(cURLHandle, CURLOPT_COOKIEFILE, @sCookiesFilePath)
	curl_easy_setopt(cURLHandle, CURLOPT_COOKIEJAR, @sCookiesFilePath)
	
	cURLRetValue = curl_easy_perform(cURLHandle)
	
	Delete ptInfo
	
	curl_easy_cleanup(cURLHandle)
	
	curl_global_cleanup()
	
	return 0
End Function

MainDebug3()
In C:

Code: Select all

#include <curl/curl.h>
#include "crt/string.bi"
#include "crt/io.bi"

struct tagcURLCallBackBuffer {
  char *strbuf;
  unsigned int size;
  unsigned int allocated;
};

static int cURLCallbackFunc_DebugTraceFuncEL Cdecl(CURL *handle, curl_infotype itype, char *idata, size_t iSize, tagcURLCallBackBuffer *zBuffer)
{
	(void)handle; /* prevent compiler warning */
	
	if (itype == CURLINFO_TEXT || itype = CURLINFO_HEADER_OUT || itype = CURLINFO_HEADER_IN) {
			memset(&zBuffer->strbuf[zBuffer->size],0,iSize + 1);
			memcpy(&zBuffer->strbuf[zBuffer->size],idata,iSize);
			zBuffer->size += iSize;
			}
	
	Return 0;
}


static void MainDebug3()
{
	CURL *cURLHandle;
	CURLcode cURLRetValue;
	tagcURLCallBackBuffer ptInfo;
	
	ptInfo->allocated = 1000000;
	ptInfo->size = 0;
	ptInfo->strbuf = calloc(1, ptInfo->allocated);
	
	remove(&"C:\Temp\_CookiesFileInQuestion.txt");
	
	Sleep(1000);
	
	curl_global_init(CURL_GLOBAL_ALL);
	
	cURLHandle = curl_easy_init();
	
	curl_easy_setopt(cURLHandle, CURLOPT_DEBUGFUNCTION, @cURLCallbackFunc_DebugTraceFuncEL);
	curl_easy_setopt(cURLHandle, CURLOPT_DEBUGDATA, &ptInfo);
	curl_easy_setopt(cURLHandle, CURLOPT_VERBOSE, 1L);
	curl_easy_setopt(cURLHandle, CURLOPT_URL, "???");
	curl_easy_setopt(cURLHandle, CURLOPT_COOKIESESSION, 1L);
	curl_easy_setopt(cURLHandle, CURLOPT_COOKIEFILE, "C:\Temp\_CookiesFileInQuestion.txt");
	curl_easy_setopt(cURLHandle, CURLOPT_COOKIEJAR, "C:\Temp\_CookiesFileInQuestion.txt");
	
	cURLRetValue = curl_easy_perform(cURLHandle);
	
	free(ptInfo->strbuf);
	ptInfo->allocated = 0;
	ptInfo->size = 0;
	ptInfo->strbuf = null;
	
	curl_easy_cleanup(cURLHandle);
	
	curl_global_cleanup();
}

MainDebug3()
Post Reply