Bug 689237 - gv, kghostview, and pdf2ps hang with GPL GS 8.57 or newer, both trunk and gs-esp-gpl-merger
Summary: gv, kghostview, and pdf2ps hang with GPL GS 8.57 or newer, both trunk and gs-...
Alias: None
Product: Ghostscript
Classification: Unclassified
Component: PDF Interpreter (show other bugs)
Version: master
Hardware: All Linux
: P4 critical
Assignee: Ray Johnston
Depends on:
Reported: 2007-05-16 15:59 UTC by Till Kamppeter
Modified: 2008-12-19 08:31 UTC (History)
2 users (show)

See Also:
Word Size: ---

Patches to gv-3.5.8 (78.72 KB, patch)
2007-05-24 18:16 UTC, William Bader
Details | Diff
This PDF works only without anti-aliasing (1.25 MB, application/pdf)
2007-07-05 14:09 UTC, Till Kamppeter
Patches to gv-3.5.8, version 31 May 07 (80.27 KB, patch)
2007-07-29 05:26 UTC, William Bader
Details | Diff
patch to pdf_main.ps (735 bytes, patch)
2007-07-29 05:27 UTC, William Bader
Details | Diff
Test file for hangs with gv + gs (1.70 KB, application/postscript)
2007-07-29 05:30 UTC, William Bader
gv init file (2.76 KB, text/plain)
2007-07-29 05:32 UTC, William Bader
Misc patches to gs 8.57 (25.82 KB, patch)
2007-07-29 05:36 UTC, William Bader
Details | Diff
Example ps file for my gs patches (783 bytes, application/postscript)
2007-07-29 05:42 UTC, William Bader

Note You need to log in before you can comment on or make changes to this bug.
Description Till Kamppeter 2007-05-16 15:59:08 UTC
I am currently packaging GPL Ghostscript with merged ESP functionality for
Ubuntu (branch "gs-esp-gpl-merger"). After installing my new Ubuntu package I
have found out that gv and kghostview do not display PDF files any more but
Postscript files still display. The viewer utilities simply hang infinitely.
They show only the number of pages and resize the window to the page size. This
happens both with and without anti-aliasing. Also converting PDF to PostScript
does not work. "pdf2ps" also hangs and with some PDFs it regular gives the
warning "**** Warning: Encoding not present.".

Reverting to ESP GhostScript 8.15.4 or GPL GhostScript 8.56 makes everything
working again.

After observing this I have tested with GPL Ghostscript SVN snapshots directly
compiled, without Ubuntu packaging and without patches, both the
gs-esp-gpl-merger branch and trunk, both with the X11 driver built-in or as
shared library, and with or without the "--disable-contrib" configure option.
Revisions tested are 7976 and 7983. On all these versions gv, kghostview, and
pdf2ps failed on all PDF files (hanging).

So the problem seems not to be the merger but recent changes in the core
Comment 1 Till Kamppeter 2007-05-17 02:53:14 UTC
Additional info to this bug:

- "gs -sDEVICE=x11 <PDF file>" works.

- The problem seems to be similar to bug #689138, but it is not the same, as the 
  patch of comment #10 is already applied to the SVN repository and applying the
  patch of comment #8 in addition does not solve the problem.

- The problem occurs for me with every PDF file.
Comment 2 Till Kamppeter 2007-05-18 11:06:49 UTC
More info (most posted already on IRC):

Here is an example for a failure of pdf2ps. The command line

gs -dNOPAUSE -dQUIET -dBATCH -sDEVICE=pswrite -sOutputFile=x -f
~/ghostscript/gpl/testfiles/Mo03_ThomasNau_ZFS.pdf -c "save pop quit"

seems to hang, with a PDF file containing pictures. When I wait some time and do
Ctrl-C the file x is created and HUGE, and gv displays it. Seems that GS makes a
very hi-res bitmap from the PDF and takes ages. So pdf2ps will exit in some days
(or in some hours if your disk is full).

