Skip to content

Commit

Permalink
Fix SEGFAULT at terminal resize
Browse files Browse the repository at this point in the history
this_cli is a thread-local variable used by functions within
SIGWINCH signal handler. This means that it can only be accessed by the
main thread (that created it). Previosly however this signal could be
handled by any thread of the process, thus occasionally causing
SEGFAULTs.
In a multithreaded process if a signal is blocked by all threads but
one, then the signal will be delivered to the thread expecting it. Using
the fact that signal masks are inherited by pthreads this commit blocks
SIGWINCH in the beginning of main(before the workers and the screen
timer are spawned) and unblocks it just before cli_start(). The
unblocking could be moved to scrn_start() function.
An alternative to this could be adding a 'handle_winch' atomic to struct
cli_scrn.

Signed-off-by: Philipp <phila775@gmail.com>
  • Loading branch information
Phikimon committed Sep 29, 2023
1 parent f080c4a commit 2853779
Showing 1 changed file with 24 additions and 4 deletions.
28 changes: 24 additions & 4 deletions app/pktgen-main.c
Original file line number Diff line number Diff line change
Expand Up @@ -420,13 +420,26 @@ main(int argc, char **argv)
{
uint32_t i;
int32_t ret;
struct sigaction sa;
sigset_t set;

setlocale(LC_ALL, "");

signal(SIGSEGV, sig_handler);
signal(SIGHUP, sig_handler);
signal(SIGINT, sig_handler);
signal(SIGPIPE, sig_handler);
sa.sa_handler = sig_handler;
sigemptyset(&sa.sa_mask);
sa.sa_flags = 0;

sigaction(SIGSEGV, &sa, NULL);
sigaction(SIGHUP, &sa, NULL);
sigaction(SIGINT, &sa, NULL);
sigaction(SIGPIPE, &sa, NULL);

/* Block SIGWINCH for all threads,
* because we only want it to be
* handled by the main thread */
sigemptyset(&set);
sigaddset(&set, SIGWINCH);
pthread_sigmask(SIG_BLOCK, &set, NULL);

scrn_setw(1); /* Reset the window size, from possible crash run. */
scrn_pos(100, 1); /* Move the cursor to the bottom of the screen again */
Expand Down Expand Up @@ -561,6 +574,13 @@ main(int argc, char **argv)
}

pktgen_log_info("=== Run CLI\n");

/* Unblock SIGWINCH so main thread
* can handle screen resizes */
sigemptyset(&set);
sigaddset(&set, SIGWINCH);
pthread_sigmask(SIG_BLOCK, &set, NULL);

cli_start(NULL);

scrn_pause();
Expand Down

0 comments on commit 2853779

Please sign in to comment.