Fixing printer page ejection problem

Asked by Stephen A. Smith on 2019-06-06

I have been battling with a page ejection problem using an HP G85 printer on USB on and off for about two years, and have just recently found a probable cause. It seems that I have successfully repaired the problem. Since finding the cause and dealing with it I have had no further page ejection problems.

The printer (an all-in-one printer) was able to scan without difficulty, but would frequently eject the paper part way through a print operation. On a recent occasion I used ps -A immediately after a page ejection to look for processes starting with the characters 'hp'. This showed two processes, 'hpcups' and 'hp'. I then searched for files with the same name and found /usr/lib/cups/filter/hpcups and /usr/lib/cups/backend/hp. Next, I checked which libraries were linked by using ldd on these two file names. At this point my attention was drawn to libpthread.so, which was one of the shared object files linked by hpcups.

On my system, and probably on many other linux systems, /usr/lib/libpthread.so contains a script which looks like this:
/* GNU ld script
   Use the shared library, but some functions are only in
   the static library, so try that secondarily. */
OUTPUT_FORMAT(elf64-x86-64)
GROUP ( /lib64/libpthread.so.0 /usr/lib64/libpthread_nonshared.a )

This script is not typical for the contents of a shared object file. However it can be understood by GNU ld. This linker version can understand such scripts. So if GNU ld is not used there is a danger that when the executable tries to link the shared object file, it will fail. If so, then the associated print operation will also fail.

There is a configuration switch for hplip called --with-gnu-ld. Its default value is 'no'. So what I did was change this so that GNU ld is set at the hplip configuration stage. Incidentally, I am using version 3.19.5 on a 64 bit platform, running linux from scratch. I then reconfigured, rebuilt and installed hplip. Since then hplip has been printing without difficulty. Also I can see from ldd applied to hpcups that the correct shared object file (which is located at /lib/libpthread.so.0) is being linked. It does not contain a script.

On systems which use glibc, it seems likely that one will have access to GNU ld, and this should usually be used. So perhaps that should be the default choice at the configuration stage.

Question information

Language:
English Edit question
Status:
Answered
For:
HPLIP Edit question
Assignee:
No assignee Edit question
Last query:
2019-06-06
Last reply:
2019-06-15

Hi Stephen,

Thanks for your input.
We will verify this issue from our end.

Regards,
Manchikanti Santhosh

Stephen A. Smith (suenos) said : #2

Hi Manchikanti,

I found a way of checking this using ldd, readelf, sed and xargs on my system. If I do:
readelf -h /usr/lib/libpthread.so
I get this:
readelf: Error: Not an ELF file - it has the wrong magic bytes at the start

That is because this libpthread file is actually just a script containing directives for ld. It is not a proper ELF file. An ELF file has 'Executable and Linkable Format', hence the name.

Now I can use ldd on the cups filter, together with sed to strip out extraneous information. This will give me the path for each and every shared object file that the cups filter is linked to. The combination I use for that is this:
ldd /usr/lib/cups/filter/hpcups | sed 's/.*=>//' | sed 's/ (.*//' | grep '/' | grep -v gcc

On my system it gives a long list of such shared object files which starts out like this:
 /usr/lib/libjpeg.so.8
 /lib/libdl.so.2
 /usr/lib/libImageProcessor.so
 /usr/lib/libcups.so.2
 /usr/lib/libcupsimage.so.2
etc. etc.

The reason for the grep -v gcc is that I don't want information about the libgcc_s.so.1 which I do not have permissions to read. I could do that as root, of course, but I don't need that here.

So now that I have my list of shared object files, I can check them all by using readelf -h, and then check whether any of them have the wrong magic bytes. So that looks like this:
ldd /usr/lib/cups/filter/hpcups | sed 's/.*=>//' | sed 's/ (.*//' | grep '/' | grep -v gcc | xargs readelf -h | grep 'wrong magic bytes'

The line wraps should be removed, of course. They are just local editing artifacts. The use of xargs is just to make sure that each one of the file names gets passed to readelf -h.

If the response to this is basically null, then it means that none of the shared object files had the wrong initial magic bytes. However if you see the message 'readelf: Error: Not an ELF file - it has the wrong magic bytes at the start' then you know that at least one of the supposed shared object files is not the real thing, and in that case it means that the cups filter is not correctly linked.

My previous hpcups was linked to /usr/lib/libpthread.so. That was the cause of the problem, because that is not an ELF file. However now it is linked to /lib/libpthread.so.0, which is fine, because that one is an ELF file.

Incidentally, my USB printing is still working fine. And that is even though the printer uses USB version 1.0 whilst the computer it is attached to is working to USB version 3.0. I printed out some photos without problems yesterday.

Also it would be possible to use rather similar techniques to the above to check that all the required libraries are really available on the host.

Best wishes,
Stephen

Can you help with this problem?

Provide an answer of your own, or ask Stephen A. Smith for more information if necessary.

To post a message you must log in.