A simple PDF without pictures converts in a reasonable time, but it also seems
to be something bitmappish.

gv uses the command line

gs -sDEVICE=x11 -dTextAlphaBits=4 -dGraphicsAlphaBits=2 -dMaxBitmap=10000000

And while it is hanging it does not consume any CPU. There is also a very shoert
PostScript file in the /tmp directory. It contains nearly only DSC comments, no
"showpage" and a "<page number> DoPDFPage" line for each page. It looks like this:

%%Title: (Optimizing Adobe PDF Files for Accessibility)
%%CreationDate: (D:19991115100307)
%%DocumentMedia: y792x612 612 792 70 white ()
%%Pages: 10
/Page null def
/Page# 0 def
/PDFSave null def
/DSCPageCount 0 def
/DoPDFPage {dup /Page# exch store pdfgetpage pdfshowpage } def
GS_PDF_ProcSet begin
pdfdict begin
(pdfaccess.pdf) (r) file { DELAYSAFER { .setsafe } if } stopped pop
 pdfopen begin
%%Page: (1) 1
%%PageMedia: y792x612
%%PageBoundingBox: 0 0 612 792 
%%PageOrientation: Portrait
1 DoPDFPage
%%Page: (2) 2
%%PageMedia: y792x612
%%PageBoundingBox: 0 0 612 792 
%%PageOrientation: Portrait
2 DoPDFPage
%%Page: (3) 3
%%PageMedia: y792x612
%%PageBoundingBox: 0 0 612 792 
%%PageOrientation: Portrait
3 DoPDFPage
%%Page: (4) 4
%%PageMedia: y792x612
%%PageBoundingBox: 0 0 612 792 
%%PageOrientation: Portrait
4 DoPDFPage
%%Page: (5) 5
%%PageMedia: y792x612
%%PageBoundingBox: 0 0 612 792 
%%PageOrientation: Portrait
5 DoPDFPage
%%Page: (6) 6
%%PageMedia: y792x612
%%PageBoundingBox: 0 0 612 792 
%%PageOrientation: Portrait
6 DoPDFPage
%%Page: (7) 7
%%PageMedia: y792x612
%%PageBoundingBox: 0 0 612 792 
%%PageOrientation: Portrait
7 DoPDFPage
%%Page: (8) 8
%%PageMedia: y792x612
%%PageBoundingBox: 0 0 612 792 
%%PageOrientation: Portrait
8 DoPDFPage
%%Page: (9) 9
%%PageMedia: y792x612
%%PageBoundingBox: 0 0 612 792 
%%PageOrientation: Portrait
9 DoPDFPage
%%Page: (10) 10
%%PageMedia: y792x612
%%PageBoundingBox: 0 0 612 792 
%%PageOrientation: Portrait
10 DoPDFPage
currentdict pdfclose

This file displays correctly with "gs -sDEVICE=x11" if the original PDF file
(here pdfaccess.pdf) is in the current working directory.

Trying to open the file with gv lets gv hang, as opening the original PDF in gv.

When opening a PDF with gv and gv hangs, clicking 2 or 3 times on "Reload" makes
the contents of the current page appear, but when navigating to another page,
the page is blank (but can be made appearing with 2 or 3 clicks on "Reload").

It seems that gv does not pass the original PDF through above-mentioned command
line. I create a little wrapper for Ghostscript, /tmp/gs:

tee /tmp/x | /usr/local/bin/gs $*

and under "State"/"Ghostscript options ..." I have set "/tmp/gs" as
"Interpreter". This way the input stream gets captured. After having started gv
and arriving at the blank first page with waiting mouse cursor the file /tmp/x

/Page null def
/Page# 0 def
/PDFSave null def
/DSCPageCount 0 def
/DoPDFPage {dup /Page# exch store pdfgetpage pdfshowpage } def
GS_PDF_ProcSet begin
pdfdict begin
(pdfaccess.pdf) (r) file { DELAYSAFER { .setsafe } if } stopped pop
 pdfopen begin
%%Page: (1) 1
%%PageMedia: y792x612
%%PageBoundingBox: 0 0 612 792 
%%PageOrientation: Portrait
1 DoPDFPage

Hitting "Reload" once makes the first page visible, without any new data in /tmp/x.

Clicking on page #2 in gv adds the following output to /tmp/x

%%Page: (2) 2
%%PageMedia: y792x612
%%PageBoundingBox: 0 0 612 792 
%%PageOrientation: Portrait
2 DoPDFPage

and the 1st page stays displayed.

"Reload" -> /tmp/x gets deleted, bklank page
Another "Reload" shows the second page with

%%Page: (2) 2
%%PageMedia: y792x612
%%PageBoundingBox: 0 0 612 792 
%%PageOrientation: Portrait
2 DoPDFPage

added to /tmp/x.

The temporary file of gv, which seems also the input for Ghostscript for
displaying the PDF seems to be generated by the command line defined in
"State"/"Ghostscript options ..." under "Scan PDF".

In our case

gs -dNODISPLAY -dQUIET -sPDFname=pdfaccess.pdf -sDSCname=<tmpfile> pdf2dsc.ps -c

is executed.

I tried to revert pdf2dsc.ps to the version of GPL GS 8.56 (no page label
support), but this did not solve the problem. So it seems to be somewhere in the
Ghostscript process which does the display itself.
Comment 3 Till Kamppeter 2007-05-18 16:24:31 UTC
I could display the file pdfaccess.pdf with gv again when reverting
lib/pdf_main.ps to the file which comes with GPL Ghostscript 8.56. Then I tried
to undo all changed which happened to the file after release of GPL Ghostscript
8.56 and found that rev 7834 was the offending one. Reverting the following patch

--- lib/pdf_main.ps     (revision 7833)
+++ lib/pdf_main.ps     (revision 7834)
@@ -76,7 +76,7 @@
   } loop
   exch pop
-    dup 127 string .peekstring { % "128 string" doesn't work for "(%stdin) run"
+    dup 1023 string .peekstring { % "1024 string" exceeds current %stdin buffer
       (%PDF-1.) search {
         3 1 roll pop pop
         dup (%!PS) search not {

makes gv displaying pdfaccess.pdf again.
Comment 4 Till Kamppeter 2007-05-18 16:33:42 UTC
Now both gv and kghostview work again if one turns off anti-aliasing.

Using gv with anti-aliasing I get in PDF files with 

Error: /rangecheck in --.discardtransparencygroup--

kghostview simply shows a blank page.

Another file lets gv simply hang with Anti-aliasing.
Comment 5 Till Kamppeter 2007-05-18 16:37:56 UTC
I have checked now, anti-aliasing was already broken with the pdf_main.ps of GPL
GS 8.56.
Comment 6 Till Kamppeter 2007-05-18 16:54:40 UTC
The antialiasing problem I get also without the frontends gv and kghostview. If
I simply copy and paste the anti-aliasing Ghostscript command lines from their
configuration dialogs

gs -sDEVICE=x11 -dTextAlphaBits=4 -dGraphicsAlphaBits=2 -dMaxBitmap=10000000

I get the same errors/problems as when I use the frontends.

And when I remove "-dMaxBitmap=10000000" it works again, both the direct command
line and the GUI tools.

For what is/was "-dMaxBitmap=10000000" good for?
Comment 7 Till Kamppeter 2007-05-18 17:00:03 UTC
Now after removing "-dMaxBitmap=10000000" from the anti-aliasing command line gv
cannot dislay the CUPS test page (/usr/share/cups/data/testprint.ps) any more
with anti-aliasing. I get the following error:

Error: /unknownerrorGPL Ghostscript SVN PRE-RELEASE 8.60: Unrecoverable error,
exit code 1
 in --stroke--
Operand stack:

Execution stack:
   %interp_exit   .runexec2   --nostringval--   --nostringval--  
--nostringval--   2   %stopped_push   --nostringval--   --nostringval--  
--nostringval--   false   1   %stopped_push   1889   1   3   %oparray_pop   1888
  1   3   %oparray_pop   1872   1   3   %oparray_pop   1755   1   3  
%oparray_pop   --nostringval--   %errorexec_pop   .runexec2   --nostringval--  
--nostringval--   --nostringval--   2   %stopped_push   --nostringval--
Dictionary stack:
   --dict:1146/1684(ro)(G)--   --dict:0/20(G)--   --dict:80/200(L)--
Current allocation mode is local
Error: /unknownerror in --stroke--
Operand stack:

Execution stack:
   %interp_exit   .runexec2   --nostringval--   --nostringval--  
--nostringval--   2   %stopped_push   --nostringval--   --nostringval--  
--nostringval--   false   1   %stopped_push   1889   1   3   %oparray_pop   1888
  1   3   %oparray_pop   1872   1   3   %oparray_pop   1755   1   3  
%oparray_pop   --nostringval--   %errorexec_pop   .runexec2   --nostringval--  
--nostringval--   --nostringval--   2   %stopped_push   --nostringval--
Dictionary stack:
   GPL Ghostscript SVN PRE-RELEASE 8.60: Unrecoverable error, exit code 1
--dict:1146/1684(ro)(G)--   --dict:0/20(G)--   --dict:80/200(L)--
Current allocation mode is local
Error: /unknownerrorGPL Ghostscript SVN PRE-RELEASE 8.60: Unrecoverable error,
exit code 1
 in --stroke--
Operand stack:

Execution stack:
   %interp_exit   .runexec2   --nostringval--   --nostringval--  
--nostringval--   2   %stopped_push   --nostringval--   --nostringval--  
--nostringval--   false   1   %stopped_push   1889   1   3   %oparray_pop   1888
  1   3   %oparray_pop   1872   1   3   %oparray_pop   1755   1   3  
%oparray_pop   --nostringval--   %errorexec_pop   .runexec2   --nostringval--  
--nostringval--   --nostringval--   2   %stopped_push   --nostringval--
Dictionary stack:

Without anti-aliasing the test page displays correctly.
Comment 8 Till Kamppeter 2007-05-18 17:06:11 UTC
But the test page displays with anti-aliasing when putting the
"-dMaxBitmap=10000000" back in.

So there are two things to fix:

1. Reverting the changes of rev 7834 makes the PDFs displaying again, but rev
7834 has fixed bug #687125 (Increase of stdin buffer to find %PDF tag). Both
problems need to be solved somehow.

2. Anti-aliasing works for PDF files only with "-dMaxBitmap=10000000" removed
but for the CUPS test page only with "-dMaxBitmap=10000000" present. As the
current versions of the frontends use "-dMaxBitmap=10000000", all files should
display with "-dMaxBitmap=10000000" present.

Comment 9 Till Kamppeter 2007-05-18 17:11:30 UTC
As pdf2ps consumes CPU when it hangs (and it really runs slowly, as it produces
a huge output file), it is another problem, no the one described in this bug. It
looks like one of the several PDF performance problems reported in other bug
reports here.
Comment 10 Till Kamppeter 2007-05-22 08:32:50 UTC
I have investigated more and one can find a maximum size for the string
allocated in line 79 of pdf_main.ps

dup 127 string .peekstring

where gv displays the file and if one increases the size by one gv hangs. This
maximum length depends on the file. In my pdfaccess.pdf file it is 405:

dup 405 string .peekstring

pdf_main.ps is reading data from stdin, and this data gets fed in by gv (or
kghostview). It seems that gv is not feeding in the data quickly enough or not
in a continuous way. Perhaps gv feeds in only a very small amount of data (in
our case 405 bytes) and then waits for a reaction of Ghostscript, but
Ghostscript waits for gv to feed the requested 1023 bytes before it answers to
gv. And so the two simply hang waiting for each other.

If Ghostscript requests only 127 bytes, as the old versions did and the goes on
(outputting something to gv) gv has no problem.
Comment 11 Ray Johnston 2007-05-22 09:58:33 UTC
The 8.57 has changes for 1023 string .peekstring

I will re-test with 8.57

peekstring will wait for the requested number of bytes (1023) before
processing in pdf_main.ps

Any application piping data to gs stdin must send the entire file, then
close stdin (at which point peekstring will proceed).
Comment 12 William Bader 2007-05-24 18:16:03 UTC
Created attachment 2978 [details]
Patches to gv-3.5.8

I had the same problem with some pdf files and with short ps files where gs
could display them alone but the combination of gv and gs would hang.
The hangs happened if the file had DSCs and the sum of the chunks that gv wrote
to gs was less than 1023 bytes.
I changed Input() in Ghostview.c to write 1023 new lines at the end of the
page, and that fixes most of the problems.

I still have problems with a large ps file that is fine with gv and gs8.54 and
alone with gs8.56 and 8.57, but it sometimes gets errors with gv and gs8.56 or
8.57.  The errors happen in different places and rarely happen on my Pentium M
laptop but happen almost all the time on a Xeon desktop that /proc/cpuinfo
reports as having four processors.  It seems like gs8.56 and 8.57 have problems
if they get ahead of gv.
Comment 13 Till Kamppeter 2007-07-05 14:09:19 UTC
Created attachment 3162 [details]
This PDF works only without anti-aliasing
Comment 14 William Bader 2007-07-21 15:05:39 UTC
I have another problem that might be related.  I have a 115 MB postscript file
that views fine directly with gs 8.57.  If I view the file through gv, gs
reports postscript errors.  The error is different each time that I run gv. 
Also, if I use a script with tee to catch the data that gv passes to gs until gs
stops taking input, I have seen the size of the file vary from 6 MB to 36 MB.  I
have Red Hat Fedora Core 3, and if I set gv to use Fedora's gs 7.07 from
/usr/bin/gs, the file views every time without errors.  It seems as if something
changed in gs between 7.07 and 8.57 that gs fails if it is reading from a pipe
and gets ahead of the program writing into the pipe.  I can not post the file to
a public area, but I could send it privately.  I can create other files that
show this problem, some as small as 20 MB.
Comment 15 Ralph Giles 2007-07-24 10:21:59 UTC
The patch to gv should be committed; the view behaviour here looks wrong.

However, we can provide compatibility. The resolution of this bug is to modify
pdf_main.ps to first check for a file id in the first 127 bytes, and check the
first 1023 if and only if that check fails to make a determination. This will
allow the majority of files to render even if the viewer does not send an EOF.

If the other, unrelated issues mentioned in the discussion persist after this
change please open separate bugs with test files for each of them.
Comment 16 Ray Johnston 2007-07-28 23:41:10 UTC
For the gv hang problem with 8.57, please try the following patch to 
lib/pdf_main.ps with an UNMODIFIED version of gv. 
It isn't clear that this will work since I don't know if 'gv' sends %! as the start 
of PS file input to gs. 
If simple cases still hang (without using CPU or disk which indicates a deadlock), 
then the only solution is changing 'gv' to emit the %! before sending PS (with 
the patch below) , or to use the 'padding' kloodge which might be a problem 
if the gs buffer sizes are changed again later. 
The patch to test is: 
*** lib/pdf_main.ps     Sat Jul 28 23:40:38 2007 
--- ./pdf_main.ps       Sat Jul 28 23:35:48 2007 
*** 79,84 **** 
--- 79,88 ---- 
    } loop 
    exch pop 
+     % First check for the 'minimal' PS header since interactive 
+     % apps sending small strings via stdin might need response 
+     % from the PS interpreter (e.g., Apple PAP does this). 
+     dup 2 string .peekstring pop (%!) ne { 
        dup 1023 string .peekstring pop dup length 400 ge { 
        % "1024 string" exceeds current %stdin buffer 
        % Valid PDF file cannot be smaller than 400 bytes. 
*** 123,128 **** 
--- 127,135 ---- 
        pop cvx .runps   % too short for PDF 
        } ifelse 
      } { 
+       cvx .runps      % found an initial (%!) 
+     } ifelse 
+   } { 
      closefile % file was empty 
    } ifelse 
  } bind odef 
Note that other bugs mentioned below unrelated to the 1023 string change 
should be opened as separate bugs. Basically, if gs is consuming CPU or disk, 
then it is not a 'deadlock' and should be reported as 'slow processing'. 
Comment 17 William Bader 2007-07-29 05:21:46 UTC
Thanks for the patches, but they did not help.  gs 8.57 with the patch to
pdf_main.ps still hangs with an unpatched gv 3.6.2.  The hang leaves the cpu
idle.  Here are my results:
* unpatched gv-3.6.2 + unpatched gs 8.57:
 hangs with cpu idle and "State -> Respect document structure" enabled
 OK when disabled
* patched gv-3.5.8 + unpatched gs 8.57:
 OK with either setting "Respect document structure"
* ggv-2.8.0 + unpatched gs 8.57:
 OK but ggv has "Respect document structure" permanently disabled
Applying the patch does not make a difference.
For reference, I will attach
gv-3.5.8.pat (my patches to gv updated 31 May 07)
gs857-pdfmain.pat (the patches that I applied to pdf_main)
gv-hang-1024.ps (a test file based on the one by Till Kamppeter)
gv.ini (my .gv resource file)
gs8.57.pat (unrelated patches to gs)
Comment 18 William Bader 2007-07-29 05:26:24 UTC
Created attachment 3228 [details]
Patches to gv-3.5.8, version 31 May 07

Patches to make gv work better with gs and to fix parsing of some comments.
Comment 19 William Bader 2007-07-29 05:27:43 UTC
Created attachment 3229 [details]
patch to pdf_main.ps

This is the patch to fix hangs that I applied for testing.  It did not seem to
Comment 20 William Bader 2007-07-29 05:30:42 UTC
Created attachment 3230 [details]
Test file for hangs with gv + gs

This is a file for testing hangs when viewing files with gv + gs.  The file
posted earlier required an external file called pdfaccess.pdf.	This file is
all postscript and does not reference any external files.
Comment 21 William Bader 2007-07-29 05:32:30 UTC
Created attachment 3231 [details]
gv init file

A .gv file that shows my initial settings of gv parameters.
Comment 22 William Bader 2007-07-29 05:36:15 UTC
Created attachment 3232 [details]
Misc patches to gs 8.57

My misc patches to gs 8.57 unrelated to this issue that improve other issues
with gv/gs interaction.
Comment 23 William Bader 2007-07-29 05:42:26 UTC
Created attachment 3233 [details]
Example ps file for my gs patches

This is a sample file that displays cropped if you open it in gv and change the
page size larger than letter.  My patches to gs fix the problem by changing
gdevxini.c to take the page size passed by gv.
Comment 24 Ray Johnston 2007-08-01 10:26:03 UTC
The problem with the patch given in comment  #16 is that gv is sending  
a sequence beginning with %% not %!  
The patch to let gv work without modifications is rev 8159 and WILL be in 
the 8.60 release today. 
Note that this bug has collected a bunch of comments unrelated to the 
hang (or at least the gv hang that was well documented). 
We aren't really set up to process bugs with multiple topics and different 
actual bugs. I am closing this bug as 'FIXED' even though some of the 
other issues may still exist (the comment is thread is such a hodge podge 
that I am not really sure) and ask that those be opened as SEPARATE bugs 
in the tracker by the person adding the topic here.