summaryrefslogtreecommitdiff
path: root/tools/perf/ui/tui/setup.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/perf/ui/tui/setup.c')
-rw-r--r--tools/perf/ui/tui/setup.c83
1 files changed, 67 insertions, 16 deletions
diff --git a/tools/perf/ui/tui/setup.c b/tools/perf/ui/tui/setup.c
index b9401482d110..022534eed68c 100644
--- a/tools/perf/ui/tui/setup.c
+++ b/tools/perf/ui/tui/setup.c
@@ -1,7 +1,15 @@
+#include <errno.h>
#include <signal.h>
#include <stdbool.h>
-
-#include "../../util/cache.h"
+#include <stdlib.h>
+#include <termios.h>
+#include <unistd.h>
+#include <linux/kernel.h>
+#ifdef HAVE_BACKTRACE_SUPPORT
+#include <execinfo.h>
+#endif
+
+#include "../../util/color.h"
#include "../../util/debug.h"
#include "../browser.h"
#include "../helpline.h"
@@ -9,10 +17,12 @@
#include "../util.h"
#include "../libslang.h"
#include "../keysyms.h"
+#include "tui.h"
static volatile int ui__need_resize;
extern struct perf_error_ops perf_tui_eops;
+extern bool tui_helpline__set;
extern void hist_browser__init_hpp(void);
@@ -20,10 +30,10 @@ void ui__refresh_dimensions(bool force)
{
if (force || ui__need_resize) {
ui__need_resize = 0;
- pthread_mutex_lock(&ui__lock);
+ mutex_lock(&ui__lock);
SLtt_get_screen_size();
SLsmg_reinit_smg();
- pthread_mutex_unlock(&ui__lock);
+ mutex_unlock(&ui__lock);
}
}
@@ -87,6 +97,25 @@ int ui__getch(int delay_secs)
return SLkp_getkey();
}
+#ifdef HAVE_BACKTRACE_SUPPORT
+static void ui__signal_backtrace(int sig)
+{
+ void *stackdump[32];
+ size_t size;
+
+ ui__exit(false);
+ psignal(sig, "perf");
+
+ printf("-------- backtrace --------\n");
+ size = backtrace(stackdump, ARRAY_SIZE(stackdump));
+ __dump_stack(stdout, stackdump, size);
+
+ exit(0);
+}
+#else
+# define ui__signal_backtrace ui__signal
+#endif
+
static void ui__signal(int sig)
{
ui__exit(false);
@@ -94,6 +123,23 @@ static void ui__signal(int sig)
exit(0);
}
+static void ui__sigcont(int sig)
+{
+ static struct termios tty;
+
+ if (sig == SIGTSTP) {
+ while (tcgetattr(SLang_TT_Read_FD, &tty) == -1 && errno == EINTR)
+ ;
+ while (write(SLang_TT_Read_FD, PERF_COLOR_RESET, sizeof(PERF_COLOR_RESET) - 1) == -1 && errno == EINTR)
+ ;
+ raise(SIGSTOP);
+ } else {
+ while (tcsetattr(SLang_TT_Read_FD, TCSADRAIN, &tty) == -1 && errno == EINTR)
+ ;
+ raise(SIGWINCH);
+ }
+}
+
int ui__init(void)
{
int err;
@@ -105,9 +151,10 @@ int ui__init(void)
err = SLsmg_init_smg();
if (err < 0)
goto out;
- err = SLang_init_tty(0, 0, 0);
+ err = SLang_init_tty(-1, 0, 0);
if (err < 0)
goto out;
+ SLtty_set_suspend_state(true);
err = SLkp_init();
if (err < 0) {
@@ -115,20 +162,22 @@ int ui__init(void)
goto out;
}
- SLkp_define_keysym((char *)"^(kB)", SL_KEY_UNTAB);
-
- ui_helpline__init();
- ui_browser__init();
- ui_progress__init();
+ SLkp_define_keysym("^(kB)", SL_KEY_UNTAB);
- signal(SIGSEGV, ui__signal);
- signal(SIGFPE, ui__signal);
+ signal(SIGSEGV, ui__signal_backtrace);
+ signal(SIGFPE, ui__signal_backtrace);
signal(SIGINT, ui__signal);
signal(SIGQUIT, ui__signal);
signal(SIGTERM, ui__signal);
+ signal(SIGTSTP, ui__sigcont);
+ signal(SIGCONT, ui__sigcont);
perf_error__register(&perf_tui_eops);
+ ui_helpline__init();
+ ui_browser__init();
+ tui_progress__init();
+
hist_browser__init_hpp();
out:
return err;
@@ -136,15 +185,17 @@ out:
void ui__exit(bool wait_for_ok)
{
- if (wait_for_ok)
+ if (wait_for_ok && tui_helpline__set)
ui__question_window("Fatal Error",
ui_helpline__last_msg,
"Press any key...", 0);
SLtt_set_cursor_visibility(1);
- SLsmg_refresh();
- SLsmg_reset_smg();
+ if (mutex_trylock(&ui__lock)) {
+ SLsmg_refresh();
+ SLsmg_reset_smg();
+ mutex_unlock(&ui__lock);
+ }
SLang_reset_tty();
-
perf_error__unregister(&perf_tui_eops);
}