mirror of
https://github.com/kovidgoyal/kitty
synced 2026-06-08 14:18:26 +02:00
Loop API print proper stack traces for panics in go routines
This commit is contained in:
@@ -229,6 +229,7 @@ func (h *Handler) get_results() (ans []*ResultItem, in_progress bool) {
|
|||||||
sc.search_text = st
|
sc.search_text = st
|
||||||
sp := h.state.ScorePatterns()
|
sp := h.state.ScorePatterns()
|
||||||
go func() {
|
go func() {
|
||||||
|
defer h.lp.RecoverFromPanicInGoRoutine()
|
||||||
results := sc.scan(cd, st, sp)
|
results := sc.scan(cd, st, sp)
|
||||||
sc.mutex.Lock()
|
sc.mutex.Lock()
|
||||||
defer sc.mutex.Unlock()
|
defer sc.mutex.Unlock()
|
||||||
|
|||||||
@@ -171,6 +171,7 @@ func (self *Handler) initialize() {
|
|||||||
self.original_context_count = self.current_context_count
|
self.original_context_count = self.current_context_count
|
||||||
self.async_results = make(chan AsyncResult, 32)
|
self.async_results = make(chan AsyncResult, 32)
|
||||||
go func() {
|
go func() {
|
||||||
|
self.lp.RecoverFromPanicInGoRoutine()
|
||||||
r := AsyncResult{}
|
r := AsyncResult{}
|
||||||
r.collection, r.err = create_collection(self.left, self.right)
|
r.collection, r.err = create_collection(self.left, self.right)
|
||||||
self.async_results <- r
|
self.async_results <- r
|
||||||
@@ -191,6 +192,7 @@ func (self *Handler) generate_diff() {
|
|||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
go func() {
|
go func() {
|
||||||
|
self.lp.RecoverFromPanicInGoRoutine()
|
||||||
r := AsyncResult{rtype: DIFF}
|
r := AsyncResult{rtype: DIFF}
|
||||||
r.diff_map, r.err = diff(jobs, self.current_context_count)
|
r.diff_map, r.err = diff(jobs, self.current_context_count)
|
||||||
self.async_results <- r
|
self.async_results <- r
|
||||||
@@ -230,6 +232,7 @@ func (self *Handler) highlight_all() {
|
|||||||
}
|
}
|
||||||
text_files := utils.Filter(self.collection.paths_to_highlight.AsSlice(), is_path_text)
|
text_files := utils.Filter(self.collection.paths_to_highlight.AsSlice(), is_path_text)
|
||||||
go func() {
|
go func() {
|
||||||
|
self.lp.RecoverFromPanicInGoRoutine()
|
||||||
r := AsyncResult{rtype: HIGHLIGHT}
|
r := AsyncResult{rtype: HIGHLIGHT}
|
||||||
highlight_all(text_files, use_light_colors)
|
highlight_all(text_files, use_light_colors)
|
||||||
self.async_results <- r
|
self.async_results <- r
|
||||||
@@ -252,6 +255,7 @@ func (self *Handler) load_all_images() {
|
|||||||
if self.image_count > 0 {
|
if self.image_count > 0 {
|
||||||
image_collection.Initialize(self.lp)
|
image_collection.Initialize(self.lp)
|
||||||
go func() {
|
go func() {
|
||||||
|
self.lp.RecoverFromPanicInGoRoutine()
|
||||||
r := AsyncResult{rtype: IMAGE_LOAD}
|
r := AsyncResult{rtype: IMAGE_LOAD}
|
||||||
image_collection.LoadAll()
|
image_collection.LoadAll()
|
||||||
self.async_results <- r
|
self.async_results <- r
|
||||||
@@ -273,6 +277,7 @@ func (self *Handler) resize_all_images_if_needed() {
|
|||||||
}
|
}
|
||||||
if sz != self.images_resized_to && self.image_count > 0 {
|
if sz != self.images_resized_to && self.image_count > 0 {
|
||||||
go func() {
|
go func() {
|
||||||
|
self.lp.RecoverFromPanicInGoRoutine()
|
||||||
image_collection.ResizeForPageSize(sz.Width, sz.Height)
|
image_collection.ResizeForPageSize(sz.Width, sz.Height)
|
||||||
r := AsyncResult{rtype: IMAGE_RESIZE, page_size: sz}
|
r := AsyncResult{rtype: IMAGE_RESIZE, page_size: sz}
|
||||||
self.async_results <- r
|
self.async_results <- r
|
||||||
|
|||||||
@@ -49,6 +49,7 @@ type Loop struct {
|
|||||||
timers, timers_temp []*timer
|
timers, timers_temp []*timer
|
||||||
timer_id_counter, write_msg_id_counter IdType
|
timer_id_counter, write_msg_id_counter IdType
|
||||||
wakeup_channel chan byte
|
wakeup_channel chan byte
|
||||||
|
panic_channel chan any
|
||||||
pending_writes []write_msg
|
pending_writes []write_msg
|
||||||
tty_write_channel chan write_msg
|
tty_write_channel chan write_msg
|
||||||
pending_mouse_events *utils.RingBuffer[MouseEvent]
|
pending_mouse_events *utils.RingBuffer[MouseEvent]
|
||||||
@@ -328,11 +329,14 @@ func (self *Loop) Run() (err error) {
|
|||||||
lines = append(lines, fmt.Sprintf("%s\r\n\t%s:%d\r\n", frame.Function, frame.File, frame.Line))
|
lines = append(lines, fmt.Sprintf("%s\r\n\t%s:%d\r\n", frame.Function, frame.File, frame.Line))
|
||||||
}
|
}
|
||||||
text := strings.Join(lines, "")
|
text := strings.Join(lines, "")
|
||||||
os.Stderr.WriteString(text)
|
|
||||||
tty.DebugPrintln(strings.TrimSpace(text))
|
tty.DebugPrintln(strings.TrimSpace(text))
|
||||||
if self.terminal_options.Alternate_screen {
|
is_terminal := tty.IsTerminal(os.Stderr.Fd())
|
||||||
term, err := tty.OpenControllingTerm(tty.SetRaw)
|
if is_terminal {
|
||||||
if err == nil {
|
os.Stderr.WriteString("\x1b]\x1b\\\x1bc\x1b[H\x1b[2J") // reset terminal
|
||||||
|
}
|
||||||
|
os.Stderr.WriteString(text)
|
||||||
|
if is_terminal {
|
||||||
|
if term, err := tty.OpenControllingTerm(tty.SetRaw); err == nil {
|
||||||
defer term.RestoreAndClose()
|
defer term.RestoreAndClose()
|
||||||
fmt.Println("Press any key to exit.\r")
|
fmt.Println("Press any key to exit.\r")
|
||||||
buf := make([]byte, 16)
|
buf := make([]byte, 16)
|
||||||
@@ -588,6 +592,12 @@ type SizedText struct {
|
|||||||
Width int
|
Width int
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (self *Loop) RecoverFromPanicInGoRoutine() {
|
||||||
|
if r := recover(); r != nil {
|
||||||
|
self.panic_channel <- r
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (self *Loop) DrawSizedText(text string, spec SizedText) {
|
func (self *Loop) DrawSizedText(text string, spec SizedText) {
|
||||||
b := strings.Builder{}
|
b := strings.Builder{}
|
||||||
b.Grow(len(text) + 24)
|
b.Grow(len(text) + 24)
|
||||||
|
|||||||
@@ -394,6 +394,7 @@ func (self *Loop) run() (err error) {
|
|||||||
self.write_msg_id_counter = 0
|
self.write_msg_id_counter = 0
|
||||||
write_done_channel := make(chan IdType)
|
write_done_channel := make(chan IdType)
|
||||||
self.wakeup_channel = make(chan byte, 256)
|
self.wakeup_channel = make(chan byte, 256)
|
||||||
|
self.panic_channel = make(chan any)
|
||||||
self.pending_writes = make([]write_msg, 0, 256)
|
self.pending_writes = make([]write_msg, 0, 256)
|
||||||
err_channel := make(chan error, 8)
|
err_channel := make(chan error, 8)
|
||||||
self.death_signal = SIGNULL
|
self.death_signal = SIGNULL
|
||||||
@@ -563,6 +564,8 @@ func (self *Loop) run() (err error) {
|
|||||||
}
|
}
|
||||||
select {
|
select {
|
||||||
case <-timeout_chan:
|
case <-timeout_chan:
|
||||||
|
case p := <-self.panic_channel:
|
||||||
|
panic(p)
|
||||||
case <-self.wakeup_channel:
|
case <-self.wakeup_channel:
|
||||||
for len(self.wakeup_channel) > 0 {
|
for len(self.wakeup_channel) > 0 {
|
||||||
<-self.wakeup_channel
|
<-self.wakeup_channel
|
||||||
|
|||||||
Reference in New Issue
Block a user