1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2024-12-29 04:50:03 +01:00

sys/ps: Improve robustness against string table errors.

The mapping from thread state codes to a human readable string in the
PS modules has to be maintained manually. There is a very real possibility
for it to get out of sync with the actual defined states, which would cause
a crash when a lookup with an out of bounds index is performed. Also, because
of the way the array is defined, there could be gaps (which will be filled by
nulls).

This patch replaces the array looukup by a function that checks bounds and
also triggers an assertion so that the issue can be caught during development.
This commit is contained in:
Juan Carrano 2019-02-08 18:28:23 +01:00 committed by Francisco Molina
parent d187e83221
commit d167cb3af8
No known key found for this signature in database
GPG Key ID: 3E94EAC3DBDEEDA8

View File

@ -16,6 +16,7 @@
*/
#include <stdio.h>
#include <assert.h>
#include "thread.h"
#include "sched.h"
@ -32,7 +33,7 @@
#endif
/* list of states copied from tcb.h */
static const char *state_names[] = {
static const char *state_names[STATUS_NUMOF] = {
[STATUS_RUNNING] = "running",
[STATUS_PENDING] = "pending",
[STATUS_STOPPED] = "stopped",
@ -48,6 +49,28 @@ static const char *state_names[] = {
[STATUS_COND_BLOCKED] = "bl cond",
};
#define STATE_NAME_UNKNOWN "unknown"
/**
* Convert a thread state code to a human readable string.
*
* This function should be used instead of a direct array lookup: if ever
* state_names and the actual states in tcb.h get out of sync, a hole will be
* left in the lookup table. If compiling with NDEBUG not defined, this will
* generate an assertion which should make it clear that the table needs
* updating. With NDEBUG, any missing code will result in the string "unknown"
* (while direct access would return a NULL, possibly causing a crash.)
*/
static const char *state_to_string(thread_status_t state)
{
const char *name = state_names[state] ? state_names[state] : NULL;
assert(name != NULL); /* if compiling with assertions, this is an error that
indicates that the table above is incomplete */
return (name != NULL) ? name : STATE_NAME_UNKNOWN;
}
/**
* @brief Prints a list of running threads including stack usage to stdout.
*/
@ -104,7 +127,7 @@ void ps(void)
if (p != NULL) {
thread_status_t state = p->status; /* copy state */
const char *sname = state_names[state]; /* get state name */
const char *sname = state_to_string(state); /* get state name */
const char *queued = &queued_name[(int)(state >= STATUS_ON_RUNQUEUE)]; /* get queued flag */
#ifdef DEVELHELP
int stacksz = p->stack_size; /* get stack size */