OK, I've now built glibc (overnight - it took nearly four hours) in debug and caught the crash in gdb. We're in ADDW (L_('\0')), right after the comment /* Convert the number. */ <quote src="gdb">
(gdb) run Starting program: /disk/home/eddy/work/mine/toys/sscanferange Program received signal SIGSEGV, Segmentation fault. 0xb7ee1e81 in _IO_vfscanf_internal (s=0xbfdff2dc, format=0x80485a0 "%llu", argptr=0xbfdff3a8 "¸óÿ¿", errp=0x0) at vfscanf.c:1760 (gdb) p wpsize $1 = 2097152 (gdb) p wpmax $2 = 4194304 (gdb) p old $3 = <value optimized out> (gdb) p wp $4 = 0xbf5fef70 <Address 0xbf5fef70 out of bounds> (gdb) p/x wpmax $5 = 0x400000 </quote> OK, that sounds like it's probably the problem. Perhaps alloca can't handle 4MiB allocations ! Unfortunately, its return, in this case, isn't the NULL checked for. Indeed, ADDW's check for NULL is pointless - alloca() is not specified to do so: <quote src="man alloca"> RETURN VALUE The alloca() function returns a pointer to the beginning of the allocated space. If the allocation causes stack overflow, program behavior is undefined. </quote> It's also worth noting that, by the time it comes to this call to alloca, the code has previously alloca()-ed 0x3fff00 bytes of memory, since ADDW does a doubling game to get to this point; using realloc might be more apt. Of course, since this is in read-number code, it might be better yet for the code to notice it's overflowed, set ERANGE and simply skip over digits of input until it finds something else, without any copying. Unfortunately, the code is sufficiently convoluted that I don't see how to change it to do that ... For reference: <quote src="gdb"> (gdb) p *s $6 = {_flags = -72515583, _IO_read_ptr = 0xbffff3b7 "", _IO_read_end = 0xbffff3b7 "", _IO_read_base = 0xbfdff3b7 '9' <repeats 200 times>..., _IO_write_base = 0xbfdff3b7 '9' <repeats 200 times>..., _IO_write_ptr = 0xbfdff3b7 '9' <repeats 200 times>..., _IO_write_end = 0xbfdff3b7 '9' <repeats 200 times>..., _IO_buf_base = 0xbfdff3b7 '9' <repeats 200 times>..., _IO_buf_end = 0xbffff3b7 "", _IO_save_base = 0x0, _IO_backup_base = 0x0, _IO_save_end = 0x0, _markers = 0x0, _chain = 0x0, _fileno = 0, _flags2 = 16, _old_offset = 0, _cur_column = 0, _vtable_offset = 0 '\000', _shortbuf = "", _lock = 0x0, _offset = 3086879200, _codecvt = 0xffffffff, _wide_data = 0xb7ffeff4, _freeres_list = 0x0, _freeres_buf = 0xb7fff670, _freeres_size = 3219125120, _mode = -1, _unused2 = "(øÿ·p\rþ·\001\000\000\000\001\000\000\000\000\000\000\000U\202\004\b\003\000\000\000\000\000\000\000¨\226\004\b\001\000\000"} (gdb) bt #0 0xb7ee1e81 in _IO_vfscanf_internal (s=0xbfdff2dc, format=0x80485a0 "%llu", argptr=0xbfdff3a8 "¸óÿ¿", errp=0x0) at vfscanf.c:1760 #1 0xb7ee7a65 in *__GI___isoc99_vsscanf (string=0xbfdff3b7 '9' <repeats 200 times>..., format=0x80485a0 "%llu", args=0xbfdff3a8 "¸óÿ¿") at isoc99_vsscanf.c:44 #2 0xb7ee79bf in __isoc99_sscanf (s=0xbfdff3b7 '9' <repeats 200 times>..., format=0x80485a0 "%llu") at isoc99_sscanf.c:33 #3 0x080484bf in main () at sscanferange.c:13 (gdb) up 3 #3 0x080484bf in main () at sscanferange.c:13 (gdb) p &(buf[0]) $8 = 0xbfdff3b7 '9' <repeats 200 times>... </quote> so it's just copied the very last character when this happens. If there are other things maintainers would like to know about details of this bug, I can easilly reproduce and ferret out the information you need - although I'll probably delete my debug build of glibc before many weeks have passed, Eddy. -- To UNSUBSCRIBE, email to debian-bugs-dist-requ...@lists.debian.org with a subject of "unsubscribe". Trouble? Contact listmas...@lists.debian.org