SDB:How to Report a Printing Issue
tagline: From openSUSE
|Tested on openSUSE||Recommended articles||Related articles|
- 1 Situation
- 2 Basics
- 3 In any case without exception tell the exact printer model name
- 4 In any case without exception tell how the printer is connected
- 5 Always tell which printer driver is used
- 6 Always tell the openSUSE version
- 7 Always tell exactly what you did
- 8 Usually provide an example file
- 9 It always helps to simulate printout on a virtual generic PostScript printer
- 10 Usually provide CUPS debug messages
- 11 Do not overdo things
- 12 Background Information
- 13 See also
You have a printing issue and like to ask for help or report a bug but you do not know which information you must provide so that others can help you or understand your bug report.
Optionally you may like to diagnose the cause of your printing issue. Some basic tests are described below.
See Concepts printing for information about printing basics.
Do not assume someone knows about your particular environment and what you did.
In any case provide sufficient information about your particular environment and what you did and usually provide CUPS debug messages.
On the other hand do not overdo things by flooding the audience with tons of information that was not requested.
In general regarding "How to Report Bugs Effectively" it is recommended to have a look at http://www.chiark.greenend.org.uk/~sgtatham/bugs.html which reads in particular (excerpts):
In a nutshell, the aim of a bug report is to enable the programmer to see the program failing in front of them.
When you report a bug, you are doing so because you want the bug fixed. There is no point in swearing at the programmer or being deliberately unhelpful: it may be their fault and your problem, and you might be right to be angry with them, but the bug will get fixed faster if you help them by supplying all the information they need. Remember also that if the program is free, then the author is providing it out of kindness, so if too many people are rude to them then they may stop feeling kind.
Give the programmer some credit for basic intelligence: if the program really didn't work at all, they would probably have noticed. Since they haven't noticed, it must be working for them. Therefore, either you are doing something differently from them, or your environment is different from theirs. They need information; providing this information is the purpose of a bug report.
Providing your own diagnosis might be helpful sometimes, but always state the symptoms. The diagnosis is an optional extra, and not an alternative to giving the symptoms.
By all means try to diagnose the fault yourself if you think you can, but if you do, you should still report the symptoms as well.
First and foremost it is crucial to provide a clear description of the plain symptoms and your environment and what you did without any intermixed conclusion or personal opinion.
Optionally but strictly separated you may try to diagnose the cause of your printing issue. For some basic tests see in particular the sections "Basic tests when printing from an application program fails", "Test if what the application had submitted to CUPS seems to be correct", and "Simulate the printout on a virtual generic PostScript printer".
Never wander from the subject by complaining or spilling out your personal frustration about the issue. Try as good as you can to stick to the facts and focus on providing a clear description of the symptoms and your environment and what you did exactly.
In any case without exception tell the exact printer model name
Even if you are 100% sure that your particular issue cannot depend on your particular printer model, tell the model nevertheless.
Provide the exact model name as labeled on the printer device. For example when the device is labeled "ACME FunPrinter 1000 XL+" then provide its full name and not any kind of abbreviation like "ACME 1000 XL" because there could be a different model "ACME FancyPrinter 1000 XL" and even tiny details like the '+' could make a difference whether or not the particular model works.
In any case without exception tell how the printer is connected
Even if you are 100% sure that your particular issue cannot depend on how the printer is connected to your system, provide that information nevertheless.
What does the YaST "Add New Printer Configuration" or "Modify" dialog (see YaST Printer) or whatever setup tool show as connection?
Or more precisely: What is the CUPS device URI on the Linux system from where you submit the print job? I.e. what is the output of the command
lpstat -v <queue_name>
provided you have already set up your printer (replace <queue_name> with your print queue name).
If printer setup failed, provide the output of the command (run it as root)
that lets CUPS autodetect printers (but not all printers can be autodetected).
If your printer is not autodetected describe precisely how it is connected to the Linux system from where you submit the print job.
For example directly via USB cable or indirectly via whatever kind of adapter in between (e.g. a USB to parallel port adapter cable or an Internet router box or a laptop docking station) or directly via network by traditional ethernet cable or indirectly via whatever networking stuff in between (e.g. WLAN or a print server).
If your printer is connected indirectly and not autodetected by "lpinfo -v" try to connect it directly (i.e. directly via USB cable or directly via traditional ethernet cable).
In particular for network printers see SDB:Printing via TCP/IP network.
Always tell which printer driver is used
Do not assume it is irrelevant which exact driver you use for your particular printer model.
What does the YaST "Add New Printer Configuration" or "Modify" dialog (see YaST Printer) or whatever setup tool show as driver?
Or more precisely: What are the NickName and cupsFilter entries in the PPD in /etc/cups/ppd/<queue_name>.ppd (replace <queue_name> with your print queue name)? I.e. what is the output of the command
egrep 'NickName|cupsFilter' /etc/cups/ppd/<queue_name>.ppd
provided you have already set up your printer. If printer setup failed, see below.
Do you use the driver from the openSUSE printer driver software packages (see Concepts printing) or do you use other driver software like drivers from the printer manufacturer?
If you use other driver software, provide an URL wherefrom you got the other driver software.
Always tell the openSUSE version
Always tell which openSUSE version you use and how you installed it.
Was it an update of an existing older openSUSE version (if yes, which exact older version) or did you install your current openSUSE version from scratch?
Do you use only software packages from openSUSE or do you also use other software like newer versions of particular packages or self-compiled software which might be related to your printing issue?
If you use other software which might be related to your printing issue, tell which exact other software it is and provide an URL wherefrom you got the other software.
Always tell exactly what you did
Do not assume others know what you did.
Even if you are 100% sure that your particular way how you do it is the same as all others do, tell exactly what you did nevertheless.
If printer setup fails
Which printer setup tool are you using?
We have many printer setup tools which could be launched via various ways depending on which desktop is currently used:
- YaST printer setup tool (see YaST Printer)
- Gnome printer setup tool ("system-config-printer")
- KDE printer setup tool
- CUPS web frontend (see SDB:CUPS in a Nutshell)
- CUPS command line tools ("lpinfo"/"lpadmin", see SDB:CUPS in a Nutshell)
- for HP devices: HP's setup tool "hp-setup" (see SDB:How to set-up a HP printer)
- anything else (e.g. a setup tool from a printer manufacturer)
If you don't know which printer setup tool the desktop magic runs, provide a screenshot or try if there is a "help" or "about" info in your printer setup tool.
Tell exactly step by step what you did in the printer setup tool and what the printer setup tool shows to you in each step (in particular exact error messages).
Probably best is to run the printer setup tool in English language and provide some screen shots for those printer setup tool dialogs that are presumably of most interest so that others can understand what you did in the printer setup tool and what the printer setup tool shows to you.
In particular when there are issues with the YaST printer setup tool see openSUSE:Bugreport_YaST how to "Report a YaST bug" where most important is to "attach y2logs".
Basic tests when printing from an application program fails
Does printing a test page from a printer setup tool work?
YaST provides a "Print Test Page" button in its initial "Printer Configurations" dialog.
Does printing from the command line work?
Does printing work when you run the following commands? Replace <queue_name> with your print queue name and use the command that matches the media (A4 or Letter) that is actually loaded in your printer:
echo Hello | lp -d <queue_name>
echo A4 | a2ps -1 -j -M A4 -o- | lp -d <queue_name> echo Letter | a2ps -1 -j -M Letter -o- | lp -d <queue_name>
echo -e 'One\fTwo' | lp -d <queue_name>
echo -e 'A4-1\fA4-2' | a2ps -1 -j -M A4 -o- | lp -d <queue_name> echo -e 'Letter-1\fLetter-2' | a2ps -1 -j -M Letter -o- | lp -d <queue_name>
You should get:
- one page with "Hello"
- one page with "A4" or "Letter"
- two pages with "One" and "Two"
- two pages with "A4-1" and "A4-2" or "Letter-1" and "Letter-2"
When a2ps (package a2ps) is not available use enscript (package enscript) that also accepts the above options, for example:
echo A4 | enscript -1 -j -M A4 -o- | lp -d <queue_name> echo Letter | enscript -1 -j -M Letter -o- | lp -d <queue_name>
If the output of the commands for "A4" or "Letter" does not fit on your paper, try out the following commands:
echo A4 | a2ps -1 -j -M A4 -o- | lp -d <queue_name> -o PageSize=A4 echo Letter | a2ps -1 -j -M Letter -o- | lp -d <queue_name> -o PageSize=Letter
If one of those comands works, you need to adjust the default paper size of your print queue and also in your application program to match what is actually loaded in your printer.
To adjust the default paper size of a print queue run as root one of those commands:
lpadmin -p <queue_name> -o PageSize=A4 lpadmin -p <queue_name> -o PageSize=Letter
It depends on the particular application program how to adjust its paper size to match what is actually loaded in the printer.
Does printing from other application programs work?
Does printing work when you run the same application program under a different user account?
You may set up a new test-user and try to print as the test-user. Different users could obtain different printout results, even though they print identical data via the same print queue, see SDB:Print Settings with CUPS.
Which application program are you using where printing fails?
If you don't know which application program the desktop magic runs, provide a screenshot or try if there is a "help" or "about" info in your application program.
If printing from an application program fails, provide sufficient information so that others have a chance to reproduce the failure.
In particular tell when you changed any of the default settings in the print dialog of the application program e.g. "landscape" printing (see SDB:Landscape Printing) or a high resolution like "1200x1200dpi" (see SDB:Laser Printer Does Not Print Properly Or Does Not Print At All).
If printing from command line fails
Provide the exact printing command and a small example file (when you print a file) where printing fails for you.
Usually provide an example file
If printing from an application program fails or if printing from command line fails, provide an example file that fails for you (or a reference to a public accessible example file).
For example when printing from a browser fails, provide an URL to a commonly known and public accessible web page (e.g. an openSUSE web page) where the printout of this web page fails in the particular browser.
When the application program works with files (for example a PDF reader or an office software like LibreOffice/OpenOffice), provide a small example file where the printout of this example file fails in the particular application program. For example a small PDF file for a PDF reader or a small LibreOffice/OpenOffice document when printing from LibreOffice/OpenOffice fails.
Do not provide big example files like PDFs or office documents with many pages. Even if the failure happens for you on page 123 of a 234 pages document, do not provide the whole document. Instead try to extract only the part of the document which causes the failure (e.g. only page 122 up to 124) and provide this as small example document - provided it still fails for you with your example document.
If printing from an application program fails, provide additionally what the application submits as printing data to CUPS when printing exactly that example file. A precondition is that printing from an application program does not already fail in the application itself when it makes its printing data before it gets submitted to CUPS.
Get what the application submits to CUPS
To get what the application submits to CUPS do the following:
- Stop printing for your print queue. As user 'root' run "cupsdisable <queue_name>" (replace <queue_name> with your print queue name).
- Clean up all your print queues. As user 'root' run "cancel -a" or since CUPS 1.7 "cancel -a -x" which completely removes all existing (old) print jobs (including job history) in all print queues.
- As normal user print the exact example file where printing fails from the particular application program.
- What the application had submitted in the previous step to CUPS is now hold in the print queue as /var/spool/cups/d<job_number>-001 (see "Saving the print job in the spool directory" in SDB:CUPS in a Nutshell).
- Save the print job data for further analysis. As user 'root' run "cp /var/spool/cups/d<job_number>-001 /tmp/print-job-data.save" (replace <job_number> with your actual print job number) and "chmod a+r /tmp/print-job-data.save" to make it accessible also as normal user for later analysis (see below).
- Clean up the print queue. As user 'root' run "cancel -a <queue_name>" or since CUPS 1.7 "cancel -a -x <queue_name>" (replace <queue_name> with your print queue name).
- Re-enable printing for your print queue. As user 'root' run "cupsenable <queue_name>" (replace <queue_name> with your print queue name).
- Now /tmp/print-job-data.save can be inspected at your leisure.
If printing from an application program fails, the first test is to check if what the application had submitted as printing data to CUPS seems to be correct.
Test if what the application had submitted to CUPS seems to be correct
Usually application programs submit either PostScript or PDF as printing data format to CUPS (see "common printing format" at Concepts printing).
Get what the application had submitted to CUPS as described above and test that it is actually PostScript or PDF:
This should report that it is a PostScript or PDF document.
If "file /tmp/print-job-data.save" reports "gzip compressed data" first uncompress it with
mv /tmp/print-job-data.save /tmp/print-job-data.save.gz gunzip /tmp/print-job-data.save.gz
and afterwards test again with "file /tmp/print-job-data.save" that it is a PostScript or PDF document.
Only for PostScript or PDF the following tests with Ghostscript can work:
To test if the PostScript or PDF that an application had submitted to CUPS seems to be correct, display it with Ghostscript. Depending on the paper size in your printer use one of the following commands:
gs -r50 -sPAPERSIZE=a4 -dFIXEDMEDIA /tmp/print-job-data.save gs -r50 -sPAPERSIZE=letter -dFIXEDMEDIA /tmp/print-job-data.save
This opens a X11-window that shows the graphical content of a PostScript or PDF page. At the command line where you typed the "gs" command, press the [Enter/Return] key to show the next page. To exit Ghostscript type "quit" or press the [Ctrl/Strg]+[C] keys.
Possible errors are shown at the command line where you typed the "gs" command. In case of errors, the application had submitted invalid PostScript or PDF to CUPS.
To only test if the PostScript or PDF is valid run:
gs -r50 -dNOPAUSE -dBATCH -sDEVICE=nullpage /tmp/print-job-data.save
With "-dNOPAUSE -dBATCH" Ghostscript processes the PostScript or PDF pages continuously but "-sDEVICE=nullpage" does not show the graphical content. If there are no errors, it only means that Ghostscript does not fail to process it. When you have a PostScript printer the printer might fail to print it nevertheless (see Concepts printing).
If there are no errors, check if the graphical content is what you expect.
The "-r" parameter specifies the resolution so that "-r100" shows the graphical content at double size compared to "-r50".
If the window that shows the graphical content is too small to show the whole content you can specify a big window size in pixels like:
gs -r50 -g900x900 /tmp/print-job-data.save
The graphical content that is shown by Ghostscript is what the application had submitted and what your printer should print.
For details how to use Ghostscript see the file /usr/share/ghostscript/<ghostscript-version>/doc/Use.htm of your currently installed Ghostscript version.
It always helps to simulate printout on a virtual generic PostScript printer
The goal behind simulating the printout on a virtual generic PostScript printer is to find out if the root cause is a generic issue or if the root cause is more likely related to a particular printer driver software which helps a lot to diagnose the specific root cause of your particular printing issue (cf. "it becomes complicated when you look at a real particular case" in the "Background Information" section below).
Even if printer setup failed for your particular printer device it should always work to set up a virtual generic PostScript printer so that it should always be possible to simulate printout on a virtual generic PostScript printer.
A generic PostScript printer is THE reference printer device because PostScript is the traditional printing data format (cf. Concepts printing). Therefore a generic PostScript printer can be used to verify whether or not printing works in general. This means when the printout is o.k. on a generic PostScript printer, the root cause is probably not a generic issue but more likely related to a particular printer driver software.
The basic idea how to set up a virtual generic PostScript printer is to set up a separated test print queue for a generic PostScript printer (by using a PPD file for a generic PostScript printer) that outputs the final printing data (generic PostScript) into a file.
To output the final printing data into a file you must specify "FileDevice Yes" in /etc/cups/cups-files.conf since CUPS >= 1.6 (for CUPS up to 1.5.4 "FileDevice Yes" has to be set in /etc/cups/cupsd.conf).
Additionally you should set "LogLevel debug" in /etc/cups/cupsd.conf to get verbose (i.e. meaningful) CUPS logging and debug messages in the /var/log/cups/error_log file.
After changing /etc/cups/cupsd.conf or /etc/cups/cups-files.conf you must restart the cupsd (cf. "Usually provide CUPS debug messages" below).
Set up the test queue (as root):
lpadmin -p testq -v file:/tmp/testq.out.ps -P /usr/share/cups/model/Postscript.ppd.gz -E
Use /usr/share/cups/model/Postscript.ppd.gz for a generic PostScript printer. Do not use a PPD file for a particular specific PostScript printer model.
Explicitly specify A4 or Letter page size by using one of the following commands (as root):
lpadmin -p testq -o PageSize=A4 lpadmin -p testq -o PageSize=Letter
As normal user print the exact example file where printing fails from the particular application program to the "testq" or when printing via command line print the exact example file where printing fails via command line to the "testq".
The final printing data appears in the file /tmp/testq.out.ps which can only be read by root.
If there is no data in /tmp/testq.out.ps (or if /tmp/testq.out.ps contains invalid PostScript), then print job processing of your example file had failed and you may inspect the /var/log/cups/error_log file for error messages that may indicate why print job processing of your example file had failed, see below how to get and provide "CUPS debug messages only for one single failed print job".
When there is data in /tmp/testq.out.ps you can use (as root) "chmod a+r /tmp/testq.out.ps" to make it readable by any user.
To view how the printout on a generic PostScript printer would look like, display /tmp/testq.out.ps with Ghostscript (cf. "Test if what the application had submitted to CUPS seems to be correct" above).
Depending on the paper size use one of the following commands:
gs -r50 -sPAPERSIZE=a4 -dFIXEDMEDIA /tmp/testq.out.ps gs -r50 -sPAPERSIZE=letter -dFIXEDMEDIA /tmp/testq.out.ps
What is shown by Ghostscript is what a generic PostScript printer should print on A4 or Letter paper (except that real generic PostScript printers have more or less wide unprintable margins while Ghostscript shows it up to the edges of the paper).
The "-r" parameter specifies the resolution so that "-r100" shows it at double size compared to "-r50".
If the A4 or Letter page size window is too small to show the whole printout content the root cause is likely that the particular printing application program had submitted content to the print queue that exceeds the printable area that is provided in the PPD file (see also SDB:Landscape Printing).
To show the whole printout content you can specify a big window size in pixels like:
gs -r50 -g900x900 /tmp/testq.out.ps
When you do no longer need the test queue remove it (as root):
lpadmin -x testq
Usually provide CUPS debug messages
In almost all cases when printing does not work you should provide CUPS debug messages:
- In /etc/cups/cupsd.conf set "LogLevel debug". As user 'root' set the "LogLevel" value to "debug" in /etc/cups/cupsd.conf using a plain text editor like 'vi' or 'nano', see Text editor.
- Stop cupsd. As user 'root' run "rccups stop" or in case of systemd use appropriate systemctl commands like "systemctl stop cups.service" and so on (check the output of "systemctl list-units | grep cups" and "systemctl list-unit-files | grep cups").
- Move /var/log/cups/error_log to another location (or delete it) in order to avoid having to search through gigantic log files. As user 'root' run "mv /var/log/cups/error_log /var/log/cups/error_log.old" (or "rm /var/log/cups/error_log").
- Start cupsd. As user 'root' run "rccups start" or in case of systemd use appropriate systemctl commands like "systemctl start cups.service" and so on.
- Retry the action leading to the problem (i.e. usually try to print again what had failed to print).
- Now /var/log/cups/error_log contains many messages that are useful for troubleshooting.
- Save the current /var/log/cups/error_log for further analysis. As user 'root' run "cp /var/log/cups/error_log /tmp/cups.error_log.save".
- Now /tmp/cups.error_log.save can be inspected for interesting messages at your leisure.
Provide CUPS debug messages only for one single failed print job. Do not provide a whole /var/log/cups/error_log file, except its content belongs only to one single failed print job.
With "LogLevel debug" some printer drivers may pollute the /var/log/cups/error_log file with zillions of driver internal debug messages which are usually meaningless to find out why a print job failed (such messages may only be provided with "LogLevel debug2" or not at all when they do not show why a print job failed). In such cases only provide those CUPS debug messages which seem to be of real interest regarding the failure of the print job. Look for "error" or "fail" messages and include several lines before the "error" or "fail" message appears in your printing issue report. Try to imagine which of the lines before the "error" or "fail" message could to be of real interest regarding the failure of the print job.
There are a few examples where CUPS debug messages won't help:
When printer setup fails (i.e. it fails to set up a print queue), then CUPS debug messages won't help because without a print queue no print job can be processed by CUPS (see Concepts printing).
If printing from an application program fails in the application itself when it makes its printing data before it gets submitted to CUPS, there is no print job that can be processed by CUPS (see Concepts printing).
When printing basically works (i.e. you get a printout) but there are differences in size or position of the printout on the paper or there is a color cast or there are visual artifacts (see SDB:Purchasing a Printer and Compatibility), then CUPS debug messages won't help because there is no failure of the print job.
When you like to print via a remote CUPS server in the network but this fails, the CUPS debug messages on the remote CUPS server are needed. But when you cannot get them (e.g. because it is a company CUPS server where you do not have access), the CUPS debug messages on your client host from where you submit the print job usually won't help. Nevertheless inspect the CUPS debug messages on your client host to verify that it does not fail on your client host. Furthermore see SDB:Printing via TCP/IP network.
Do not overdo things
Initially you should only provide the above described information.
Do not overdo things by providing tons of low-level debug information that was not requested.
In particular low-level debug messages like "strace" output, backtraces (in particular backtraces without debug info) or even core dumps are usually not really helpful to debug printing-related issues - except you are a sufficient expert to know for which process which particular kind of low-level debug messages is needed and which lines in such an output actually show the root cause of the failure (see openSUSE:Bugreport application crashed).
Also a whole "dmesg" output or even the whole /var/log/messages file is never ever needed to find out the root cause of a printing-related issue.
On the other hand there are printing-related issues where it helps to inspect "dmesg" and /var/log/messages for information which could be of interest regarding the printing-related issue. Such issues are in particular when a locally connected printer is not accessible (see SDB:Installing a Printer). In such cases only provide those messages which seem to be of real interest regarding the printing-related issue. For example if an USB printer is not accessible, you could get usb-related kernel messages via the command:
dmesg | grep -i usb >/tmp/dmesg.usb
Then you can inspect /tmp/dmesg.usb and extract only those messages which seem to be of particular interest regarding the USB printer issue.
Printing is relatively simple from a conceptual point of view: "Just" convert PostScript or PDF into printer-specific data and send that to the printer device (see Concepts printing). But it becomes complicated when you look at a real particular case.
There is no such thing as THE way how to convert PostScript or PDF into printer-specific data.
There are many different ways how an application can make PostScript or PDF, leading to many different ways how PostScript and PDF processing tools (Ghostscript and Poppler/Xpdf) interpret it, together with many different printer drivers where each driver has several driver-specific option settings.
When printing text it depends additionally on the installed font packages which fonts are used by a particular application to make the PostScript or PDF. Furthermore it depends on which software is used for font rendering, for example Ghostscript's font rendering versus FreeType font rendering (see https://bugzilla.novell.com/show_bug.cgi?id=692356).
Furthermore for color printing it depends on the color models that are used in the PostScript or PDF (RGB or CMYK) and by the printer (e.g. CMY, CMYK, CcMmYK, CcMmYy, CcMmYyK).
All together lead to a zillion of ways how printer-specific data can be made for a particular printer with particular driver settings in a particular environment.
Therefore do not assume that something which fails for you also fails for others or that it must have been already detected by those who do beta-testing for openSUSE. Even when it is already a known issue, do not assume that the root cause is "obvious" and an "obvious solution" exists which is correct for all users in any environment.
If you depend on a particular printing functionality in openSUSE, it is you who must test this particular functionality for openSUSE, provide meaningful bug reports, answer questions, and so on.
Be prepared that you may have to report issues which are not caused by openSUSE directly at the matching upstream project. In this case bug reports submitted to openSUSE will get closed as "UPSTREAM", see http://en.wikipedia.org/wiki/Upstream_%28software_development%29 that reads:
Responsibility for a bug is said to lie upstream when it is not caused through the distribution's porting and integration efforts.
In particular when a printing issue depends on the printer model (e.g. a driver does not work or results bad printout quality for a particular printer model), we (i.e. openSUSE) usually do not have such a printer model to reproduce it so that there is basically nothing what we could do in such cases. In contrast when you report the issue directly at the matching upstream project, there is a direct communication between you and the upstream authors.
In general we (i.e. openSUSE) distribute the various printer driver packages from the various upstream projects but we do not develop printer drivers so that usually we cannot do anything when a particular printer driver does not work. In particular usually we cannot reproduce issues with printer drivers.
When a particular printer driver is listed at the matching upstream project that it should work for your particular printer model but it does not work for you with the version that we provide in an openSUSE release you should check if a newer version is already available and try out if the newer version may work for your particular model, see "Version upgrades for printer driver packages" at SDB:Installing a Printer.
I.e. before you report an issue to the driver authors at the matching upstream project you may have to upgrade the printer driver RPM package to the one from the openSUSE "Printing" project and verify that the issue also happens with the currently latest printer driver release.
There is a longer beta-testing phase (a.k.a. "milestones") for each openSUSE release where interested users can test it (see openSUSE:Testing).
"How to Report Bugs Effectively" at http://www.chiark.greenend.org.uk/~sgtatham/bugs.html