From ce0d5fffb46233db6dac610e65e5c96a6ec929d0 Mon Sep 17 00:00:00 2001 From: patwie Date: Wed, 8 Apr 2026 09:57:00 +0000 Subject: [PATCH 1/3] [AI generated] fix: Clamp GPU graph widths to prevent crash on small terminals When many GPUs are present and the terminal is small, the GPU graph width calculations in Cpu::draw init_graphs and draw_graphs can produce negative values. This causes std::out_of_range from the Draw::Graph constructor, surfacing as "Exception in runner thread -> Cpu:: -> deque". The root cause is the remainder-distribution formula for the last GPU graph: graph_width + graph_default_width%graph_width - gpus.size() + 1 which underflows when gpus.size() exceeds the available remainder plus graph_width. The per-GPU graph_width itself can also go below 1 when graph_default_width is small relative to gpu_draw_count. Clamp both graph_width and the last-GPU width to a minimum of 1, and clamp the cursor movement arguments in draw_graphs to prevent negative Mv::l and Mv::r values. --- src/btop_draw.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/btop_draw.cpp b/src/btop_draw.cpp index 469806d..ed7d16d 100644 --- a/src/btop_draw.cpp +++ b/src/btop_draw.cpp @@ -625,7 +625,7 @@ namespace Cpu { gpu_mem_graphs.resize(gpus.size()); gpu_meters.resize(gpus.size()); const int gpu_draw_count = gpu_always ? Gpu::count : Gpu::count - Gpu::shown; - graph_width = gpu_draw_count <= 0 ? graph_default_width : graph_default_width/gpu_draw_count - gpu_draw_count + 1 + graph_default_width%gpu_draw_count; + graph_width = gpu_draw_count <= 0 ? graph_default_width : max(1, graph_default_width/gpu_draw_count - gpu_draw_count + 1 + graph_default_width%gpu_draw_count); for (size_t i = 0; i < gpus.size(); i++) { if (gpu_auto and v_contains(Gpu::shown_panels, i)) continue; @@ -638,7 +638,7 @@ namespace Cpu { } else { graph = Draw::Graph{ - graph_width + graph_default_width%graph_width - (int)gpus.size() + 1, + max(1, graph_width + graph_default_width%graph_width - (int)gpus.size() + 1), graph_height, "cpu", safeVal(gpu.gpu_percent, graph_field), graph_symbol, invert, true }; } @@ -793,8 +793,8 @@ namespace Cpu { } if (Gpu::count - (gpu_auto ? Gpu::shown : 0) > 1) { auto i_str = to_string(i); - out += Mv::l(graph_width-1) + Mv::u(graph_height/2) + (graph_width > 5 ? "GPU" : "") + i_str - + Mv::d(graph_height/2) + Mv::r(graph_width - 1 - (graph_width > 5)*3 - i_str.size()); + out += Mv::l(max(0, graph_width-1)) + Mv::u(graph_height/2) + (graph_width > 5 ? "GPU" : "") + i_str + + Mv::d(graph_height/2) + Mv::r(max(0, (int)(graph_width - 1 - (graph_width > 5)*3 - i_str.size()))); } if (++gpu_drawn < Gpu::count - (gpu_auto ? Gpu::shown : 0)) From 0bafa6fa7110067ce3e4f24554896c0b82a40c1e Mon Sep 17 00:00:00 2001 From: Patrick Wieschollek Date: Sat, 25 Apr 2026 15:22:56 +0200 Subject: [PATCH 2/3] Update src/btop_draw.cpp Co-authored-by: dieter-apptronik --- src/btop_draw.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/btop_draw.cpp b/src/btop_draw.cpp index ed7d16d..9e42b6d 100644 --- a/src/btop_draw.cpp +++ b/src/btop_draw.cpp @@ -625,7 +625,10 @@ namespace Cpu { gpu_mem_graphs.resize(gpus.size()); gpu_meters.resize(gpus.size()); const int gpu_draw_count = gpu_always ? Gpu::count : Gpu::count - Gpu::shown; - graph_width = gpu_draw_count <= 0 ? graph_default_width : max(1, graph_default_width/gpu_draw_count - gpu_draw_count + 1 + graph_default_width%gpu_draw_count); + // Fairly distribute graph_default_width across gpu_draw_count GPUs, leaving 1 col per separator. + // Clamp to >=1 to avoid degenerate/negative widths reaching Draw::Graph::_create (#1118, #1017). + const int gpu_drawable_width = graph_default_width - max(0, gpu_draw_count - 1); + graph_width = gpu_draw_count <= 0 ? graph_default_width : max(1, gpu_drawable_width / gpu_draw_count); for (size_t i = 0; i < gpus.size(); i++) { if (gpu_auto and v_contains(Gpu::shown_panels, i)) continue; From 169737fb86d28fe97106ee58837d341168fdca6c Mon Sep 17 00:00:00 2001 From: Patrick Wieschollek Date: Sat, 25 Apr 2026 15:23:05 +0200 Subject: [PATCH 3/3] Update src/btop_draw.cpp Co-authored-by: dieter-apptronik --- src/btop_draw.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/btop_draw.cpp b/src/btop_draw.cpp index 9e42b6d..e943d95 100644 --- a/src/btop_draw.cpp +++ b/src/btop_draw.cpp @@ -641,7 +641,7 @@ namespace Cpu { } else { graph = Draw::Graph{ - max(1, graph_width + graph_default_width%graph_width - (int)gpus.size() + 1), + max(1, graph_width + (gpu_draw_count > 0 ? gpu_drawable_width % gpu_draw_count : 0)), graph_height, "cpu", safeVal(gpu.gpu_percent, graph_field), graph_symbol, invert, true }; }