Subject: pkg/33808: misc/screen OOPSes on 64 bit archs [with patch]
To: None <pkg-manager@netbsd.org, gnats-admin@netbsd.org,>
From: Rhialto <rhialto@falu.nl>
List: pkgsrc-bugs
Date: 06/23/2006 13:55:00
>Number:         33808
>Category:       pkg
>Synopsis:       misc/screen OOPSes on 64 bit archs [with patch]
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    pkg-manager
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Fri Jun 23 13:55:00 +0000 2006
>Originator:     Rhialto
>Release:        NetBSD 3.0
>Organization:
>Environment:
	
	
System: NetBSD radl.falu.nl 3.0 NetBSD 3.0 (Radls Doordringend Onjuiste Akkoord) #0: Sat Jan 28 16:44:07 CET 2006 root@radl.falu.nl:/usr/src/sys/arch/amd64/compile/RADL amd64
Architecture: x86_64
Machine: amd64
>Description:

I have been trying to find why the "alternate characters" from xterm
don't work anymore in screen. You can see this in mutt for instance, if
you have set ascii_chars=no and order by thread. You get lots of OOPSes
when using screen, but not when using a bare xterm.

I instrumented screen to copy the implementation of tgoto(), since I
knew (and verified) that that is a (the) source of OOPS.
For some reason it is impossible to get stack backtraces once a process
calls abort() (on 3.0/amd64), nor do breakpoints work. So I had to make
do with a log file. It showed that the string passed to tgoto() is
^[(%p1%c, (tgoto does not understand %p) which does not appear to come
from the termcap but is coming from the source of screen itself:

#ifdef TERMINFO
        D_CS0 = "\033(%p1%c";
#else
        D_CS0 = "\033(%.";
#endif    

So why is TERMINFO getting defined??

During configure, I see this:

configure: checking libcurses...
- you use the terminfo database

which is the wrong conclusion.

config.log tells us about this fragment:

configure:4750: checking libcurses...
configure:4775: gcc -o conftest -g -O2   conftest.c -lcurses  >&5
configure:4778: $? = 0
configure:4781: test -s conftest
configure:4784: $? = 0
configure:4934: gcc -o conftest -g -O2   conftest.c -lcurses  >&5
configure: In function `main':
configure:4946: warning: passing arg 1 of `strcmp' makes pointer from integer without a cast
configure:4937: $? = 0
configure:4939: ./conftest
./configure: line 4940: 23761 Segmentation fault      (core dumped) ./conftest$ac_exeext
configure:4942: $? = 139
configure: program exited with status 139
configure: failed program was:
| #line 4920 "configure"
| /* confdefs.h.  */
|
| #define PACKAGE_NAME ""
| #define PACKAGE_TARNAME ""
| #define PACKAGE_VERSION ""
| #define PACKAGE_STRING ""
| #define PACKAGE_BUGREPORT ""
| #define SOCKDIR (eff_uid ? "/tmp/uscreens" : "/tmp/screens")
| #define POSIX 1
| #define HAVE_SYS_TYPES_H 1
| #define HAVE_SYS_STAT_H 1
| #define HAVE_STDLIB_H 1
| #define HAVE_STRING_H 1
| #define HAVE_MEMORY_H 1
| #define HAVE_STRINGS_H 1
| #define HAVE_INTTYPES_H 1
| #define HAVE_STDINT_H 1
| #define HAVE_UNISTD_H 1
| #define BSDJOBS 1
| #define HAVE_SETREUID 1
| #define HAVE_SETEUID 1
| #define NAMEDPIPE 1
| /* end confdefs.h.  */
| 
| main()
| {
|  exit(strcmp(tgoto("%p1%d", 0, 1), "1") ? 0 : 1);
| }

Notice this: passing arg 1 of `strcmp' makes pointer from integer
without a cast, and the resulting core dump.

So, the fix is to insert an #include <curses.h> into the test file,
to declare tgoto().

>How-To-Repeat:
	Use mutt inside screen, with fancy arrow characters for the
	threaded display.
>Fix:

So, the fix is to insert an #include <curses.h> into the test file,
to declare tgoto().

Result: new versions of patch-aj and patch-ak (as diffs to the diffs and
as new diffs):


Index: patch-aj
===================================================================
RCS file: /cvsroot/pkgsrc/misc/screen/patches/patch-aj,v
retrieving revision 1.4
diff -u -r1.4 patch-aj
--- patch-aj	28 Sep 2005 19:35:36 -0000	1.4
+++ patch-aj	23 Jun 2006 13:40:38 -0000
@@ -1,10 +1,19 @@
 $NetBSD: patch-aj,v 1.4 2005/09/28 19:35:36 rillig Exp $
 
+Add #include <curses.h> to tgoto test program.
 Detect getutent correctly on NetBSD with utmpx.
 
---- configure.in.orig	2003-06-03 07:58:24.000000000 -0400
-+++ configure.in	2004-06-16 16:11:55.000000000 -0400
-@@ -815,9 +815,15 @@
+--- configure.in.orig	2003-06-03 13:58:24.000000000 +0200
++++ configure.in	2006-06-23 15:33:22.000000000 +0200
+@@ -664,6 +664,7 @@
+ AC_MSG_ERROR(!!! no tgetent - no screen))))))
+ 
+ AC_TRY_RUN([
++#include <curses.h>
+ main()
+ {
+  exit(strcmp(tgoto("%p1%d", 0, 1), "1") ? 0 : 1);
+@@ -815,9 +816,15 @@
  AC_TRY_LINK([
  #include <time.h> /* to get time_t on SCO */
  #include <sys/types.h>
@@ -21,7 +30,7 @@
  #else
  #include <utmp.h>
  #endif
-@@ -1209,6 +1215,7 @@
+@@ -1209,6 +1216,7 @@
  AC_TRY_LINK(,[vsprintf(0,0,0);], AC_MSG_RESULT(yes);AC_DEFINE(USEVARARGS), AC_MSG_RESULT(no))
  
  AC_HEADER_DIRENT
Index: patch-ak
===================================================================
RCS file: /cvsroot/pkgsrc/misc/screen/patches/patch-ak,v
retrieving revision 1.3
diff -u -r1.3 patch-ak
--- patch-ak	16 Jun 2004 21:35:00 -0000	1.3
+++ patch-ak	23 Jun 2006 13:40:38 -0000
@@ -1,8 +1,16 @@
 $NetBSD: patch-ak,v 1.3 2004/06/16 21:35:00 christos Exp $
 
---- configure.orig	2003-12-05 08:46:53.000000000 -0500
-+++ configure	2004-06-16 16:12:06.000000000 -0400
-@@ -5572,9 +5572,15 @@
+--- configure.orig	2003-12-05 14:46:53.000000000 +0100
++++ configure	2006-06-23 15:33:44.000000000 +0200
+@@ -4925,6 +4925,7 @@
+ cat >>conftest.$ac_ext <<_ACEOF
+ /* end confdefs.h.  */
+ 
++#include <curses.h>
+ main()
+ {
+  exit(strcmp(tgoto("%p1%d", 0, 1), "1") ? 0 : 1);
+@@ -5572,9 +5573,15 @@
  
  #include <time.h> /* to get time_t on SCO */
  #include <sys/types.h>
@@ -19,7 +27,7 @@
  #else
  #include <utmp.h>
  #endif
-@@ -7502,6 +7508,148 @@
+@@ -7502,6 +7509,148 @@
  fi
  
  
@@ -168,3 +176,12 @@
  echo "$as_me:$LINENO: checking for setenv" >&5
  echo $ECHO_N "checking for setenv... $ECHO_C" >&6
  cat >conftest.$ac_ext <<_ACEOF
+@@ -8485,6 +8634,8 @@
+ _ACEOF
+ cat >>$CONFIG_STATUS <<\_ACEOF
+   -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
++    # Avoid regenerating for rechecks on pkgsrc
++    exit 0
+     ac_cs_recheck=: ;;
+   --version | --vers* | -V )
+     echo "$ac_cs_version"; exit 0 ;;



$NetBSD: patch-aj,v 1.4 2005/09/28 19:35:36 rillig Exp $

Add #include <curses.h> to tgoto test program.
Detect getutent correctly on NetBSD with utmpx.

--- configure.in.orig	2003-06-03 13:58:24.000000000 +0200
+++ configure.in	2006-06-23 15:33:22.000000000 +0200
@@ -664,6 +664,7 @@
 AC_MSG_ERROR(!!! no tgetent - no screen))))))
 
 AC_TRY_RUN([
+#include <curses.h>
 main()
 {
  exit(strcmp(tgoto("%p1%d", 0, 1), "1") ? 0 : 1);
@@ -815,9 +816,15 @@
 AC_TRY_LINK([
 #include <time.h> /* to get time_t on SCO */
 #include <sys/types.h>
-#if defined(SVR4) && !defined(DGUX)
+#include <sys/param.h>
+#if (defined(SVR4) && !defined(DGUX)) \
+ || (defined(__NetBSD_Version__) && (__NetBSD_Version__ >= 106050000))
 #include <utmpx.h>
 #define utmp utmpx
+# ifdef __NetBSD__
+#  define pututline pututxline
+#  define getutent  getutxent
+# endif
 #else
 #include <utmp.h>
 #endif
@@ -1209,6 +1216,7 @@
 AC_TRY_LINK(,[vsprintf(0,0,0);], AC_MSG_RESULT(yes);AC_DEFINE(USEVARARGS), AC_MSG_RESULT(no))
 
 AC_HEADER_DIRENT
+AC_CHECK_HEADERS(sys/stropts.h)
 
 AC_MSG_CHECKING(for setenv)
 AC_TRY_LINK(,[setenv((char *)0,(char *)0);unsetenv((char *)0);], AC_MSG_RESULT(yes);AC_DEFINE(USESETENV),



$NetBSD: patch-ak,v 1.3 2004/06/16 21:35:00 christos Exp $

--- configure.orig	2003-12-05 14:46:53.000000000 +0100
+++ configure	2006-06-23 15:33:44.000000000 +0200
@@ -4925,6 +4925,7 @@
 cat >>conftest.$ac_ext <<_ACEOF
 /* end confdefs.h.  */
 
+#include <curses.h>
 main()
 {
  exit(strcmp(tgoto("%p1%d", 0, 1), "1") ? 0 : 1);
@@ -5572,9 +5573,15 @@
 
 #include <time.h> /* to get time_t on SCO */
 #include <sys/types.h>
-#if defined(SVR4) && !defined(DGUX)
+#include <sys/param.h>
+#if (defined(SVR4) && !defined(DGUX)) \
+ || (defined(__NetBSD_Version__) && (__NetBSD_Version__ >= 106050000))
 #include <utmpx.h>
 #define utmp utmpx
+# ifdef __NetBSD__
+#  define pututline pututxline
+#  define getutent  getutxent
+# endif
 #else
 #include <utmp.h>
 #endif
@@ -7502,6 +7509,148 @@
 fi
 
 
+for ac_header in sys/stropts.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+else
+  # Is the header compilable?
+echo "$as_me:$LINENO: checking $ac_header usability" >&5
+echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <$ac_header>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking $ac_header presence" >&5
+echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <$ac_header>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc in
+  yes:no )
+    { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
+    (
+      cat <<\_ASBOX
+## ------------------------------------ ##
+## Report this to bug-autoconf@gnu.org. ##
+## ------------------------------------ ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+  no:yes )
+    { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
+echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
+    (
+      cat <<\_ASBOX
+## ------------------------------------ ##
+## Report this to bug-autoconf@gnu.org. ##
+## ------------------------------------ ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  eval "$as_ac_Header=$ac_header_preproc"
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+
+fi
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
 echo "$as_me:$LINENO: checking for setenv" >&5
 echo $ECHO_N "checking for setenv... $ECHO_C" >&6
 cat >conftest.$ac_ext <<_ACEOF
@@ -8485,6 +8634,8 @@
 _ACEOF
 cat >>$CONFIG_STATUS <<\_ACEOF
   -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+    # Avoid regenerating for rechecks on pkgsrc
+    exit 0
     ac_cs_recheck=: ;;
   --version | --vers* | -V )
     echo "$ac_cs_version"; exit 0 ;;

>Unformatted: