FreeBSD6 /bin/tcsh ls-F : Floating exception (core dumped)

TOMITA Yoshinori yoshint at flab.fujitsu.co.jp
Mon Nov 7 21:46:33 PST 2005


tcsh 6.14.00 of FreeBSD 6-STABLE will crash by ls-F built-in command.

% /bin/tcsh
% cd /SOMEWHERE
% ls-F
Floating exception (core dumped)


If login shell is /bin/tcsh, this results in unintentional logout.

This problem occurs for example,

  1. charset of filename is ja_JP.eucJP
  2. LANG is not ja_JP.eucJP
  3. run ls-F

This is not only the case.


GDB stack trace:

-----------------------------------------------------
(gdb) where
#0  0x0806e947 in print_by_column (dir=0x80b9b94, items=0x8167c08, count=331, 
    no_file_suffix=1)
    at /usr/src/bin/csh/../../contrib/tcsh/tw.parse.c:2071
#1  0x0806d993 in tw_list_items (looking=4, numitems=331, list_max=0)
    at /usr/src/bin/csh/../../contrib/tcsh/tw.parse.c:1394
#2  0x0806e107 in t_search (word=0x80b9b94, wp=0x0, command=LIST, 
    max_word_length=0, looking=4, list_max=80, pat=0x80b9b94, suf=0)
    at /usr/src/bin/csh/../../contrib/tcsh/tw.parse.c:1706
#3  0x0808119b in dolist (v=0x8135cbc, c=0x81677e8)
    at /usr/src/bin/csh/../../contrib/tcsh/tc.func.c:251
#4  0x08056a2d in func (t=0x81677e8, bp=0x80909e0)
    at /usr/src/bin/csh/../../contrib/tcsh/sh.func.c:152
#5  0x08065ab7 in execute (t=0x81677e8, wanttty=50551, pipein=0x0, 
    pipeout=0x0, do_glob=1)
    at /usr/src/bin/csh/../../contrib/tcsh/sh.sem.c:650
#6  0x08065dd3 in execute (t=0x81652a8, wanttty=50551, pipein=0x0, 
    pipeout=0x0, do_glob=1)
    at /usr/src/bin/csh/../../contrib/tcsh/sh.sem.c:721
#7  0x0804d081 in process (catch=1)
    at /usr/src/bin/csh/../../contrib/tcsh/sh.c:2180
#8  0x0804bd8b in main (argc=0, argv=0xbfbfeb74)
    at /usr/src/bin/csh/../../contrib/tcsh/sh.c:1362
-----------------------------------------------------

signal comes from tw.parse.c:

    columns = TermH / maxwidth;		/* PWP: terminal size change */
                    ^^^^^^^^^^^

There are cases when maxwidth == 0 !!!

maxwidth is computed by ...

	maxwidth = max(maxwidth, (unsigned int) NLSStringWidth(items[i]));

and NLSStringWidth() is defined in tc.nls.c

int
NLSStringWidth(Char *s)
{
    int w = 0;
    while (*s)
	w += wcwidth(*s++);
    return w;
}

wcwidth() returns -1 when char is not printable depending LANG.
If LANG is not matched with coding set used as filenames,
wcwidth() will return -1.

So, int NLSStringWidth() might return negative value such as -1 or -2.
As a result, the next sentence in tw.parse.c

    maxwidth += no_file_suffix ? 1 : 2;	/* for the file tag and space */

makes maxwidth=0.


Here is a tiny patch.

-----------------------------------------------------
--- tc.nls.c.org	Tue Nov  8 14:13:22 2005
+++ tc.nls.c	Tue Nov  8 14:04:54 2005
@@ -89,8 +89,10 @@
 NLSStringWidth(Char *s)
 {
     int w = 0;
-    while (*s)
-	w += wcwidth(*s++);
+    while (*s) {
+      int tmp = wcwidth(*s++);
+      w += (tmp>0) ? tmp : 0;
+    }
     return w;
 }
 
-----------------------------------------------------


-- 
---
TOMITA Yoshinori
(Fujitsu Laboratories Ltd., Kawasaki, Japan)


More information about the freebsd-stable mailing list