Add some checks: if getpid() or get_errno_ptr() are called very early in the initialization sequence, they would fail

This commit is contained in:
Gregory Nutt 2014-04-10 10:20:44 -06:00
parent 2fcc57edb0
commit c208b25f89
4 changed files with 40 additions and 11 deletions

View File

@ -7158,4 +7158,8 @@
in all configurations that use networking or USB (2014-3-9).
* include/nuttx/syslog/syslog.h and ramlog.h: Move syslog.h and
ramlog.h to include/nutt/syslog (2014-4-10).
* sched/errno_getptr.c and getpid.c: Add some checks. If these
functions are called early in initialization before the tasking
structures are initialized, they will not behavr properly
(2014-4-10).

View File

@ -80,5 +80,3 @@ int get_errno(void)
{
return *get_errno_ptr();
}

View File

@ -1,7 +1,7 @@
/****************************************************************************
* sched/errno_getptr.c
*
* Copyright (C) 2007, 2008, 2011 Gregory Nutt. All rights reserved.
* Copyright (C) 2007, 2008, 2011, 2014 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
@ -54,6 +54,12 @@
* Private Data
****************************************************************************/
/* This is a 'dummy' errno value to use in context where there is no valid
* errno location to use. For example, when running from an interrupt handler
* or early in initialization when task structures have not yet been
* initialized.
*/
static int g_irqerrno;
/****************************************************************************
@ -89,10 +95,14 @@ FAR int *get_errno_ptr(void)
* task at the head of the ready-to-run list is actually running. It
* may not be running during very brief times during context switching
* logic (see, for example, task_exit.c).
*
* There is also a corner case early in the initialization sequence:
* The ready to run list may not yet be initialized and g_readytorun.head
* may be NULL.
*/
FAR struct tcb_s *rtcb = (FAR struct tcb_s*)g_readytorun.head;
if (rtcb->task_state == TSTATE_TASK_RUNNING)
if (rtcb && rtcb->task_state == TSTATE_TASK_RUNNING)
{
/* Yes.. the task is running normally. Return a reference to the
* thread-private errno in the TCB of the running task.
@ -113,5 +123,3 @@ FAR int *get_errno_ptr(void)
return &g_irqerrno;
}

View File

@ -1,7 +1,7 @@
/************************************************************************
* sched/getpid.c
*
* Copyright (C) 2007, 2009 Gregory Nutt. All rights reserved.
* Copyright (C) 2007, 2009, 2014 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
@ -44,7 +44,7 @@
#include "os_internal.h"
/************************************************************************
* Definitions
* Pre-processor Definitions
************************************************************************/
/************************************************************************
@ -77,9 +77,28 @@
pid_t getpid(void)
{
/* Return the task ID from the TCB at the head of the
* ready-to-run task list
FAR struct tcb_s *rtcb;
/* Get the the TCB at the head of the ready-to-run task list. That
* will be the currently executing task. There is an exception to
* this: Verify early in the start-up sequence, the g_readytorun
* list may be empty! This case, of course, the start-up/IDLE thread
* with pid == 0 must be running.
*/
return ((FAR struct tcb_s*)g_readytorun.head)->pid;
rtcb = (FAR struct tcb_s *)g_readytorun.head;
if (rtcb)
{
/* Return the task ID from the TCB at the head of the ready-to-run
* task list
*/
return rtcb->pid;
}
/* We must have been called earlier in the start up sequence from the
* start-up/IDLE thread before the g_readytorun list has been initialized.
*/
return 0;
}