v0.8.0 0fa6785

crash.go RawHistoryFolder

1package logging
2
3import (
4	"fmt"
5	"os"
6	"os/signal"
7	"runtime"
8	"runtime/debug"
9	"syscall"
10)
11
12// SetupCrashHandler sets up signal handlers to catch crashes and log them
13func SetupCrashHandler() {
14	c := make(chan os.Signal, 1)
15
16	// Listen for crash signals
17	signal.Notify(c,
18		syscall.SIGSEGV, // Segmentation violation
19		syscall.SIGABRT, // Abort signal
20		syscall.SIGFPE,  // Floating point exception
21		syscall.SIGBUS,  // Bus error
22		syscall.SIGILL,  // Illegal instruction
23	)
24
25	go func() {
26		sig := <-c
27		handleCrash(sig)
28	}()
29}
30
31// SetupPanicRecovery sets up a global panic recovery handler
32// This should be called with defer at the start of main functions
33func SetupPanicRecovery() {
34	if r := recover(); r != nil {
35		logPanic(r)
36	}
37}
38
39// handleCrash logs crash information and exits
40func handleCrash(sig os.Signal) {
41	logger := GetLogger()
42	if logger == nil {
43		fmt.Fprintf(os.Stderr, "CRASH: Caught signal %v but no logger available\n", sig)
44		os.Exit(1)
45	}
46
47	// Log the crash
48	crashMsg := fmt.Sprintf("CRASH: Caught fatal signal %v", sig)
49	logger.writeLog(FATAL, crashMsg, "CRASH")
50
51	// Log stack trace
52	stack := debug.Stack()
53	stackMsg := fmt.Sprintf("Stack trace:\n%s", string(stack))
54	logger.writeLog(FATAL, stackMsg, "CRASH")
55
56	// Log system info
57	sysInfo := fmt.Sprintf("Go version: %s, OS: %s, Arch: %s, NumCPU: %d",
58		runtime.Version(), runtime.GOOS, runtime.GOARCH, runtime.NumCPU())
59	logger.writeLog(FATAL, sysInfo, "CRASH")
60
61	// Log memory stats
62	var m runtime.MemStats
63	runtime.ReadMemStats(&m)
64	memInfo := fmt.Sprintf("Memory - Alloc: %d KB, TotalAlloc: %d KB, Sys: %d KB, NumGC: %d",
65		m.Alloc/1024, m.TotalAlloc/1024, m.Sys/1024, m.NumGC)
66	logger.writeLog(FATAL, memInfo, "CRASH")
67
68	// Force flush logs
69	if logger.rotator != nil {
70		logger.rotator.Close()
71	}
72
73	// Exit with error code
74	os.Exit(128 + int(sig.(syscall.Signal)))
75}
76
77// logPanic logs panic information
78func logPanic(r any) {
79	logger := GetLogger()
80	if logger == nil {
81		fmt.Fprintf(os.Stderr, "PANIC: %v but no logger available\n", r)
82		return
83	}
84
85	// Log the panic
86	panicMsg := fmt.Sprintf("PANIC: %v", r)
87	logger.writeLog(FATAL, panicMsg, "PANIC")
88
89	// Log stack trace
90	stack := debug.Stack()
91	stackMsg := fmt.Sprintf("Stack trace:\n%s", string(stack))
92	logger.writeLog(FATAL, stackMsg, "PANIC")
93
94	// Re-panic to maintain normal panic behavior
95	panic(r)
96}
97
98// LogCrashInfo logs information that might be helpful for crash analysis
99func LogCrashInfo(context string) {
100	logger := GetLogger()
101	if logger == nil {
102		return
103	}
104
105	logger.writeLog(DEBUG, fmt.Sprintf("Crash context checkpoint: %s", context), "CRASH_DEBUG")
106}

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 8

Tags 42

↑↓ moveenter openesc close