Fix tui compilation with Solaris libcurses (PR tui/21482)
Commit Message
On both mainline and the 8.0 branch, gdb compilation fails on Solaris 10
with the native libcurses:
* Initially, compilation failed like this:
In file included from /vol/src/gnu/gdb/gdb-8.0-branch/local/gdb/gdb_curses.h:42:
0,
from /vol/src/gnu/gdb/gdb-8.0-branch/local/gdb/tui/tui-data.h:2
6,
from /vol/src/gnu/gdb/gdb-8.0-branch/local/gdb/tui/tui-disasm.c
:31:
/vol/src/gnu/gdb/gdb-8.0-branch/local/gdb/tui/tui-disasm.c: In function ‘CORE_A
DDR tui_disassemble(gdbarch*, tui_asm_line*, CORE_ADDR, int)’:
/vol/src/gnu/gdb/gdb-8.0-branch/local/gdb/tui/tui-disasm.c:71:19: error: ‘class
string_file’ has no member named ‘wclear’; did you mean ‘clear’?
gdb_dis_out.clear ();
^
/vol/src/gnu/gdb/gdb-8.0-branch/local/gdb/tui/tui-disasm.c:78:19: error: ‘class
string_file’ has no member named ‘wclear’; did you mean ‘clear’?
gdb_dis_out.clear ();
^
make[2]: *** [Makefile:1927: tui-disasm.o] Error 1
It turned out this happens because <curses.h> has
#define clear() wclear(stdscr)
This can be avoided by defining NOMACROS, which the patch below does
for solaris2.*.
* Even with this workaround, compilation fails in gdb/tui for several
instances of the same problem:
/vol/src/gnu/gdb/gdb-8.0-branch/local/gdb/tui/tui-winsource.c: In function ‘void tui_erase_source_content(tui_win_info*, int)’:
/vol/src/gnu/gdb/gdb-8.0-branch/local/gdb/tui/tui-winsource.c:257:18: error: invalid conversion from ‘const char*’ to ‘char*’ [-fpermissive]
no_src_str);
^
In file included from /vol/src/gnu/gdb/gdb-8.0-branch/local/gdb/gdb_curses.h:42:0,
from /vol/src/gnu/gdb/gdb-8.0-branch/local/gdb/tui/tui-data.h:26,
from /vol/src/gnu/gdb/gdb-8.0-branch/local/gdb/tui/tui-winsource.c:33:
/vol/gcc-7/lib/gcc/sparc-sun-solaris2.10/7.1.0/include-fixed/curses.h:699:12: note: initializing argument 4 of ‘int mvwaddstr(WINDOW*, int, int, char*)’
extern int mvwaddstr(WINDOW *, int, int, char *);
^~~~~~~~~
make[2]: *** [Makefile:1927: tui-winsource.o] Error 1
Unlike ncurses, <curses.h> declares
extern int mvwaddstr(WINDOW *, int, int, char *);
i.e. the last arg is char *, not const char *.
The patch fixes this by casting the last arg to mvwaddstr to char *,
as was recently done on mainline in a newterm() call (the only
difference between 8.0 and mainline gdb/tui).
With those changes, gdb on the 8.0 branch compiles cleanly on
sparcv9-sun-solaris2.10 with native curses and amd64-pc-solaris2.12
with bundled ncurses (well, almost: on Solaris 12 ncurses in
/usr/include is used, but gdb linked against -lcurses which fails:
Undefined first referenced
symbol in file
wattr_on tui-wingeneral.o
wattr_off tui-wingeneral.o
but that's a different and preexisting problem).
Ok for mainline and 8.0 branch?
Rainer
Comments
On 05/18/2017 09:56 AM, Rainer Orth wrote:
> On both mainline and the 8.0 branch, gdb compilation fails on Solaris 10
> with the native libcurses:
>
> * Initially, compilation failed like this:
>
> In file included from /vol/src/gnu/gdb/gdb-8.0-branch/local/gdb/gdb_curses.h:42:
> 0,
> from /vol/src/gnu/gdb/gdb-8.0-branch/local/gdb/tui/tui-data.h:2
> 6,
> from /vol/src/gnu/gdb/gdb-8.0-branch/local/gdb/tui/tui-disasm.c
> :31:
> /vol/src/gnu/gdb/gdb-8.0-branch/local/gdb/tui/tui-disasm.c: In function ‘CORE_A
> DDR tui_disassemble(gdbarch*, tui_asm_line*, CORE_ADDR, int)’:
> /vol/src/gnu/gdb/gdb-8.0-branch/local/gdb/tui/tui-disasm.c:71:19: error: ‘class
> string_file’ has no member named ‘wclear’; did you mean ‘clear’?
> gdb_dis_out.clear ();
> ^
> /vol/src/gnu/gdb/gdb-8.0-branch/local/gdb/tui/tui-disasm.c:78:19: error: ‘class
> string_file’ has no member named ‘wclear’; did you mean ‘clear’?
> gdb_dis_out.clear ();
> ^
> make[2]: *** [Makefile:1927: tui-disasm.o] Error 1
>
> It turned out this happens because <curses.h> has
>
> #define clear() wclear(stdscr)
>
> This can be avoided by defining NOMACROS, which the patch below does
> for solaris2.*.
We already handle some curses warts in gdb_curses.h (and then
include that header instead everywhere). I think this could go there,
even unconditionally. (This is more about curses implementation
than OS strictly speaking. Googling around finds hits for that
macro in the AIX curses.h header, for example.). Looks like ncurses
checks NCURSES_NOMACROS instead of NOMACROS, we could define that too.
>
> * Even with this workaround, compilation fails in gdb/tui for several
> instances of the same problem:
>
> /vol/src/gnu/gdb/gdb-8.0-branch/local/gdb/tui/tui-winsource.c: In function ‘void tui_erase_source_content(tui_win_info*, int)’:
> /vol/src/gnu/gdb/gdb-8.0-branch/local/gdb/tui/tui-winsource.c:257:18: error: invalid conversion from ‘const char*’ to ‘char*’ [-fpermissive]
> no_src_str);
> ^
> In file included from /vol/src/gnu/gdb/gdb-8.0-branch/local/gdb/gdb_curses.h:42:0,
> from /vol/src/gnu/gdb/gdb-8.0-branch/local/gdb/tui/tui-data.h:26,
> from /vol/src/gnu/gdb/gdb-8.0-branch/local/gdb/tui/tui-winsource.c:33:
> /vol/gcc-7/lib/gcc/sparc-sun-solaris2.10/7.1.0/include-fixed/curses.h:699:12: note: initializing argument 4 of ‘int mvwaddstr(WINDOW*, int, int, char*)’
> extern int mvwaddstr(WINDOW *, int, int, char *);
> ^~~~~~~~~
> make[2]: *** [Makefile:1927: tui-winsource.o] Error 1
>
> Unlike ncurses, <curses.h> declares
>
> extern int mvwaddstr(WINDOW *, int, int, char *);
>
> i.e. the last arg is char *, not const char *.
>
> The patch fixes this by casting the last arg to mvwaddstr to char *,
> as was recently done on mainline in a newterm() call (the only
> difference between 8.0 and mainline gdb/tui).
That's fine with me.
Looking at:
https://docs.oracle.com/cd/E19455-01/806-0629/6j9vjco9i/index.html
I see that this affects several APIs, so nicer would be to
fix this centrally in gdb_curses.h like we fix e.g.,
PyObject_GetAttrString in python/python-internal.h. But that can
be for another day.
>
> With those changes, gdb on the 8.0 branch compiles cleanly on
> sparcv9-sun-solaris2.10 with native curses and amd64-pc-solaris2.12
> with bundled ncurses (well, almost: on Solaris 12 ncurses in
> /usr/include is used, but gdb linked against -lcurses which fails:
>
> Undefined first referenced
> symbol in file
> wattr_on tui-wingeneral.o
> wattr_off tui-wingeneral.o
>
> but that's a different and preexisting problem).
These two problems would be better pushed as two separate patches
(with the rationales given above as separate commit logs).
> Ok for mainline and 8.0 branch?
The cast bits are OK. I'd like to hear your opinion on
moving the NOMACROS define to gdb_curses.h, before including
<curses.h>.
Thanks,
Pedro Alves
Hi Pedro,
>> It turned out this happens because <curses.h> has
>>
>> #define clear() wclear(stdscr)
>>
>> This can be avoided by defining NOMACROS, which the patch below does
>> for solaris2.*.
>
> We already handle some curses warts in gdb_curses.h (and then
> include that header instead everywhere). I think this could go there,
> even unconditionally. (This is more about curses implementation
> than OS strictly speaking. Googling around finds hits for that
> macro in the AIX curses.h header, for example.). Looks like ncurses
probably of SysVr4 origin ultimately: at least I already found it in
those sources.
> checks NCURSES_NOMACROS instead of NOMACROS, we could define that too.
Makes sense (unless this creates problems of its own ;-).
>> * Even with this workaround, compilation fails in gdb/tui for several
>> instances of the same problem:
>>
>> /vol/src/gnu/gdb/gdb-8.0-branch/local/gdb/tui/tui-winsource.c: In function ‘void tui_erase_source_content(tui_win_info*, int)’:
>> /vol/src/gnu/gdb/gdb-8.0-branch/local/gdb/tui/tui-winsource.c:257:18: error: invalid conversion from ‘const char*’ to ‘char*’ [-fpermissive]
>> no_src_str);
>> ^
>> In file included from /vol/src/gnu/gdb/gdb-8.0-branch/local/gdb/gdb_curses.h:42:0,
>> from /vol/src/gnu/gdb/gdb-8.0-branch/local/gdb/tui/tui-data.h:26,
>> from /vol/src/gnu/gdb/gdb-8.0-branch/local/gdb/tui/tui-winsource.c:33:
>> /vol/gcc-7/lib/gcc/sparc-sun-solaris2.10/7.1.0/include-fixed/curses.h:699:12: note: initializing argument 4 of ‘int mvwaddstr(WINDOW*, int, int, char*)’
>> extern int mvwaddstr(WINDOW *, int, int, char *);
>> ^~~~~~~~~
>> make[2]: *** [Makefile:1927: tui-winsource.o] Error 1
>>
>> Unlike ncurses, <curses.h> declares
>>
>> extern int mvwaddstr(WINDOW *, int, int, char *);
>>
>> i.e. the last arg is char *, not const char *.
>>
>> The patch fixes this by casting the last arg to mvwaddstr to char *,
>> as was recently done on mainline in a newterm() call (the only
>> difference between 8.0 and mainline gdb/tui).
>
> That's fine with me.
>
> Looking at:
>
> https://docs.oracle.com/cd/E19455-01/806-0629/6j9vjco9i/index.html
>
> I see that this affects several APIs, so nicer would be to
> fix this centrally in gdb_curses.h like we fix e.g.,
> PyObject_GetAttrString in python/python-internal.h. But that can
> be for another day.
This way you centralize the knowledge why you are doing this in once
header rather than several calls/casts. I guess we'll cross that bridge
once another function causes similar trouble.
>> With those changes, gdb on the 8.0 branch compiles cleanly on
>> sparcv9-sun-solaris2.10 with native curses and amd64-pc-solaris2.12
>> with bundled ncurses (well, almost: on Solaris 12 ncurses in
>> /usr/include is used, but gdb linked against -lcurses which fails:
>>
>> Undefined first referenced
>> symbol in file
>> wattr_on tui-wingeneral.o
>> wattr_off tui-wingeneral.o
>>
>> but that's a different and preexisting problem).
>
> These two problems would be better pushed as two separate patches
> (with the rationales given above as separate commit logs).
Fine with me. I'll look at the ncurses header vs. libcurses issue
later: so far I've just been lazy and manually linked gdb if I hit it.
>> Ok for mainline and 8.0 branch?
>
> The cast bits are OK. I'd like to hear your opinion on
> moving the NOMACROS define to gdb_curses.h, before including
> <curses.h>.
The move makes sense to me: I just wasn't aware of that file. I'll
prepare a separate patch.
Thanks.
Rainer
# HG changeset patch
# Parent bfb43bbf7ca9808a9e660c111b68eef77999e76c
Fix tui compilation with Solaris libcurses (PR tui/21482)
@@ -1312,6 +1312,14 @@ case $host_os in
Solaris 2.[789] when using GCC. ])
fi ;;
esac
+# On Solaris, we need to define NOMACROS so the native <curses.h> doesn't
+# define clear which interferes with the clear member of class string_file.
+case $host_os in
+ solaris2.*)
+ AC_DEFINE(NOMACROS, 1,
+ [Define to 1 to avoid <curses.h> defining clear which interferes with class string_file. ])
+ ;;
+esac
AC_CHECK_HEADERS(curses.h cursesX.h ncurses.h ncurses/ncurses.h ncurses/term.h)
AC_CHECK_HEADERS(term.h, [], [],
[#if HAVE_CURSES_H
@@ -117,7 +117,7 @@ tui_erase_data_content (const char *prom
mvwaddstr (TUI_DATA_WIN->generic.handle,
(TUI_DATA_WIN->generic.height / 2),
x_pos,
- prompt);
+ (char *) prompt);
}
wrefresh (TUI_DATA_WIN->generic.handle);
}
@@ -101,7 +101,7 @@ box_win (struct tui_gen_win_info *win_in
box (win, tui_border_vline, tui_border_hline);
#endif
if (win_info->title)
- mvwaddstr (win, 0, 3, win_info->title);
+ mvwaddstr (win, 0, 3, (char *) win_info->title);
wattroff (win, attrs);
}
}
@@ -254,7 +254,7 @@ tui_erase_source_content (struct tui_win
mvwaddstr (win_info->generic.handle,
(win_info->generic.height / 2),
x_pos,
- no_src_str);
+ (char *) no_src_str);
/* elz: Added this function call to set the real contents of
the window to what is on the screen, so that later calls
@@ -280,7 +280,7 @@ tui_show_source_line (struct tui_win_inf
wattron (win_info->generic.handle, A_STANDOUT);
mvwaddstr (win_info->generic.handle, lineno, 1,
- line->which_element.source.line);
+ (char *) line->which_element.source.line);
if (line->which_element.source.is_exec_point)
wattroff (win_info->generic.handle, A_STANDOUT);
@@ -565,7 +565,8 @@ tui_show_exec_info_content (struct tui_w
mvwaddstr (exec_info->handle,
cur_line,
0,
- exec_info->content[cur_line - 1]->which_element.simple_string);
+ (char *) exec_info->content[cur_line - 1]
+ ->which_element.simple_string);
tui_refresh_win (exec_info);
exec_info->content_in_use = TRUE;
}