This is a random issue that occurs approximately 3 to 4 times out of every 10 attempts.
Wireshark_trace.zip (2.3 MB)
I tested Stack Overflow; heap corruption is not happening.
void vApplicationMallocFailedHook( void )
{
/* vApplicationMallocFailedHook() will only be called if
configUSE_MALLOC_FAILED_HOOK is set to 1 in FreeRTOSConfig.h. It is a hook
function that will get called if a call to pvPortMalloc() fails.
pvPortMalloc() is called internally by the kernel whenever a task, queue,
timer or semaphore is created. It is also called by various parts of the
demo application. If heap_1.c or heap_2.c are used, then the size of the
heap available to pvPortMalloc() is defined by configTOTAL_HEAP_SIZE in
FreeRTOSConfig.h, and the xPortGetFreeHeapSize() API function can be used
to query the size of free heap space that remains (although it does not
provide information on how the remaining heap might be fragmented). */
printf("Malloc failed!\n");
taskDISABLE_INTERRUPTS();
for( ;; );
} /*end of vApplicationMallocFailedHook()*/
void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName )
{
( void ) pcTaskName;
( void ) pxTask;
/* Run time stack overflow checking is performed if
configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook
function is called if a stack overflow is detected. */
printf("Stack overflow in task: %s\n", pcTaskName);
taskDISABLE_INTERRUPTS();
for( ;; );
} /*end of vApplicationStackOverflowHook()*/
---------------------------------------------------------------------------------------------------
static BaseType_t prvStoreFilePrep( FTPClient_t *pxClient, char *pcFileName )
{
BaseType_t xResult;
FF_FILE *pxNewHandle;
size_t uxFileSize = 0ul;
int iErrorNo;
/* Close previous handle (if any) and reset file transfer parameters. */
prvTransferCloseFile( pxClient );
xMakeAbsolute( pxClient, pxClient->pcFileName, sizeof( pxClient->pcFileName ), pcFileName );
pxNewHandle = NULL;
if( pxClient->ulRestartOffset != 0 )
{
size_t uxOffset = pxClient->ulRestartOffset;
int32_t lRc;
printf("[FTP] Append mode. Restart offset = %lu\n", pxClient->ulRestartOffset);
printf("[FTP] Opening file: %s in 'ab' mode\n", pxClient->pcFileName);
pxClient->ulRestartOffset = 0ul; /* Only use 1 time. */
pxNewHandle = ff_fopen( pxClient->pcFileName, "ab" );
if( pxNewHandle != NULL )
{
uxFileSize = pxNewHandle->ulFileSize;
if( uxOffset <= uxFileSize )
{
lRc = ff_fseek( pxNewHandle, uxOffset, FF_SEEK_SET );
}
else
{
/* Won't even try to seek after EOF */
lRc = -pdFREERTOS_ERRNO_EINVAL;
}
if( lRc != 0 )
{
BaseType_t xLength;
xLength = snprintf( pcCOMMAND_BUFFER, sizeof( pcCOMMAND_BUFFER ),
"450 Seek invalid %u length %u\r\n",
( unsigned ) uxOffset, ( unsigned ) uxFileSize );
/* "Requested file action not taken". */
prvSendReply( pxClient->xSocket, pcCOMMAND_BUFFER, xLength );
FreeRTOS_printf( ( "ftp::storeFile: create %s: Seek %u length %u\n",
pxClient->pcFileName, ( unsigned ) uxOffset, ( unsigned ) uxFileSize ) );
ff_fclose( pxNewHandle );
pxNewHandle = NULL;
}
}
}
else
{
pxNewHandle = ff_fopen( pxClient->pcFileName, "wb" );
}
if( pxNewHandle == NULL )
{
iErrorNo = stdioGET_ERRNO();
if( iErrorNo == pdFREERTOS_ERRNO_ENOSPC )
{
prvSendReply( pxClient->xSocket, REPL_552, 0 );
}
else
{
/* "Requested file action not taken". */
prvSendReply( pxClient->xSocket, REPL_450, 0 );
}
FreeRTOS_printf( ( "ftp::storeFile: create %s: %s (errno %d)\n",
pxClient->pcFileName,
( const char* ) strerror( iErrorNo ), iErrorNo ) );
xResult = pdFALSE;
}
else
{
if( pxClient->bits1.bIsListen )
{
/* True if PASV is used. */
snprintf( pxClient->pcConnectionAck, sizeof( pxClient->pcConnectionAck ),
"150 Accepted data connection from %%xip:%%u\r\n" );
prvTransferCheck( pxClient );
}
else
{
BaseType_t xLength;
xLength = snprintf( pcCOMMAND_BUFFER, sizeof( pcCOMMAND_BUFFER ), "150 Opening BIN connection to store file\r\n" );
prvSendReply( pxClient->xSocket, pcCOMMAND_BUFFER, xLength );
pxClient->pcConnectionAck[ 0 ] = '\0';
prvTransferStart( pxClient ); /* Now active connect. */
}
pxClient->pxWriteHandle = pxNewHandle;
/* To get some statistics about the performance. */
pxClient->xStartTime = xTaskGetTickCount( );
xResult = pdTRUE;
}
return xResult;
}
-------------------------------------------------------------------------------------------------------
static BaseType_t prvStoreFileWork( FTPClient_t *pxClient )
{
BaseType_t xRc, xWritten;
int error = 0;
/* Read from the data socket until all has been read or until a negative value
is returned. */
for( ; ; )
{
char *pcBuffer;
/* The "zero-copy" method: */
xRc = FreeRTOS_recv( pxClient->xTransferSocket, ( void * ) &pcBuffer,
0x20000u, FREERTOS_ZERO_COPY | FREERTOS_MSG_DONTWAIT );
if( xRc <= 0 )
{
break;
}
pxClient->ulRecvBytes += xRc;
xWritten = ff_fwrite( pcBuffer, 1, xRc, pxClient->pxWriteHandle );
FreeRTOS_recv( pxClient->xTransferSocket, ( void * ) NULL, xRc, 0 );
if( xWritten != xRc )
{
error = stdioGET_ERRNO();
printf("error: %d\n", error);
xRc = -1;
/* bHadError: a transfer got aborted because of an error. */
pxClient->bits1.bHadError = pdTRUE_UNSIGNED;
break;
}
}
return xRc;
}
Above the function, I added print statements inside the condition if( pxClient->ulRestartOffset != 0 ), but nothing is being printed there. The output is only appearing in the function prvStoreFileWork.
Output is:
error: 29
Please let me know if there’s anything I might be missing or doing incorrectly.