Subject: port-mips/19183: tcsh on sgimips complains of malloc/free inconsistencies
To: None <gnats-bugs@gnats.netbsd.org>
From: None <he@netbsd.org>
List: netbsd-bugs
Date: 11/26/2002 23:32:17
>Number:         19183
>Category:       port-mips
>Synopsis:       tcsh on sgimips complains of malloc/free inconsistencies
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    port-mips-maintainer
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Tue Nov 26 14:33:00 PST 2002
>Closed-Date:
>Last-Modified:
>Originator:     Havard Eidnes
>Release:        NetBSD 1.6K, Nov 19 2002
>Organization:
	Unorganized Inc.
>Environment:
System: NetBSD viola.urc.uninett.no 1.6K NetBSD 1.6K (VIOLA) #26: Sat Nov  9 22:43:06 CET 2002     he@viola.urc.uninett.no:/usr/src/sys/arch/sgimips/compile/VIOLA sgimips
Architecture: mips
Machine: sgimips
>Description:
	Tcsh reports the following problems when it starts up:

free(10041150) bad block. (memtop = 1005f000 membot = 10033000)
free(10041180) bad block. (memtop = 1005f000 membot = 10033000)

	etc. (some 30 entries).

	Tcsh tries to replace free/malloc/realloc with it's own
	versions.  Debugging reveals that the malloc() called from
	cgetstr() inside the C library does not get redirected to
	tcsh's own malloc(), but most probably uses the C library's
	own malloc().  However, the free() call in libterm (which
	frees the memory allocated by cgetstr()) uses the free() call
	from tcsh, which produces the above warnings.

>How-To-Repeat:
	GDB debug session (after compiling libterm with -g):

viola: {29} gdb tcsh
GNU gdb 5.0nb1
Copyright 2000 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB.  Type "show warranty" for details.
This GDB was configured as "mipseb--netbsd"...
(gdb) b main
Breakpoint 1 at 0x409fa0: file sh.c, line 201.
(gdb) r
Starting program: /usr/pkgsrc/shells/tcsh/work/tcsh-6.12.00/tcsh 

Breakpoint 1, main (argc=1, argv=0x7fffeff0) at sh.c:201
201         (void) setlocale(LC_MESSAGES, "");
(gdb) b t_getstr
Breakpoint 2 at 0x3000a114: file /usr/src/lib/libterm/termcap.c, line 398.
(gdb) c
Continuing.

Breakpoint 2, t_getstr (info=0x10048108, id=0x3000aab0 "up", area=0x7fffbc90, 
    limit=0x7fffbc94) at /usr/src/lib/libterm/termcap.c:398
398             if ((i = cgetstr(info->info, id, &s)) < 0) {
(gdb) b malloc
Breakpoint 3 at 0x46b99c: file tc.alloc.c, line 168.
(gdb) b free
Breakpoint 4 at 0x46bcfc: file tc.alloc.c, line 305.
(gdb) c
Continuing.

Breakpoint 4, free (cp=0x1003d030) at tc.alloc.c:305
305         if (cp == NULL || dont_free)
(gdb) up
#1  0x3000a1e8 in t_getstr (info=0x1003d030, id=0x1003d034 "", 
    area=0x7fffbc90, limit=0x7fffbc94) at /usr/src/lib/libterm/termcap.c:417
417                     free(s);
(gdb) l
412                             free(s);
413                             return NULL;
414                     }
415             
416                     (void)strcpy(*area, s);
417                     free(s);
418                     s = *area;
419                     *area += i + 1;
420                     if (limit != NULL) *limit -= i;
421             
(gdb) l 392
392     
393             _DIAGASSERT(info != NULL);
394             _DIAGASSERT(id != NULL);
395             /* area may be NULL */
396     
397     
398             if ((i = cgetstr(info->info, id, &s)) < 0) {
399                     errno = ENOENT;
400                     if ((area == NULL) && (limit != NULL))
401                             *limit = 0;
(gdb) l
402                     return NULL;
403             }
404             
405             if (area != NULL) {
406                     /*
407                      * check if there is room for the new entry to be put into
408                      * area
409                      */
410                     if (limit != NULL && (*limit < (size_t) i)) {
411                             errno = E2BIG;
(gdb) l
412                             free(s);
413                             return NULL;
414                     }
415             
416                     (void)strcpy(*area, s);
417                     free(s);
418                     s = *area;
419                     *area += i + 1;
420                     if (limit != NULL) *limit -= i;
421             
(gdb) 


>Fix:
	Sorry, don't know, but after consulting with Christos, he
	suggested this might actually be a toolchain issue.
>Release-Note:
>Audit-Trail:
>Unformatted: