Subject: bin/11247: mmap maps only part of file
To: None <gnats-bugs@gnats.netbsd.org>
From: Havard Eidnes <he@runit.no>
List: netbsd-bugs
Date: 10/17/2000 04:33:19
>Number: 11247
>Category: bin
>Synopsis: mmap maps only part of file
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: bin-bug-people
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Tue Oct 17 04:33:00 PDT 2000
>Closed-Date:
>Last-Modified:
>Originator: Havard Eidnes
>Release: NetBSD-current Oct 14 2000
>Organization:
RUNIT AS
>Environment:
NetBSD pt.runit.no 1.5H NetBSD 1.5H (PT) #5: Mon Oct 16 22:13:39 CEST 2000 he@pt.runit.no:/usr/src/sys/arch/i386/compile/PT i386
System: NetBSD pt.runit.no 1.5H NetBSD 1.5H (PT) #5: Mon Oct 16 22:13:39 CEST 2000 he@pt.runit.no:/usr/src/sys/arch/i386/compile/PT i386
>Description:
I'm currently in the middle of a source-based update of a machine from
1.5_ALPHA2 to NetBSD-current (1.5H) as of a couple of days ago.
However, both the old installed tail and the newly compiled one (after
"make includes" and the new libraries have been installed) both
exhibit the problem.
Running "tail -f" or simply "tail" on a moderately large file causes a
segmentation fault. The reason appears to be that the mmap() call of
the file in rlines() only maps *parts* of the file, contrary to what
is being asked for.
The following GDB session demonstrates the problem, and why I don't
see this as a simple user-land bug:
pt# gdb obj/tail
GNU gdb 4.17
Copyright 1998 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 "i386--netbsd"...
(gdb) run -f /usr/src/list.1
Starting program: /usr/src/usr.bin/tail/obj/tail -f /usr/src/list.1
Program received signal SIGSEGV, Segmentation fault.
0x804949a in rlines (fp=0x480f3200, off=10, sbp=0xbfbfd69c)
at /usr/src/usr.bin/tail/forward.c:272
272 if (*--p == '\n' && !--off) {
(gdb) where
#0 0x804949a in rlines (fp=0x480f3200, off=10, sbp=0xbfbfd69c)
at /usr/src/usr.bin/tail/forward.c:272
#1 0x8049105 in forward (fp=0x480f3200, style=RLINES, off=10, sbp=0xbfbfd69c)
at /usr/src/usr.bin/tail/forward.c:165
#2 0x804a981 in main (argc=1, argv=0xbfbfd750)
at /usr/src/usr.bin/tail/tail.c:187
#3 0x8048ba5 in ___start ()
(gdb) l rlines
246 static int
247 rlines(fp, off, sbp)
248 FILE *fp;
249 long off;
250 struct stat *sbp;
251 {
252 off_t size;
253 char *p;
254 char *start;
255
256 if (!(size = sbp->st_size))
257 return (0);
258
(gdb) l
259 if (size > SIZE_T_MAX) {
260 err(0, "%s: %s", fname, strerror(EFBIG));
261 return (1);
262 }
263
264 if ((start = mmap(NULL, (size_t)size, PROT_READ,
265 MAP_FILE|MAP_SHARED, fileno(fp), (off_t)0)) == (caddr_t)-1) {
266 err(0, "%s: %s", fname, strerror(EFBIG));
267 return (1);
268 }
(gdb) l
269
270 /* Last char is special, ignore whether newline or not. */
271 for (p = start + size - 1; --size;)
272 if (*--p == '\n' && !--off) {
273 ++p;
274 break;
275 }
276
277 /* Set the file pointer to reflect the length displayed. */
278 size = sbp->st_size - size;
(gdb) p start
$1 = 0x480f4000 "Build started at: Mon Oct 16 22:50:46 CEST 2000\n(cd /usr/src/etc && make -m /usr/src/share/mk DESTDIR=/ distrib-dirs)\ninstall -d -o root -g wheel -m 755 /\nmtree -def mtree/NetBSD.dist -p // -u\nmissin"...
(gdb) p size
$2 = 8110783
(gdb) p p
$3 = 0x488b02be <Error reading address 0x488b02be: Bad address>
(gdb) p start+size
$4 = 0x488b02bf <Error reading address 0x488b02bf: Bad address>
(gdb) p fp
$5 = (FILE *) 0x480f3200
(gdb) p *$
$6 = {_p = 0x0, _r = 0, _w = 0, _flags = 4, _file = 6, _bf = {_base = 0x0,
_size = 0}, _lbfsize = 0, _cookie = 0x480f3200,
_close = 0x480dc4dc <__sclose>, _read = 0x480dc3ec <__sread>,
_seek = 0x480dc488 <__sseek>, _write = 0x480dc43c <__swrite>, _ub = {
_base = 0x0, _size = 0}, _up = 0x0, _ur = 0, _ubuf = "\000\000",
_nbuf = "", _lb = {_base = 0x0, _size = 0}, _blksize = 0, _offset = 0}
(gdb)
(gdb) p start+64536
$7 = 0x48103c18 "c.o p7_evp.o p7_dgst.o p7_s_e.o p7_enc.o p7_lib.o f_int.o f_string.o i2d_dhp.o i2d_dsap.o d2i_dhp.o d2i_dsap.o n_pkey.o f_enum.o a_hdr.o x_pkey.o a_bool.o x_exten.o asn1_par.o asn1_lib.o asn1_err.o a_"...
(gdb) p start+128000
$8 = 0x48113400 "depend /usr/src/sbin/sysctl/tags \ncleandir ===> sbin/ttyflags\nrm -f a.out [Ee]rrs mklog core *.core ttyflags ttyflags.o ttyflags.ln \nrm -f ttyflags.cat8\nrm -f .depend /usr/src/sbin/ttyflags/tags \nc"...
(gdb) p start+256000
$9 = 0x48132800 "wap_2.o byte_swap_4.o bswap64.o bcmp.o bzero.o ffs.o memchr.o memcmp.o memcpy.o memmove.o memset.o strcat.o strchr.o strcmp.o strcpy.o strlen.o strncasecmp.o strncmp.o strncpy.o strrchr.o scanc.o skpc"...
(gdb) p start+512000
$10 = 0x48171000 <Error reading address 0x48171000: Bad address>
(gdb) p size
$11 = 8142006
(gdb) p start+400000
$12 = 0x48155a80 <Error reading address 0x48155a80: Bad address>
(gdb) p start+300000
$13 = 0x4813d3e0 "nake/snscore\nrm -f a.out [Ee]rrs mklog core *.core snscore snscore.o snscore.ln \nrm -f snscore.cat1\nrm -f .depend /usr/src/games/snake/snscore/tags \ncleandir ===> games/tetris\nrm -f a.out [Ee]rrs m"...
(gdb) p start+350000
$14 = 0x48149730 ""
(gdb) p start+355000
$15 = 0x4814aab8 <Error reading address 0x4814aab8: Bad address>
(gdb) p start+352000
$16 = 0x48149f00 ""
(gdb) p start+351000
$17 = 0x48149b18 ""
(gdb) p start+340000
$18 = 0x48147020 "ln tc-i386.ln obj-elf.ln atof-ieee.ln \nrm -f as.cat1\nrm -f .depend /usr/src/gnu/usr.bin/gas.new/tags \ncleandir ===> gnu/usr.bin/gawk\nrm -f awk.info\nrm -f a.out [Ee]rrs mklog core *.core awk alloca.o"...
(gdb) p start+345000
$19 = 0x481483a8 "f/libdriver/tags \ncleandir ===> gnu/usr.bin/groff/libbib\nrm -f a.out [Ee]rrs mklog core *.core \nrm -f libbib.a common.o index.o linear.o search.o map.o\nrm -f libbib_p.a \nrm -f libbib_pic.a libbib.so."...
(gdb) p start+348000
$20 = 0x48148f60 "usr.bin/groff/lkbib/tags \ncleandir ===> gnu/usr.bin/groff/hpftodit\nrm -f a.out [Ee]rrs mklog core *.core hpftodit hpftodit.o \nrm -f hpftodit.cat1\nrm -f .depend /usr/src/gnu/usr.bin/groff/hpftodit/"...
(gdb) p start+349000
$21 = 0x48149348 "ff/devices/devascii\nrm -f a.out [Ee]rrs mklog core *.core \nrm -f R I B BI DESC\ncleandir ===> gnu/usr.bin/groff/devices/devlatin1\nrm -f a.out [Ee]rrs mklog core *.core \nrm -f R I B BI DESC\nclea"...
(gdb) p start+349500
$22 = 0x4814953c "ices/devX100\nrm -f a.out [Ee]rrs mklog core *.core \ncleandir ===> gnu/usr.bin/groff/devices/devX100-12\nrm -f a.out [Ee]rrs mklog core *.core \ncleandir ===> gnu/usr.bin/groff/devices/devX75\nrm "...
(gdb) p start+349800
$23 = 0x48149668 "t [Ee]rrs mklog core *.core \ncleandir ===> gnu/usr.bin/groff/tmac\n"
(gdb) p start+350000
$24 = 0x48149730 ""
(gdb) p start+349999
$25 = 0x4814972f ""
(gdb) p start+349900
$26 = 0x481496cc ""
(gdb) p start+349800
$27 = 0x48149668 "t [Ee]rrs mklog core *.core \ncleandir ===> gnu/usr.bin/groff/tmac\n"
(gdb) p start+349850
$28 = 0x4814969a "/usr.bin/groff/tmac\n"
(gdb)
???
pt# limit
cputime unlimited
filesize unlimited
datasize 131072 kbytes
stacksize 2048 kbytes
coredumpsize unlimited
memoryuse 14156 kbytes
memorylocked 4718 kbytes
maxproc 80
openfiles 64
pt#
>How-To-Repeat:
See above.
>Fix:
Don't know.
>Release-Note:
>Audit-Trail:
>Unformatted: