From dc00c37ad03effaea8e11cc02aa6cfd4c8758569 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Thu, 10 Apr 2014 10:20:44 -0600 Subject: Add some checks: if getpid() or get_errno_ptr() are called very early in the initialization sequence, they would fail --- nuttx/ChangeLog | 4 ++++ nuttx/sched/errno_get.c | 2 -- nuttx/sched/errno_getptr.c | 16 ++++++++++++---- nuttx/sched/getpid.c | 29 ++++++++++++++++++++++++----- 4 files changed, 40 insertions(+), 11 deletions(-) diff --git a/nuttx/ChangeLog b/nuttx/ChangeLog index 2f381cd98..4840987d0 100644 --- a/nuttx/ChangeLog +++ b/nuttx/ChangeLog @@ -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). diff --git a/nuttx/sched/errno_get.c b/nuttx/sched/errno_get.c index cac041f64..c313e3868 100644 --- a/nuttx/sched/errno_get.c +++ b/nuttx/sched/errno_get.c @@ -80,5 +80,3 @@ int get_errno(void) { return *get_errno_ptr(); } - - diff --git a/nuttx/sched/errno_getptr.c b/nuttx/sched/errno_getptr.c index b233b18e4..76123468d 100644 --- a/nuttx/sched/errno_getptr.c +++ b/nuttx/sched/errno_getptr.c @@ -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 * * 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; } - - diff --git a/nuttx/sched/getpid.c b/nuttx/sched/getpid.c index 259d78091..69e2a9c34 100644 --- a/nuttx/sched/getpid.c +++ b/nuttx/sched/getpid.c @@ -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 * * 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. + */ + + 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 ((FAR struct tcb_s*)g_readytorun.head)->pid; + return 0; } -- cgit v1.2.3