mirror of
https://github.com/apache/nuttx.git
synced 2026-05-31 14:27:37 +08:00
Fix c5471 signal handling + deallocation bug
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@44 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
@@ -40,11 +40,13 @@
|
|||||||
# CONFIG_ROM_VECTORS - unique to c5471
|
# CONFIG_ROM_VECTORS - unique to c5471
|
||||||
# CONFIG_DRAM_END - the size of installed DRAM.
|
# CONFIG_DRAM_END - the size of installed DRAM.
|
||||||
# Unique to c5471
|
# Unique to c5471
|
||||||
|
# CONFIG_C5471_LEDS - Use LEDs to show state. Unique to c5471.
|
||||||
#
|
#
|
||||||
CONFIG_ARCH=c5471
|
CONFIG_ARCH=c5471
|
||||||
CONFIG_ARCH_C5471=y
|
CONFIG_ARCH_C5471=y
|
||||||
CONFIG_ROM_VECTORS=n
|
CONFIG_ROM_VECTORS=n
|
||||||
CONFIG_DRAM_END=0x11000000
|
CONFIG_DRAM_END=0x11000000
|
||||||
|
CONFIG_C5471_LEDS=y
|
||||||
|
|
||||||
#
|
#
|
||||||
# C5471 specific device driver settings
|
# C5471 specific device driver settings
|
||||||
|
|||||||
@@ -58,6 +58,64 @@
|
|||||||
* Private Functions
|
* Private Functions
|
||||||
************************************************************/
|
************************************************************/
|
||||||
|
|
||||||
|
/************************************************************
|
||||||
|
* Name: up_getsp
|
||||||
|
************************************************************/
|
||||||
|
|
||||||
|
/* I don't know if the builtin to get SP is enabled */
|
||||||
|
|
||||||
|
static inline uint32 up_getsp(void)
|
||||||
|
{
|
||||||
|
uint32 sp;
|
||||||
|
__asm__
|
||||||
|
(
|
||||||
|
"\tmov %0, sp\n\t"
|
||||||
|
: "=r"(sp)
|
||||||
|
);
|
||||||
|
return sp;
|
||||||
|
}
|
||||||
|
|
||||||
|
/************************************************************
|
||||||
|
* Name: up_stackdump
|
||||||
|
************************************************************/
|
||||||
|
|
||||||
|
#ifdef CONFIG_C5471_STACKDUMP
|
||||||
|
static void up_stackdump(void)
|
||||||
|
{
|
||||||
|
_TCB *rtcb = (_TCB*)g_readytorun.head;
|
||||||
|
uint32 stack_base = (uint32)rtcb->adj_stack_ptr;
|
||||||
|
uint32 sp = up_getsp();
|
||||||
|
|
||||||
|
lldbg("stack_base: %08x\n", stack_base);
|
||||||
|
lldbg("stack_size: %08x\n", rtcb->adj_stack_size);
|
||||||
|
lldbg("sp: %08x\n", sp);
|
||||||
|
|
||||||
|
if (sp >= stack_base || sp < stack_base - rtcb->adj_stack_size)
|
||||||
|
{
|
||||||
|
lldbg("ERROR: Stack pointer is not within allocated stack\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
uint32 stack = sp & ~0x1f;
|
||||||
|
|
||||||
|
for (stack = sp & ~0x1f; stack < stack_base; stack += 32)
|
||||||
|
{
|
||||||
|
uint32 *ptr = (uint32*)stack;
|
||||||
|
lldbg("%08x: %08x %08x %08x %08x %08x %08x %08x %08x\n",
|
||||||
|
stack, ptr[0], ptr[1], ptr[2], ptr[3],
|
||||||
|
ptr[4], ptr[5], ptr[6], ptr[7]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
# define up_stackdump()
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/************************************************************
|
||||||
|
* Name: _up_assert
|
||||||
|
************************************************************/
|
||||||
|
|
||||||
static void _up_assert(int errorcode) /* __attribute__ ((noreturn)) */
|
static void _up_assert(int errorcode) /* __attribute__ ((noreturn)) */
|
||||||
{
|
{
|
||||||
/* Are we in an interrupt handler or the idle task? */
|
/* Are we in an interrupt handler or the idle task? */
|
||||||
@@ -91,9 +149,19 @@ static void _up_assert(int errorcode) /* __attribute__ ((noreturn)) */
|
|||||||
|
|
||||||
void up_assert(const ubyte *filename, int lineno)
|
void up_assert(const ubyte *filename, int lineno)
|
||||||
{
|
{
|
||||||
|
#if CONFIG_TASK_NAME_SIZE > 0
|
||||||
|
_TCB *rtcb = (_TCB*)g_readytorun.head;
|
||||||
|
#endif
|
||||||
|
|
||||||
up_ledon(LED_ASSERTION);
|
up_ledon(LED_ASSERTION);
|
||||||
|
#if CONFIG_TASK_NAME_SIZE > 0
|
||||||
|
dbg("Assertion failed at file:%s line: %d task: %s\n",
|
||||||
|
filename, lineno, rtcb->name);
|
||||||
|
#else
|
||||||
dbg("Assertion failed at file:%s line: %d\n",
|
dbg("Assertion failed at file:%s line: %d\n",
|
||||||
filename, lineno);
|
filename, lineno);
|
||||||
|
#endif
|
||||||
|
up_stackdump();
|
||||||
_up_assert(EXIT_FAILURE);
|
_up_assert(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -103,8 +171,18 @@ void up_assert(const ubyte *filename, int lineno)
|
|||||||
|
|
||||||
void up_assert_code(const ubyte *filename, int lineno, int errorcode)
|
void up_assert_code(const ubyte *filename, int lineno, int errorcode)
|
||||||
{
|
{
|
||||||
|
#if CONFIG_TASK_NAME_SIZE > 0
|
||||||
|
_TCB *rtcb = (_TCB*)g_readytorun.head;
|
||||||
|
#endif
|
||||||
|
|
||||||
up_ledon(LED_ASSERTION);
|
up_ledon(LED_ASSERTION);
|
||||||
|
#if CONFIG_TASK_NAME_SIZE > 0
|
||||||
|
dbg("Assertion failed at file:%s line: %d task: %s error code: %d\n",
|
||||||
|
filename, lineno, rtcb->name, errorcode);
|
||||||
|
#else
|
||||||
dbg("Assertion failed at file:%s line: %d error code: %d\n",
|
dbg("Assertion failed at file:%s line: %d error code: %d\n",
|
||||||
filename, lineno, errorcode);
|
filename, lineno, errorcode);
|
||||||
|
#endif
|
||||||
|
up_stackdump();
|
||||||
_up_assert(errorcode);
|
_up_assert(errorcode);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -44,13 +44,16 @@
|
|||||||
* Definitions
|
* Definitions
|
||||||
************************************************************/
|
************************************************************/
|
||||||
|
|
||||||
/* Bring-up debug configurations */
|
/* Bring-up debug configurations. These are here (vs defconfig)
|
||||||
|
* because these should only be controlled during low level
|
||||||
|
* board bring-up and not part of normal platform configuration.
|
||||||
|
*/
|
||||||
|
|
||||||
#define CONFIG_SUPPRESS_INTERRUPTS 1 /* Do not enable interrupts */
|
#define CONFIG_SUPPRESS_INTERRUPTS 1 /* Do not enable interrupts */
|
||||||
#undef CONFIG_SUPPRESS_UART_CONFIG /* Do not reconfig UART */
|
#undef CONFIG_SUPPRESS_UART_CONFIG /* Do not reconfig UART */
|
||||||
#define CONFIG_C5471_LEDS 1 /* Use LEDs to show state */
|
#define CONFIG_C5471_STACKDUMP 1 /* Dump stack on assertion */
|
||||||
|
|
||||||
/* LED meanings */
|
/* LED definitions */
|
||||||
|
|
||||||
#define LED_STARTED 0
|
#define LED_STARTED 0
|
||||||
#define LED_HEAPALLOCATE 1
|
#define LED_HEAPALLOCATE 1
|
||||||
|
|||||||
@@ -99,6 +99,8 @@ void up_schedule_sigaction(_TCB *tcb, sig_deliver_t sigdeliver)
|
|||||||
{
|
{
|
||||||
/* Refuse to handle nested signal actions */
|
/* Refuse to handle nested signal actions */
|
||||||
|
|
||||||
|
dbg("tcb=0x%p sigdeliver=0x%p\n", tcb, sigdeliver);
|
||||||
|
|
||||||
if (!tcb->xcp.sigdeliver)
|
if (!tcb->xcp.sigdeliver)
|
||||||
{
|
{
|
||||||
irqstate_t flags;
|
irqstate_t flags;
|
||||||
@@ -111,6 +113,8 @@ void up_schedule_sigaction(_TCB *tcb, sig_deliver_t sigdeliver)
|
|||||||
* being delivered to the currently executing task.
|
* being delivered to the currently executing task.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
dbg("rtcb=0x%p current_regs=0x%p\n", g_readytorun.head, current_regs);
|
||||||
|
|
||||||
if (tcb == (_TCB*)g_readytorun.head)
|
if (tcb == (_TCB*)g_readytorun.head)
|
||||||
{
|
{
|
||||||
/* CASE 1: We are not in an interrupt handler and
|
/* CASE 1: We are not in an interrupt handler and
|
||||||
|
|||||||
@@ -589,14 +589,13 @@ static void up_xmitchars(up_dev_t *dev)
|
|||||||
static void up_putxmitchar(up_dev_t *dev, int ch)
|
static void up_putxmitchar(up_dev_t *dev, int ch)
|
||||||
{
|
{
|
||||||
int nexthead = dev->xmit.head + 1;
|
int nexthead = dev->xmit.head + 1;
|
||||||
|
|
||||||
for(;;)
|
|
||||||
{
|
|
||||||
if (nexthead >= dev->xmit.size)
|
if (nexthead >= dev->xmit.size)
|
||||||
{
|
{
|
||||||
nexthead = 0;
|
nexthead = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for(;;)
|
||||||
|
{
|
||||||
if (nexthead != dev->xmit.tail)
|
if (nexthead != dev->xmit.tail)
|
||||||
{
|
{
|
||||||
dev->xmit.buffer[dev->xmit.head] = ch;
|
dev->xmit.buffer[dev->xmit.head] = ch;
|
||||||
|
|||||||
@@ -81,7 +81,10 @@ void up_sigdeliver(void)
|
|||||||
sig_deliver_t sigdeliver;
|
sig_deliver_t sigdeliver;
|
||||||
|
|
||||||
up_ledon(LED_SIGNAL);
|
up_ledon(LED_SIGNAL);
|
||||||
ASSERT(rtcb->xcp.sigdeliver);
|
|
||||||
|
dbg("rtcb=%p sigdeliver=%p sigpendactionq.head=%p\n",
|
||||||
|
rtcb, rtcb->xcp.sigdeliver, rtcb->sigpendactionq.head);
|
||||||
|
ASSERT(rtcb->xcp.sigdeliver != NULL);
|
||||||
|
|
||||||
/* Save the real return state on the stack. */
|
/* Save the real return state on the stack. */
|
||||||
|
|
||||||
@@ -99,12 +102,9 @@ void up_sigdeliver(void)
|
|||||||
sigdeliver = rtcb->xcp.sigdeliver;
|
sigdeliver = rtcb->xcp.sigdeliver;
|
||||||
rtcb->xcp.sigdeliver = NULL;
|
rtcb->xcp.sigdeliver = NULL;
|
||||||
|
|
||||||
/* Then enable interrupts. We should still be safe from
|
/* Then restore the task interrupt statat. */
|
||||||
* any further signal handling actions until we also
|
|
||||||
* nullify tcb->xcp.sigdeliver.
|
|
||||||
*/
|
|
||||||
|
|
||||||
irqrestore(SVC_MODE | F_BIT);
|
irqrestore(regs[REG_CPSR]);
|
||||||
|
|
||||||
/* Deliver the signals */
|
/* Deliver the signals */
|
||||||
|
|
||||||
@@ -115,5 +115,6 @@ void up_sigdeliver(void)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
up_ledoff(LED_SIGNAL);
|
up_ledoff(LED_SIGNAL);
|
||||||
|
dbg("Resuming\n");
|
||||||
up_fullcontextrestore(regs);
|
up_fullcontextrestore(regs);
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -141,7 +141,7 @@ int files_releaselist(FAR struct filelist *list)
|
|||||||
/* Decrement the reference count */
|
/* Decrement the reference count */
|
||||||
|
|
||||||
_files_semtake(list);
|
_files_semtake(list);
|
||||||
crefs = --list->fl_crefs;
|
crefs = --(list->fl_crefs);
|
||||||
_files_semgive(list);
|
_files_semgive(list);
|
||||||
|
|
||||||
/* If the count decrements to zero, then there is no reference
|
/* If the count decrements to zero, then there is no reference
|
||||||
|
|||||||
@@ -68,6 +68,8 @@ void free(FAR void *mem)
|
|||||||
FAR struct mm_freenode_s *prev;
|
FAR struct mm_freenode_s *prev;
|
||||||
FAR struct mm_freenode_s *next;
|
FAR struct mm_freenode_s *next;
|
||||||
|
|
||||||
|
vdbg("Freeing %p\n", mem);
|
||||||
|
|
||||||
/* Protect against attempts to free a NULL reference */
|
/* Protect against attempts to free a NULL reference */
|
||||||
|
|
||||||
if (!mem)
|
if (!mem)
|
||||||
|
|||||||
@@ -165,6 +165,8 @@ void mm_addregion(FAR void *heapstart, size_t heapsize)
|
|||||||
heapend = MM_ALIGN_DOWN((size_t)heapstart + (size_t)heapsize);
|
heapend = MM_ALIGN_DOWN((size_t)heapstart + (size_t)heapsize);
|
||||||
heapsize = heapend - heapbase;
|
heapsize = heapend - heapbase;
|
||||||
|
|
||||||
|
lldbg("Region %d: base=%p size=%d\n", IDX+1, heapstart, heapsize);
|
||||||
|
|
||||||
/* Add the size of this region to the total size of the heap */
|
/* Add the size of this region to the total size of the heap */
|
||||||
|
|
||||||
g_heapsize += heapsize;
|
g_heapsize += heapsize;
|
||||||
|
|||||||
@@ -199,5 +199,6 @@ FAR void *malloc(size_t size)
|
|||||||
}
|
}
|
||||||
|
|
||||||
mm_givesemaphore();
|
mm_givesemaphore();
|
||||||
|
vdbg("Allocated %p\n", ret);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -132,7 +132,7 @@ void sig_deliver(FAR _TCB *stcb)
|
|||||||
|
|
||||||
rpid = getpid();
|
rpid = getpid();
|
||||||
|
|
||||||
/* Deliver the signal using its address environment */
|
/* Deliver the signal */
|
||||||
|
|
||||||
(*sigq->action.sighandler)(sigq->info.si_signo, &sigq->info, NULL);
|
(*sigq->action.sighandler)(sigq->info.si_signo, &sigq->info, NULL);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user