char *vlib_default_runtime_dir = "vlib";
unix_main_t unix_main;
+clib_file_main_t file_main;
+vlib_physmem_main_t physmem_main;
static clib_error_t *
unix_main_init (vlib_main_t * vm)
VLIB_INIT_FUNCTION (unix_main_init);
+static int
+unsetup_signal_handlers (int sig)
+{
+ struct sigaction sa;
+
+ sa.sa_handler = SIG_DFL;
+ sa.sa_flags = 0;
+ sigemptyset (&sa.sa_mask);
+ return sigaction (sig, &sa, 0);
+}
+
+
+/* allocate this buffer from mheap when setting up the signal handler.
+ dangerous to vec_resize it when crashing, mheap itself might have been
+ corruptted already */
+static u8 *syslog_msg = 0;
+
static void
unix_signal_handler (int signum, siginfo_t * si, ucontext_t * uc)
{
- uword fatal;
- u8 *msg = 0;
+ uword fatal = 0;
- msg = format (msg, "received signal %U, PC %U",
- format_signal, signum, format_ucontext_pc, uc);
+ syslog_msg = format (syslog_msg, "received signal %U, PC %U",
+ format_signal, signum, format_ucontext_pc, uc);
if (signum == SIGSEGV)
- msg = format (msg, ", faulting address %p", si->si_addr);
+ syslog_msg = format (syslog_msg, ", faulting address %p", si->si_addr);
switch (signum)
{
if (unix_main.vlib_main->main_loop_exit_set)
{
syslog (LOG_ERR | LOG_DAEMON, "received SIGTERM, exiting...");
-
- clib_longjmp (&unix_main.vlib_main->main_loop_exit,
- VLIB_MAIN_LOOP_EXIT_CLI);
+ unix_main.vlib_main->main_loop_exit_now = 1;
}
+ break;
/* fall through */
case SIGQUIT:
case SIGINT:
case SIGSEGV:
case SIGHUP:
case SIGFPE:
+ case SIGABRT:
fatal = 1;
break;
}
/* Null terminate. */
- vec_add1 (msg, 0);
+ vec_add1 (syslog_msg, 0);
if (fatal)
{
- syslog (LOG_ERR | LOG_DAEMON, "%s", msg);
+ syslog (LOG_ERR | LOG_DAEMON, "%s", syslog_msg);
+
+ /* Address of callers: outer first, inner last. */
+ uword callers[15];
+ uword n_callers = clib_backtrace (callers, ARRAY_LEN (callers), 0);
+ int i;
+ for (i = 0; i < n_callers; i++)
+ {
+ vec_reset_length (syslog_msg);
+
+ syslog_msg =
+ format (syslog_msg, "#%-2d 0x%016lx %U%c", i, callers[i],
+ format_clib_elf_symbol_with_address, callers[i], 0);
+
+ syslog (LOG_ERR | LOG_DAEMON, "%s", syslog_msg);
+ }
+
+ /* have to remove SIGABRT to avoid recusive - os_exit calling abort() */
+ unsetup_signal_handlers (SIGABRT);
+
os_exit (1);
}
else
- clib_warning ("%s", msg);
+ clib_warning ("%s", syslog_msg);
- vec_free (msg);
}
static clib_error_t *
uword i;
struct sigaction sa;
+ /* give a big enough buffer for msg, most likely it can avoid vec_resize */
+ vec_alloc (syslog_msg, 2048);
+
for (i = 1; i < 32; i++)
{
- memset (&sa, 0, sizeof (sa));
+ clib_memset (&sa, 0, sizeof (sa));
sa.sa_sigaction = (void *) unix_signal_handler;
sa.sa_flags = SA_SIGINFO;
switch (i)
{
/* these signals take the default action */
- case SIGABRT:
case SIGKILL:
case SIGSTOP:
case SIGUSR1:
um->cli_no_banner = 1;
else if (unformat (input, "cli-no-pager"))
um->cli_no_pager = 1;
+ else if (unformat (input, "poll-sleep-usec %d", &um->poll_sleep_usec))
+ ;
else if (unformat (input, "cli-pager-buffer-limit %d",
&um->cli_pager_buffer_limit))
;
vlib_default_runtime_dir, 0);
}
+ error = setup_signal_handlers (um);
+ if (error)
+ return error;
+
if (um->pidfile)
{
if ((error = vlib_unix_validate_runtime_file (um,
}
}
- error = setup_signal_handlers (um);
- if (error)
- return error;
-
if (!(um->flags & UNIX_FLAG_INTERACTIVE))
{
openlog (vm->name, LOG_CONS | LOG_PERROR | LOG_PID, LOG_DAEMON);
vm->argv = (u8 **) argv;
vm->name = argv[0];
vm->heap_base = clib_mem_get_heap ();
+ vm->heap_aligned_base = (void *)
+ (((uword) vm->heap_base) & ~(VLIB_FRAME_ALIGN - 1));
ASSERT (vm->heap_base);
unformat_init_command_line (&input, (char **) vm->argv);
}
unformat_free (&input);
+ /* always load symbols, for signal handler and mheap memory get/put backtrace */
+ clib_elf_main_init (vm->name);
+
vlib_thread_stack_init (0);
__os_thread_index = 0;
+ vm->thread_index = 0;
i = clib_calljmp (thread0, (uword) vm,
(void *) (vlib_thread_stacks[0] +