Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
112 changes: 105 additions & 7 deletions CRT.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,13 @@ in the source distribution for its full text.
#include <string.h>
#include <locale.h>
#include <langinfo.h>
#ifdef HAVE_SETUID_ENABLED
#include <unistd.h>

#ifdef HAVE_EXECINFO_H
#include <execinfo.h>
#endif

#ifdef HAVE_SETUID_ENABLED
#include <sys/types.h>
#endif

Expand Down Expand Up @@ -539,8 +544,6 @@ char* CRT_termType;

int CRT_colorScheme = 0;

void *backtraceArray[128];

ATTR_NORETURN
static void CRT_handleSIGTERM(int sgn) {
(void) sgn;
Expand Down Expand Up @@ -585,9 +588,9 @@ void CRT_restorePrivileges() {

#endif /* HAVE_SETUID_ENABLED */

// TODO: pass an instance of Settings instead.
static struct sigaction old_sig_handler[32];

struct sigaction old_sigsegv_handler;
// TODO: pass an instance of Settings instead.

void CRT_init(int delay, int colorScheme, bool allowUnicode) {
initscr();
Expand Down Expand Up @@ -644,9 +647,15 @@ void CRT_init(int delay, int colorScheme, bool allowUnicode) {

struct sigaction act;
sigemptyset (&act.sa_mask);
act.sa_flags = (int)SA_RESETHAND;
act.sa_flags = (int)SA_RESETHAND|SA_NODEFER;
act.sa_handler = CRT_handleSIGSEGV;
sigaction (SIGSEGV, &act, &old_sigsegv_handler);
sigaction (SIGSEGV, &act, &old_sig_handler[SIGSEGV]);
sigaction (SIGFPE, &act, &old_sig_handler[SIGFPE]);
sigaction (SIGILL, &act, &old_sig_handler[SIGILL]);
sigaction (SIGBUS, &act, &old_sig_handler[SIGBUS]);
sigaction (SIGPIPE, &act, &old_sig_handler[SIGPIPE]);
sigaction (SIGSYS, &act, &old_sig_handler[SIGSYS]);
sigaction (SIGABRT, &act, &old_sig_handler[SIGABRT]);

signal(SIGTERM, CRT_handleSIGTERM);
signal(SIGQUIT, CRT_handleSIGTERM);
Expand Down Expand Up @@ -734,3 +743,92 @@ void CRT_setColors(int colorScheme) {

CRT_colors = CRT_colorSchemes[colorScheme];
}

void CRT_handleSIGSEGV(int signal) {
CRT_done();

fprintf(stderr, "\n\n"
"FATAL PROGRAM ERROR DETECTED\n"
"============================\n"
"Please check at https://htop.dev/issues whether this issue has already been reported.\n"
"If no similar issue has been reported before, please create a new issue with the following information:\n"
"\n"
"- Your htop version (htop --version)\n"
"- Your OS and kernel version (uname -a)\n"
"- Your distribution and release (lsb_release -a)\n"
"- Likely steps to reproduce (How did it happened?)\n"
#ifdef HAVE_EXECINFO_H
"- Backtrace of the issue (see below)\n"
#endif
"\n"
);

const char* signal_str = strsignal(signal);
if(!signal_str) {
signal_str = "unknown reason";
}
fprintf(stderr,
"Error information:\n"
"------------------\n"
"A signal %d (%s) was received.\n"
"\n",
signal, signal_str
);

#ifdef HAVE_EXECINFO_H
fprintf(stderr,
"Backtrace information:\n"
"----------------------\n"
"The following function calls were active when the issue was detected:\n"
"---\n"
);

void *backtraceArray[256];

size_t size = backtrace(backtraceArray, ARRAYSIZE(backtraceArray));
backtrace_symbols_fd(backtraceArray, size, 2);
fprintf(stderr,
"---\n"
"\n"
"To make the above information more practical to work with,\n"
"you should provide a disassembly of your binary.\n"
"This can usually be done by running the following command:\n"
"\n"
#ifdef HTOP_DARWIN
" otool -tvV `which htop` > ~/htop.otool\n"
#else
" objdump -d -S -w `which htop` > ~/htop.objdump\n"
#endif
"\n"
"Please include the generated file in your report.\n"
"\n"
);
#endif

fprintf(stderr,
"Running this program with debug symbols or inside a debugger may provide further insights.\n"
"\n"
"Thank you for helping to improve htop!\n"
"\n"
"htop " VERSION " aborting.\n"
"\n"
);

/* Call old sigsegv handler; may be default exit or third party one (e.g. ASAN) */
if(sigaction (signal, &old_sig_handler[signal], NULL) < 0) {
/* This avoids an infinite loop in case the handler could not be reset. */
fprintf(stderr,
"!!! Chained handler could not be restored. Forcing exit.\n"
);
_exit(1);
}

/* Trigger the previous signal handler. */
raise(signal);

// Always terminate, even if installed handler returns
fprintf(stderr,
"!!! Chained handler did not exit. Forcing exit.\n"
);
_exit(1);
}
5 changes: 1 addition & 4 deletions CRT.h
Original file line number Diff line number Diff line change
Expand Up @@ -116,8 +116,7 @@ typedef enum ColorElements_ {

void CRT_fatalError(const char* note) ATTR_NORETURN;

extern struct sigaction old_sigsegv_handler;
void CRT_handleSIGSEGV(int sgn);
void CRT_handleSIGSEGV(int signal) ATTR_NORETURN;

#define KEY_ALT(x) (KEY_F(64 - 26) + (x - 'A'))

Expand Down Expand Up @@ -146,8 +145,6 @@ extern char* CRT_termType;

extern int CRT_colorScheme;

extern void *backtraceArray[128];

#ifdef HAVE_SETUID_ENABLED

void CRT_dropPrivileges(void);
Expand Down
22 changes: 8 additions & 14 deletions Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,6 @@ linux_platform_headers = \
linux/IOPriority.h \
linux/LinuxProcess.h \
linux/LinuxProcessList.h \
linux/LinuxCRT.h \
linux/Battery.h \
linux/PressureStallMeter.h \
zfs/ZfsArcMeter.h \
Expand All @@ -134,7 +133,7 @@ linux_platform_headers = \
if HTOP_LINUX
AM_LDFLAGS += -rdynamic
myhtopplatsources = linux/Platform.c linux/IOPriorityPanel.c \
linux/LinuxProcess.c linux/LinuxProcessList.c linux/LinuxCRT.c linux/Battery.c \
linux/LinuxProcess.c linux/LinuxProcessList.c linux/Battery.c \
linux/PressureStallMeter.c \
zfs/ZfsArcMeter.c zfs/ZfsCompressedArcMeter.c zfs/ZfsArcStats.c

Expand All @@ -148,16 +147,16 @@ freebsd_platform_headers = \
freebsd/Platform.h \
freebsd/FreeBSDProcessList.h \
freebsd/FreeBSDProcess.h \
freebsd/FreeBSDCRT.h \
freebsd/Battery.h \
zfs/ZfsArcMeter.h \
zfs/ZfsCompressedArcMeter.h \
zfs/ZfsArcStats.h \
zfs/openzfs_sysctl.h

if HTOP_FREEBSD
AM_LDFLAGS += -lexecinfo
myhtopplatsources = freebsd/Platform.c freebsd/FreeBSDProcessList.c \
freebsd/FreeBSDProcess.c freebsd/FreeBSDCRT.c freebsd/Battery.c \
freebsd/FreeBSDProcess.c freebsd/Battery.c \
zfs/ZfsArcMeter.c zfs/ZfsCompressedArcMeter.c zfs/ZfsArcStats.c zfs/openzfs_sysctl.c

myhtopplatheaders = $(freebsd_platform_headers)
Expand All @@ -170,13 +169,12 @@ dragonflybsd_platform_headers = \
dragonflybsd/Platform.h \
dragonflybsd/DragonFlyBSDProcessList.h \
dragonflybsd/DragonFlyBSDProcess.h \
dragonflybsd/DragonFlyBSDCRT.h \
dragonflybsd/Battery.h

if HTOP_DRAGONFLYBSD
AM_LDFLAGS += -lkvm -lkinfo -lexecinfo
myhtopplatsources = dragonflybsd/Platform.c dragonflybsd/DragonFlyBSDProcessList.c \
dragonflybsd/DragonFlyBSDProcess.c dragonflybsd/DragonFlyBSDCRT.c dragonflybsd/Battery.c
dragonflybsd/DragonFlyBSDProcess.c dragonflybsd/Battery.c

myhtopplatheaders = $(dragonflybsd_platform_headers)
endif
Expand All @@ -188,12 +186,11 @@ openbsd_platform_headers = \
openbsd/Platform.h \
openbsd/OpenBSDProcessList.h \
openbsd/OpenBSDProcess.h \
openbsd/OpenBSDCRT.h \
openbsd/Battery.h

if HTOP_OPENBSD
myhtopplatsources = openbsd/Platform.c openbsd/OpenBSDProcessList.c \
openbsd/OpenBSDProcess.c openbsd/OpenBSDCRT.c openbsd/Battery.c
openbsd/OpenBSDProcess.c openbsd/Battery.c

myhtopplatheaders = $(openbsd_platform_headers)
endif
Expand All @@ -205,7 +202,6 @@ darwin_platform_headers = \
darwin/Platform.h \
darwin/DarwinProcess.h \
darwin/DarwinProcessList.h \
darwin/DarwinCRT.h \
darwin/Battery.h \
zfs/ZfsArcMeter.h \
zfs/ZfsCompressedArcMeter.h \
Expand All @@ -215,7 +211,7 @@ darwin_platform_headers = \
if HTOP_DARWIN
AM_LDFLAGS += -framework IOKit -framework CoreFoundation
myhtopplatsources = darwin/Platform.c darwin/DarwinProcess.c \
darwin/DarwinProcessList.c darwin/DarwinCRT.c darwin/Battery.c \
darwin/DarwinProcessList.c darwin/Battery.c \
zfs/ZfsArcMeter.c zfs/ZfsCompressedArcMeter.c zfs/ZfsArcStats.c zfs/openzfs_sysctl.c

myhtopplatheaders = $(darwin_platform_headers)
Expand All @@ -228,7 +224,6 @@ solaris_platform_headers = \
solaris/Platform.h \
solaris/SolarisProcess.h \
solaris/SolarisProcessList.h \
solaris/SolarisCRT.h \
solaris/Battery.h \
zfs/ZfsArcMeter.h \
zfs/ZfsCompressedArcMeter.h \
Expand All @@ -237,7 +232,7 @@ solaris_platform_headers = \
if HTOP_SOLARIS
myhtopplatsources = solaris/Platform.c \
solaris/SolarisProcess.c solaris/SolarisProcessList.c \
solaris/SolarisCRT.c solaris/Battery.c \
solaris/Battery.c \
zfs/ZfsArcMeter.c zfs/ZfsCompressedArcMeter.c zfs/ZfsArcStats.c

myhtopplatheaders = $(solaris_platform_headers)
Expand All @@ -250,13 +245,12 @@ unsupported_platform_headers = \
unsupported/Platform.h \
unsupported/UnsupportedProcess.h \
unsupported/UnsupportedProcessList.h \
unsupported/UnsupportedCRT.h \
unsupported/Battery.h

if HTOP_UNSUPPORTED
myhtopplatsources = unsupported/Platform.c \
unsupported/UnsupportedProcess.c unsupported/UnsupportedProcessList.c \
unsupported/UnsupportedCRT.c unsupported/Battery.c
unsupported/Battery.c

myhtopplatheaders = $(unsupported_platform_headers)
endif
Expand Down
2 changes: 1 addition & 1 deletion XAlloc.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
void fail() {
curs_set(1);
endwin();
err(1, NULL);
abort();
}

void* xMalloc(size_t size) {
Expand Down
35 changes: 0 additions & 35 deletions darwin/DarwinCRT.c

This file was deleted.

14 changes: 0 additions & 14 deletions darwin/DarwinCRT.h

This file was deleted.

35 changes: 0 additions & 35 deletions dragonflybsd/DragonFlyBSDCRT.c

This file was deleted.

15 changes: 0 additions & 15 deletions dragonflybsd/DragonFlyBSDCRT.h

This file was deleted.

Loading