Skip to content

Commit

Permalink
HevTaskStackDetector: Init.
Browse files Browse the repository at this point in the history
  • Loading branch information
heiher committed Sep 29, 2024
1 parent 6112aac commit c23f435
Show file tree
Hide file tree
Showing 6 changed files with 126 additions and 8 deletions.
2 changes: 0 additions & 2 deletions src/kern/core/hev-task-system-private.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,7 @@ struct _HevTaskSystemContext

jmp_buf kernel_context;

#ifdef ENABLE_DEBUG
HevList all_tasks;
#endif
};

void hev_task_system_schedule (HevTaskYieldType type);
Expand Down
7 changes: 7 additions & 0 deletions src/kern/core/hev-task-system.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include <pthread.h>

#include "lib/misc/hev-compiler.h"
#include "lib/misc/hev-task-stack-detector.h"
#include "mem/api/hev-memory-allocator-api.h"
#include "mem/slice/hev-memory-allocator-slice.h"

Expand Down Expand Up @@ -72,8 +73,13 @@ hev_task_system_init (void)
if (!context->timer)
goto free_reactor;

if (hev_task_stack_detector_init () < 0)
goto free_timer;

return 0;

free_timer:
hev_task_timer_destroy (context->timer);
free_reactor:
hev_task_io_reactor_destroy (context->reactor);
rest_context:
Expand All @@ -92,6 +98,7 @@ hev_task_system_fini (void)

if (context->dns_proxy)
hev_task_dns_proxy_destroy (context->dns_proxy);
hev_task_stack_detector_fini ();
hev_task_timer_destroy (context->timer);
hev_task_io_reactor_destroy (context->reactor);
hev_free (context);
Expand Down
2 changes: 0 additions & 2 deletions src/kern/task/hev-task-private.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,7 @@ struct _HevTask

jmp_buf context;

#ifdef ENABLE_DEBUG
HevListNode list_node;
#endif
};

extern void hev_task_execute (HevTask *self, void *executer);
Expand Down
4 changes: 0 additions & 4 deletions src/kern/task/hev-task.c
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,8 @@ hev_task_new (int stack_size)
self->stack_bottom = hev_task_stack_get_bottom (self->stack);
self->sched_entity.task = self;

#ifdef ENABLE_DEBUG
hev_list_add_tail (&hev_task_system_get_context ()->all_tasks,
&self->list_node);
#endif

return self;
}
Expand All @@ -67,9 +65,7 @@ hev_task_unref (HevTask *self)
if (self->ref_count)
return;

#ifdef ENABLE_DEBUG
hev_list_del (&hev_task_system_get_context ()->all_tasks, &self->list_node);
#endif

hev_task_stack_destroy (self->stack);
hev_free (self);
Expand Down
103 changes: 103 additions & 0 deletions src/lib/misc/hev-task-stack-detector.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
/*
============================================================================
Name : hev-task-stack-detector.c
Author : hev <r@hev.cc>
Copyright : Copyright (c) 2024 hev.
Description : Task Stack Overflow Detector
============================================================================
*/

#include <stdio.h>
#include <signal.h>

#if defined(__APPLE__)
#include <Availability.h>
#include <AvailabilityMacros.h>
#include <TargetConditionals.h>
#endif

#include "kern/core/hev-task-system-private.h"
#include "kern/task/hev-task-private.h"
#include "kern/task/hev-task-stack.h"
#include "lib/misc/hev-compiler.h"

#include "hev-task-stack-detector.h"

static struct sigaction bus_sa;
static struct sigaction segv_sa;
static char stack[SIGSTKSZ];
static stack_t oss;

static int
setaltstack (const stack_t *ss, stack_t *oss)
{
#if defined(TARGET_OS_TV) && TARGET_OS_TV
return 0;
#else
return sigaltstack (ss, oss);
#endif
}

static void
signal_handler (int signo, siginfo_t *si, void *unused)
{
HevTaskSystemContext *context = hev_task_system_get_context ();
HevListNode *node = hev_list_first (&context->all_tasks);

for (; node; node = hev_list_node_next (node)) {
HevTask *task = container_of (node, HevTask, list_node);
const void *stack_base, *stack_bottom;

stack_base = hev_task_stack_get_base (task->stack);
stack_bottom = hev_task_stack_get_bottom (task->stack);

if (stack_base <= si->si_addr && si->si_addr <= stack_bottom) {
fprintf (stderr, "========== Oops! Stack overflow! ==========\n");
fprintf (stderr, "Task: %p\n", task);
fprintf (stderr, " Stack : %p - %p\n", stack_base, stack_bottom);
fprintf (stderr, " Bad addr: %p\n", si->si_addr);
fprintf (stderr, "===========================================\n");
}
}

switch (signo) {
case SIGBUS:
bus_sa.sa_sigaction (signo, si, unused);
break;
case SIGSEGV:
segv_sa.sa_sigaction (signo, si, unused);
break;
default:
return;
}
}

int
hev_task_stack_detector_init (void)
{
struct sigaction sa;
int res = 0;
stack_t ss;

ss.ss_size = SIGSTKSZ;
ss.ss_sp = stack;
ss.ss_flags = 0;

sa.sa_flags = SA_SIGINFO | SA_ONSTACK;
sa.sa_sigaction = signal_handler;
sigemptyset (&sa.sa_mask);

res |= setaltstack (&ss, &oss);
res |= sigaction (SIGBUS, &sa, &bus_sa);
res |= sigaction (SIGSEGV, &sa, &segv_sa);

return res;
}

void
hev_task_stack_detector_fini (void)
{
sigaction (SIGBUS, &bus_sa, NULL);
sigaction (SIGSEGV, &segv_sa, NULL);
setaltstack (&oss, NULL);
}
16 changes: 16 additions & 0 deletions src/lib/misc/hev-task-stack-detector.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
/*
============================================================================
Name : hev-task-stack-detector.h
Author : hev <r@hev.cc>
Copyright : Copyright (c) 2024 hev.
Description : Task Stack Overflow Detector
============================================================================
*/

#ifndef __HEV_TASK_STACK_DETECTOR_H__
#define __HEV_TASK_STACK_DETECTOR_H__

int hev_task_stack_detector_init (void);
void hev_task_stack_detector_fini (void);

#endif /* __HEV_TASK_STACK_DETECTOR_H__ */

0 comments on commit c23f435

Please sign in to comment.