Bug 691380 - Segfault in HEAD (2010-06-10)
Summary: Segfault in HEAD (2010-06-10)
Status: RESOLVED FIXED
Alias: None
Product: Ghostscript
Classification: Unclassified
Component: PDF Interpreter (show other bugs)
Version: master
Hardware: PC Linux
: P4 normal
Assignee: Jason Giglio
URL:
Keywords:
: 691005 (view as bug list)
Depends on:
Blocks:
 
Reported: 2010-06-11 02:08 UTC by Jason Giglio
Modified: 2010-08-10 08:06 UTC (History)
4 users (show)

See Also:
Customer:
Word Size: ---


Attachments
test attachment (1 bytes, application/octet-stream)
2010-06-11 02:52 UTC, Jason Giglio
Details
path for iname.c (2.96 KB, patch)
2010-07-21 18:16 UTC, Chris Liddell (chrisl)
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Jason Giglio 2010-06-11 02:08:17 UTC
Created attachment 6362 [details]
00170SOS202.pdf

Here is a segfault from testing that I am doing on HEAD:

gsc -dNOPAUSE -dBATCH -sOutputFile=/dev/shm/temp2 -sDEVICE=tiffsep -r20 -f /storage/archive/00170SOS202.pdf

GPL Ghostscript SVN PRE-RELEASE 8.72 (2010-02-11)
Copyright (C) 2010 Artifex Software, Inc.  All rights reserved.
This software comes with NO WARRANTY: see the file PUBLIC for details.
Processing pages 1 through 1.
Page 1
Segmentation fault
Comment 1 Jason Giglio 2010-06-11 02:23:04 UTC
GPL Ghostscript SVN PRE-RELEASE 8.72 (2010-02-11)
Copyright (C) 2010 Artifex Software, Inc.  All rights reserved.
This software comes with NO WARRANTY: see the file PUBLIC for details.
Processing pages 1 through 1.
Page 1
[New Thread 0x2b30420c4000 (LWP 11588)]

Program received signal SIGSEGV, Segmentation fault.
0x00002b3040f7b5cd in names_trace_finish () from /usr/lib64/libgs.so.8
(gdb) bt
#0  0x00002b3040f7b5cd in names_trace_finish () from /usr/lib64/libgs.so.8
#1  0x00002b3040f7982d in gs_gc_reclaim () from /usr/lib64/libgs.so.8
#2  0x00002b30410085b4 in context_reclaim () from /usr/lib64/libgs.so.8
#3  0x00002b3040f49045 in ireclaim () from /usr/lib64/libgs.so.8
#4  0x00002b3040f44bf1 in interp_reclaim () from /usr/lib64/libgs.so.8
#5  0x00002b3040f46704 in gs_interpret () from /usr/lib64/libgs.so.8
#6  0x00002b3040f3ba4e in gs_main_run_string_end () from /usr/lib64/libgs.so.8
#7  0x00002b3040f3ca50 in run_string () from /usr/lib64/libgs.so.8
#8  0x00002b3040f3d1b4 in runarg () from /usr/lib64/libgs.so.8
#9  0x00002b3040f3d368 in argproc () from /usr/lib64/libgs.so.8
#10 0x00002b3040f3ea5b in gs_main_init_with_args () from /usr/lib64/libgs.so.8
#11 0x0000000000400a01 in main (argc=8, argv=0x7ffff5388fe8)
    at ./psi/dxmainc.c:84
(gdb)
Comment 2 Jason Giglio 2010-06-11 02:52:46 UTC
Created attachment 6364 [details]
test attachment
Comment 3 Michael Vrhel 2010-06-24 23:04:02 UTC
This ran fine on win32.  Jason mentioned on IRC he is running 64bit.
Comment 4 Chris Liddell (chrisl) 2010-06-25 10:35:42 UTC
I had a quick look at this (in the hope it was the same as a crash I was seeing).

On 64 bit linux, I don't get a crash, but valgrind reports an invalid read and invalid write in names_trace_finish() (iname.c:427).

The problem appears to be that name_scan_sub() (at line 419) frees the subtable "names" and "strings" memory, and then at line 426 and 427, o_set_unmarked() reads then writes to the memory headers we've just freed.
Comment 5 Chris Liddell (chrisl) 2010-06-25 10:46:08 UTC
Removing the code (lines 424-428 inclusive):
	    if (nt->sub[i].names == 0 && gcst != 0) {
		/* Mark the just-freed sub-table as unmarked. */
		o_set_unmarked((obj_header_t *)sub - 1);
		o_set_unmarked((obj_header_t *)ssub - 1);
	    }

Causes the valgrind warning to go away, and doesn't /seem/ to cause a memory leak (I haven't checked exhaustively!). But this is a bit beyond my ken just now.

It seems quite possible that a different configuration/OS etc could cause the memory we've freed in name_scan_sub() to be the segment that triggers the OS to resize the heap, thus accessing the memory would cause a segmentation fault, or equivalent.
Comment 6 Ray Johnston 2010-07-20 18:21:51 UTC
This bug looks suspiciously like the description of bug 690129 which Igor
attempted to address with rev 9179. Maybe that fix wasn't enough ?

This will take some digging into the name table handling and why we need to
unmark the entries -- an area I haven't dug into before.

Chris, if you have time to dig into it, great !!!
Comment 7 Chris Liddell (chrisl) 2010-07-21 18:16:37 UTC
Created attachment 6522 [details]
path for iname.c


The reason the memory in question needs to be explicitly unmarked is because gs_free_object() may not actually free it. If the memory is allocated from a chunk in previous save level, gs_free_object() will not return it to the free list (or to the OS). But the memory reference is explicitly removed from the current save level, so clearing the gc marks may not happen as we'd expect, thus *possibly* leaving spuriously already marked memory around to confuse the next gc phase.

A small rearrangement of the code (see patch attachment) dispenses with the valgrind warning, but keeps the "firewall" of unmarking the potentially freed memory.
Comment 8 Chris Liddell (chrisl) 2010-08-06 15:04:56 UTC
patch committed in r11610.

As we could not reproduce the crash, reassigning to Jason in hope he can confirm the crash was the same problem valgrind reported.
Comment 9 keinbiervorvier 2010-08-06 16:05:32 UTC
*** Bug 691005 has been marked as a duplicate of this bug. ***
Comment 10 Jason Giglio 2010-08-09 21:45:31 UTC
I can't reproduce this in the current HEAD 9.00
Comment 11 Chris Liddell (chrisl) 2010-08-10 08:06:16 UTC
(In reply to comment #10)
> I can't reproduce this in the current HEAD 9.00

Thanks for testing it.