[binutils-gdb] gdb/tui: fix unexpected reuse of color pairs
Andrew Burgess via Gdb-cvs <[email protected]> Tue, 21 Jul 2026 11:06:58 +0000 (GMT)
| Newsgroups | gmane.comp.gdb.cvs |
|---|---|
| Message-ID | <[email protected]> |
https://sourceware.org/git/gitweb.cgi?p=3Dbinutils-gdb.git;h=3Dfbe7f20a0f09= 8ca03913452b29f50f0dc8568f77 commit fbe7f20a0f098ca03913452b29f50f0dc8568f77 Author: Jakob Sch=C3=A4ffeler <[email protected]> Date: Sat May 9 23:27:43 2026 +0200 gdb/tui: fix unexpected reuse of color pairs =20 TUI translates ANSI styling sequences to curses color pairs. Currently, this process uses COLOR_PAIR, which only returns values from 0 to 255 which results in unexpected reuse of color pairs. =20 Replacing wattron/wattroff with wcolor_set avoids the 256 color pair limit imposed by the COLOR_PAIR macro. However, wcolor_set takes a short for the pair index, limiting pairs to SHRT_MAX. =20 To support the full range of COLOR_PAIRS (up to 65536 with ncurses 6.1+), init_pair is replaced with init_extended_pair, and the pair index is passed to wcolor_set via the opts parameter as an extended color pair, a documented ncurses extension. =20 This also results in last_color_pair no longer being needed, and so it is removed. =20 The extended color pair extension requires ncurses 6.1+, so a configure check has been added. The fallback path uses the older color pair API which limits GDB to SHRT_MAX (32767) color pairs. =20 This patch was tested with make check-gdb TESTS=3D"gdb.tui/*.exp" Additionally, I tested this with the python extension from the bug report. =20 Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=3D34134 =20 Approved-By: Andrew Burgess <[email protected]> Diff: --- gdb/config.in | 3 +++ gdb/configure | 1 + gdb/configure.ac | 1 + gdb/tui/tui-io.c | 23 +++++++++++------------ 4 files changed, 16 insertions(+), 12 deletions(-) diff --git a/gdb/config.in b/gdb/config.in index 73d0b1913ce..1ef5dc5c2f4 100644 --- a/gdb/config.in +++ b/gdb/config.in @@ -250,6 +250,9 @@ /* Define to 1 if you have the `iconvlist' function. */ #undef HAVE_ICONVLIST =20 +/* Define to 1 if you have the `init_extended_pair' function. */ +#undef HAVE_INIT_EXTENDED_PAIR + /* Define to 1 if you have the <inttypes.h> header file. */ #undef HAVE_INTTYPES_H =20 diff --git a/gdb/configure b/gdb/configure index 3733ef76948..303d6ea011c 100755 --- a/gdb/configure +++ b/gdb/configure @@ -30238,6 +30238,7 @@ for ac_func in \ getrlimit \ getuid \ iconvlist \ + init_extended_pair \ libiconvlist \ posix_madvise \ pread \ diff --git a/gdb/configure.ac b/gdb/configure.ac index 5296d76f2cf..e55a733fba7 100644 --- a/gdb/configure.ac +++ b/gdb/configure.ac @@ -1520,6 +1520,7 @@ AC_CHECK_FUNCS([ \ getrlimit \ getuid \ iconvlist \ + init_extended_pair \ libiconvlist \ posix_madvise \ pread \ diff --git a/gdb/tui/tui-io.c b/gdb/tui/tui-io.c index 642b88ead0c..896d00f44c8 100644 --- a/gdb/tui/tui-io.c +++ b/gdb/tui/tui-io.c @@ -265,10 +265,6 @@ get_color (const ui_file_style::color &color, int *res= ult) return true; } =20 -/* The most recently emitted color pair. */ - -static int last_color_pair =3D -1; - /* The most recently applied style. */ =20 static ui_file_style last_style; @@ -299,7 +295,11 @@ get_color_pair (int fg, int bg) back to the default if we've used too many. */ if (next >=3D COLOR_PAIRS) return 0; +#ifdef HAVE_INIT_EXTENDED_PAIR + init_extended_pair (next, fg, bg); +#else init_pair (next, fg, bg); +#endif color_pair_map[c] =3D next; return next; } @@ -320,9 +320,8 @@ tui_apply_style (WINDOW *w, ui_file_style style) #endif wattroff (w, A_UNDERLINE); wattroff (w, A_REVERSE); - if (last_color_pair !=3D -1) - wattroff (w, COLOR_PAIR (last_color_pair)); - wattron (w, COLOR_PAIR (0)); + + wcolor_set (w, 0, nullptr); =20 const ui_file_style::color &fg =3D style.get_foreground (); const ui_file_style::color &bg =3D style.get_background (); @@ -342,10 +341,11 @@ tui_apply_style (WINDOW *w, ui_file_style style) bgi =3D (ncurses_norm_attr >> 4) & 15; #endif int pair =3D get_color_pair (fgi, bgi); - if (last_color_pair !=3D -1) - wattroff (w, COLOR_PAIR (last_color_pair)); - wattron (w, COLOR_PAIR (pair)); - last_color_pair =3D pair; +#ifdef HAVE_INIT_EXTENDED_PAIR + wcolor_set (w, 0, &pair); +#else + wcolor_set (w, pair, nullptr); +#endif } } =20 @@ -907,7 +907,6 @@ tui_setup_io (int mode) savetty (); =20 /* Clean up color information. */ - last_color_pair =3D -1; last_style =3D ui_file_style (); color_map.clear (); color_pair_map.clear ();