Skip to content

Commit

Permalink
Replace sprintf with snprintf (#802)
Browse files Browse the repository at this point in the history
This change necessitates the introduction of 2 new APIs:

void vTaskListTasks( char * pcWriteBuffer, size_t uxBufferLength );
void vTaskGetRunTimeStatistics( char * pcWriteBuffer, size_t uxBufferLength );

These 2 APIs behave exactly as vTaskList and vTaskGetRunTimeStats
except the fact that they take the length of the pcWriteBuffer as the
second argument to ensure that we do not write past the buffer.

vTaskList and vTaskGetRunTimeStats assume that the length of the
buffer is configSTATS_BUFFER_MAX_LENGTH which defaults to 0xFFFF.
This is done to ensure that the existing applications do not break.
New applications should use the new APIs to avoid memory corruption.
  • Loading branch information
aggarg authored Sep 26, 2023
1 parent 84bdb05 commit 96d6190
Show file tree
Hide file tree
Showing 3 changed files with 329 additions and 65 deletions.
20 changes: 12 additions & 8 deletions include/FreeRTOS.h
Original file line number Diff line number Diff line change
Expand Up @@ -2154,20 +2154,20 @@
#define traceRETURN_vTaskExitCriticalFromISR()
#endif

#ifndef traceENTER_vTaskList
#define traceENTER_vTaskList( pcWriteBuffer )
#ifndef traceENTER_vTaskListTasks
#define traceENTER_vTaskListTasks( pcWriteBuffer, uxBufferLength )
#endif

#ifndef traceRETURN_vTaskList
#define traceRETURN_vTaskList()
#ifndef traceRETURN_vTaskListTasks
#define traceRETURN_vTaskListTasks()
#endif

#ifndef traceENTER_vTaskGetRunTimeStats
#define traceENTER_vTaskGetRunTimeStats( pcWriteBuffer )
#ifndef traceENTER_vTaskGetRunTimeStatistics
#define traceENTER_vTaskGetRunTimeStatistics( pcWriteBuffer, uxBufferLength )
#endif

#ifndef traceRETURN_vTaskGetRunTimeStats
#define traceRETURN_vTaskGetRunTimeStats()
#ifndef traceRETURN_vTaskGetRunTimeStatistics
#define traceRETURN_vTaskGetRunTimeStatistics()
#endif

#ifndef traceENTER_uxTaskResetEventItemValue
Expand Down Expand Up @@ -2686,6 +2686,10 @@
#endif
#endif

#ifndef configSTATS_BUFFER_MAX_LENGTH
#define configSTATS_BUFFER_MAX_LENGTH 0xFFFF
#endif

#ifndef configSTACK_DEPTH_TYPE

/* Defaults to uint16_t for backward compatibility, but can be overridden
Expand Down
136 changes: 130 additions & 6 deletions include/task.h
Original file line number Diff line number Diff line change
Expand Up @@ -2074,6 +2074,60 @@ UBaseType_t uxTaskGetSystemState( TaskStatus_t * const pxTaskStatusArray,
const UBaseType_t uxArraySize,
configRUN_TIME_COUNTER_TYPE * const pulTotalRunTime ) PRIVILEGED_FUNCTION;

/**
* task. h
* @code{c}
* void vTaskListTasks( char *pcWriteBuffer, size_t uxBufferLength );
* @endcode
*
* configUSE_TRACE_FACILITY and configUSE_STATS_FORMATTING_FUNCTIONS must
* both be defined as 1 for this function to be available. See the
* configuration section of the FreeRTOS.org website for more information.
*
* NOTE 1: This function will disable interrupts for its duration. It is
* not intended for normal application runtime use but as a debug aid.
*
* Lists all the current tasks, along with their current state and stack
* usage high water mark.
*
* Tasks are reported as blocked ('B'), ready ('R'), deleted ('D') or
* suspended ('S').
*
* PLEASE NOTE:
*
* This function is provided for convenience only, and is used by many of the
* demo applications. Do not consider it to be part of the scheduler.
*
* vTaskListTasks() calls uxTaskGetSystemState(), then formats part of the
* uxTaskGetSystemState() output into a human readable table that displays task:
* names, states, priority, stack usage and task number.
* Stack usage specified as the number of unused StackType_t words stack can hold
* on top of stack - not the number of bytes.
*
* vTaskListTasks() has a dependency on the snprintf() C library function that might
* bloat the code size, use a lot of stack, and provide different results on
* different platforms. An alternative, tiny, third party, and limited
* functionality implementation of snprintf() is provided in many of the
* FreeRTOS/Demo sub-directories in a file called printf-stdarg.c (note
* printf-stdarg.c does not provide a full snprintf() implementation!).
*
* It is recommended that production systems call uxTaskGetSystemState()
* directly to get access to raw stats data, rather than indirectly through a
* call to vTaskListTasks().
*
* @param pcWriteBuffer A buffer into which the above mentioned details
* will be written, in ASCII form. This buffer is assumed to be large
* enough to contain the generated report. Approximately 40 bytes per
* task should be sufficient.
*
* @param uxBufferLength Length of the pcWriteBuffer.
*
* \defgroup vTaskListTasks vTaskListTasks
* \ingroup TaskUtils
*/
void vTaskListTasks( char * pcWriteBuffer,
size_t uxBufferLength ) PRIVILEGED_FUNCTION;

/**
* task. h
* @code{c}
Expand All @@ -2084,6 +2138,11 @@ UBaseType_t uxTaskGetSystemState( TaskStatus_t * const pxTaskStatusArray,
* both be defined as 1 for this function to be available. See the
* configuration section of the FreeRTOS.org website for more information.
*
* WARN: This function assumes that the pcWriteBuffer is of length
* configSTATS_BUFFER_MAX_LENGTH. This function is there only for
* backward compatibility. New applications are recommended to
* use vTaskListTasks and supply the length of the pcWriteBuffer explicitly.
*
* NOTE 1: This function will disable interrupts for its duration. It is
* not intended for normal application runtime use but as a debug aid.
*
Expand All @@ -2104,10 +2163,10 @@ UBaseType_t uxTaskGetSystemState( TaskStatus_t * const pxTaskStatusArray,
* Stack usage specified as the number of unused StackType_t words stack can hold
* on top of stack - not the number of bytes.
*
* vTaskList() has a dependency on the sprintf() C library function that might
* vTaskList() has a dependency on the snprintf() C library function that might
* bloat the code size, use a lot of stack, and provide different results on
* different platforms. An alternative, tiny, third party, and limited
* functionality implementation of sprintf() is provided in many of the
* functionality implementation of snprintf() is provided in many of the
* FreeRTOS/Demo sub-directories in a file called printf-stdarg.c (note
* printf-stdarg.c does not provide a full snprintf() implementation!).
*
Expand All @@ -2123,7 +2182,66 @@ UBaseType_t uxTaskGetSystemState( TaskStatus_t * const pxTaskStatusArray,
* \defgroup vTaskList vTaskList
* \ingroup TaskUtils
*/
void vTaskList( char * pcWriteBuffer ) PRIVILEGED_FUNCTION; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
#define vTaskList( pcWriteBuffer ) vTaskListTasks( pcWriteBuffer, configSTATS_BUFFER_MAX_LENGTH )

/**
* task. h
* @code{c}
* void vTaskGetRunTimeStatistics( char *pcWriteBuffer, size_t uxBufferLength );
* @endcode
*
* configGENERATE_RUN_TIME_STATS and configUSE_STATS_FORMATTING_FUNCTIONS
* must both be defined as 1 for this function to be available. The application
* must also then provide definitions for
* portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() and portGET_RUN_TIME_COUNTER_VALUE()
* to configure a peripheral timer/counter and return the timers current count
* value respectively. The counter should be at least 10 times the frequency of
* the tick count.
*
* NOTE 1: This function will disable interrupts for its duration. It is
* not intended for normal application runtime use but as a debug aid.
*
* Setting configGENERATE_RUN_TIME_STATS to 1 will result in a total
* accumulated execution time being stored for each task. The resolution
* of the accumulated time value depends on the frequency of the timer
* configured by the portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() macro.
* Calling vTaskGetRunTimeStatistics() writes the total execution time of each
* task into a buffer, both as an absolute count value and as a percentage
* of the total system execution time.
*
* NOTE 2:
*
* This function is provided for convenience only, and is used by many of the
* demo applications. Do not consider it to be part of the scheduler.
*
* vTaskGetRunTimeStatistics() calls uxTaskGetSystemState(), then formats part of
* the uxTaskGetSystemState() output into a human readable table that displays the
* amount of time each task has spent in the Running state in both absolute and
* percentage terms.
*
* vTaskGetRunTimeStatistics() has a dependency on the snprintf() C library function
* that might bloat the code size, use a lot of stack, and provide different
* results on different platforms. An alternative, tiny, third party, and
* limited functionality implementation of snprintf() is provided in many of the
* FreeRTOS/Demo sub-directories in a file called printf-stdarg.c (note
* printf-stdarg.c does not provide a full snprintf() implementation!).
*
* It is recommended that production systems call uxTaskGetSystemState() directly
* to get access to raw stats data, rather than indirectly through a call to
* vTaskGetRunTimeStatistics().
*
* @param pcWriteBuffer A buffer into which the execution times will be
* written, in ASCII form. This buffer is assumed to be large enough to
* contain the generated report. Approximately 40 bytes per task should
* be sufficient.
*
* @param uxBufferLength Length of the pcWriteBuffer.
*
* \defgroup vTaskGetRunTimeStatistics vTaskGetRunTimeStatistics
* \ingroup TaskUtils
*/
void vTaskGetRunTimeStatistics( char * pcWriteBuffer,
size_t uxBufferLength ) PRIVILEGED_FUNCTION; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */

/**
* task. h
Expand All @@ -2139,6 +2257,12 @@ void vTaskList( char * pcWriteBuffer ) PRIVILEGED_FUNCTION; /*lint !e971 Unquali
* value respectively. The counter should be at least 10 times the frequency of
* the tick count.
*
* WARN: This function assumes that the pcWriteBuffer is of length
* configSTATS_BUFFER_MAX_LENGTH. This function is there only for
* backward compatiblity. New applications are recommended to use
* vTaskGetRunTimeStatistics and supply the length of the pcWriteBuffer
* explicitly.
*
* NOTE 1: This function will disable interrupts for its duration. It is
* not intended for normal application runtime use but as a debug aid.
*
Expand All @@ -2160,10 +2284,10 @@ void vTaskList( char * pcWriteBuffer ) PRIVILEGED_FUNCTION; /*lint !e971 Unquali
* amount of time each task has spent in the Running state in both absolute and
* percentage terms.
*
* vTaskGetRunTimeStats() has a dependency on the sprintf() C library function
* vTaskGetRunTimeStats() has a dependency on the snprintf() C library function
* that might bloat the code size, use a lot of stack, and provide different
* results on different platforms. An alternative, tiny, third party, and
* limited functionality implementation of sprintf() is provided in many of the
* limited functionality implementation of snprintf() is provided in many of the
* FreeRTOS/Demo sub-directories in a file called printf-stdarg.c (note
* printf-stdarg.c does not provide a full snprintf() implementation!).
*
Expand All @@ -2179,7 +2303,7 @@ void vTaskList( char * pcWriteBuffer ) PRIVILEGED_FUNCTION; /*lint !e971 Unquali
* \defgroup vTaskGetRunTimeStats vTaskGetRunTimeStats
* \ingroup TaskUtils
*/
void vTaskGetRunTimeStats( char * pcWriteBuffer ) PRIVILEGED_FUNCTION; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
#define vTaskGetRunTimeStats( pcWriteBuffer ) vTaskGetRunTimeStatistics( pcWriteBuffer, configSTATS_BUFFER_MAX_LENGTH )

/**
* task. h
Expand Down
Loading

0 comments on commit 96d6190

Please sign in to comment.