Article 5C5X2 Slackware ncurses vs. ncursesw segfault.

Slackware ncurses vs. ncursesw segfault.

by
milkylainen
from LinuxQuestions.org on (#5C5X2)
I've stumbled upon this several times over the years but have finally decided to try to get to the bottom of it.

My theory now is that the problem stems from the --enable-widec (wide char) support and the ncurses header set.
Ncurses is built without --enable-widec, ncursesw is built with.

The definition of _XOPEN_SOURCE >= 500 seems to imply a wide-char API.

As stated by the ncurses.h:
/*
* With XPG4, you must define _XOPEN_SOURCE_EXTENDED, it is redundant (or
* conflicting) when _XOPEN_SOURCE is 500 or greater. If NCURSES_WIDECHAR is
* not already defined, e.g., if the platform relies upon nonstandard feature
* test macros, define it at this point if the standard feature test macros
* indicate that it should be defined.
*/
#ifndef NCURSES_WIDECHAR
#if defined(_XOPEN_SOURCE_EXTENDED) || (defined(_XOPEN_SOURCE) && (_XOPEN_SOURCE - 0 >= 500))
#define NCURSES_WIDECHAR 1
#else
#define NCURSES_WIDECHAR 0
#endif
#endif /* NCURSES_WIDECHAR */

The problem is with the ncurses package-config files.
$ pkg-config --cflags ncurses
-D_DEFAULT_SOURCE -D_XOPEN_SOURCE=600
$ pkg-config --cflags ncursesw
-D_DEFAULT_SOURCE -D_XOPEN_SOURCE=600

Ncurses defines .pc files that imply _XOPEN_SOURCE=600.
This creates situations where atleast some programs cannot link ncurses and then run without a segfault.

On _my_ slackware-current it's easy to reproduce.
For example. To force the Linux kernel lxdialog/mconf (menuconfig) to link with ncurses instead of ncursesw.
This should be totally fine btw.

--- scripts/kconfig/mconf-cfg.sh~2020-12-13 23:41:30.000000000 +0100
+++ scripts/kconfig/mconf-cfg.sh2020-12-28 20:10:48.671935708 +0100
@@ -1,7 +1,7 @@
#!/bin/sh
# SPDX-License-Identifier: GPL-2.0

-PKG="ncursesw"
+PKG="ncurses"
PKG2="ncurses"

if [ -n "$(command -v pkg-config)" ]; then

This will pick up slackware ncurses regardless.
And with a pkg-config with $(pkg-config --cflags $PKG)
A $ make menuconfig on my system will now result in a segfault.

Modifying the .pc to _XOPEN_SOURCE < 500.
--- /usr/lib64/pkgconfig/ncurses.pc~2020-12-27 20:59:05.000000000 +0100
+++ /usr/lib64/pkgconfig/ncurses.pc2020-12-28 20:55:57.547918191 +0100
@@ -16,4 +16,4 @@
Requires.private:
Libs: -lncurses -ltinfo
Libs.private: -ldl
-Cflags: -D_DEFAULT_SOURCE -D_XOPEN_SOURCE=600
+Cflags: -D_DEFAULT_SOURCE -D_XOPEN_SOURCE=400

$ make menuconfig now works again, with ncurses instead of ncursesw.

The segfault is maybe from this section in ncurses according to Mr. Dickey.
--------------------------------------------------------------------------------
#if !NCURSES_OPAQUE
#if NCURSES_WATTR_MACROS
#if NCURSES_WIDECHAR && 1
#define wattrset(win,at) \
(NCURSES_OK_ADDR(win) \
? ((win)->_color = NCURSES_CAST(int, PAIR_NUMBER(at)), \
(win)->_attrs = NCURSES_CAST(attr_t, at), \
OK) \
: ERR)
#else
#define wattrset(win,at) \
(NCURSES_OK_ADDR(win) \
? ((win)->_attrs = NCURSES_CAST(attr_t, at), \
OK) \
: ERR)
#endif
#endif /* NCURSES_WATTR_MACROS */
#endif /* NCURSES_OPAQUE */
--------------------------------------------------------------------------------

(From another lxdialog/mconf program)
Program received signal SIGSEGV, Segmentation fault.
0x00007ffff7fa472b in waddch_literal (win=0xce1e20, ch=2097440) at ../ncurses/./base/lib_addch.c:391
391 line->text[x++] = ch;

Backtrace looks something like this:
(gdb) bt
#0 0x00007ffff7fa472b in waddch_literal (win=0xce1e20, ch=2097440) at ../ncurses/./base/lib_addch.c:391
#1 0x00007ffff7fa480f in waddch_nosync (win=0xce1e20, ch=32) at ../ncurses/./base/lib_addch.c:443
#2 0x00007ffff7fa4ad9 in waddch (win=0xce1e20, ch=32) at ../ncurses/./base/lib_addch.c:550
#3 0x0000000000415c78 in attr_clear (win=0xce1e20, height=49, width=width@entry=299, attr=<optimized out>) at lxdialog/util.c:250
#4 0x0000000000415cfc in dialog_clear () at lxdialog/util.c:262
#5 0x0000000000416274 in init_dialog (backtitle=backtitle@entry=0x0) at lxdialog/util.c:336
#6 0x000000000040272c in main (ac=2, av=0x7ffffffefb48) at mconf.c:1017

Investigated the win->line allocation.
After initscr the value seems ok.

(gdb) print stdscr->_line[0]
$14 = {text = 0xce2a10, firstchar = 0, lastchar = 301, oldindex = 0}
(gdb) print stdscr->_line[1]
$15 = {text = 0xce2ed0, firstchar = 0, lastchar = 301, oldindex = 0}
(gdb) print stdscr->_line[2]
$16 = {text = 0xce3390, firstchar = 0, lastchar = 301, oldindex = 0}
(gdb) print stdscr->_line[3]
$17 = {text = 0xce3850, firstchar = 0, lastchar = 301, oldindex = 0}

Breakpoint 1, main (ac=2, av=0x7ffffffefb28) at mconf.c:1000
1000 signal(SIGINT, sig_handler);
(gdb) c
Continuing.

Breakpoint 3, init_dialog (backtitle=backtitle@entry=0x0) at lxdialog/util.c:319
319 initscr(); /* Init curses */
(gdb) c
Continuing.

Breakpoint 4, initscr () at ../ncurses/./base/lib_initscr.c:56
56 START_TRACE();
(gdb) c
Continuing.

Hardware watchpoint 5: stdscr->_line[1]->text

Old value = <unreadable>
New value = (chtype *) 0xce2ed0
_nc_setupscreen_sp (spp=0x7ffffffef938, slines=49, scolumns=302, output=0x7ffff7f236a0 <_IO_2_1_stdout_>, filtered=0, slk_format=0) at ../ncurses/./base/lib_set_term.c:744
744 sp->_prescreen = FALSE;
(gdb) c
Continuing.

Hardware watchpoint 5: stdscr->_line[1]->text

Old value = (chtype *) 0xce2ed0
New value = (chtype *) 0x100ce2ed0
0x0000000000415c3f in attr_clear (win=0xce2690, height=49, width=width@entry=302, attr=2097408) at lxdialog/util.c:247
247 for (i = 0; i < height; i++) {
(gdb) n
248 wmove(win, i, 0);
(gdb) n
249 for (j = 0; j < width; j++)
(gdb) n
250 waddch(win, ' ');
(gdb) print i
$28 = 0
(gdb) print j
$29 = 0

And at the segfault...
(gdb) print win->_line[0]
$9 = {text = 0xce2a10, firstchar = 0, lastchar = 301, oldindex = 0}
(gdb) print win->_line[1]
$10 = {text = 0x100ce2ed0, firstchar = 0, lastchar = 301, oldindex = 0}
(gdb) print win->_line[2]
$11 = {text = 0xce3390, firstchar = 0, lastchar = 301, oldindex = 0}
(gdb) print win->_line[3]
$12 = {text = 0xce3850, firstchar = 0, lastchar = 301, oldindex = 0}

Seems the line text pointer is botched by something.

Seems to me that ncurses have internal structures that are sensitive between wide-char and not.
And the Slackware ncurses.pc indiciate wide-char API although it is built without.
I'm also not sure this is easily reproducible everywhere.
Different memory layouts seem to "fix" the problem sometimes.
At one point I tried to preload a library when the problem just disappeared...

Anyone?latest?d=yIl2AUoC8zA latest?i=ngYybGwiBCc:If5jVxKLlaA:F7zBnMy latest?i=ngYybGwiBCc:If5jVxKLlaA:V_sGLiP latest?d=qj6IDK7rITs latest?i=ngYybGwiBCc:If5jVxKLlaA:gIN9vFwngYybGwiBCc
External Content
Source RSS or Atom Feed
Feed Location https://feeds.feedburner.com/linuxquestions/latest
Feed Title LinuxQuestions.org
Feed Link https://www.linuxquestions.org/questions/
Reply 0 comments