Wiris Desktop software hangs up whenever a user running it on a 64 bit GNU/Linux platform is trying to open, save, print or whatever action involves opening a GTK Common Dialogue. As far as I’m concerned, this abnormal behaviour is not present when it comes to 32 bit GNU/Linux boxes.
Analysing what is happening behind the scenes
When the “Open” file-menu option is clicked, the entire Wiris Desktop window freezes. The ps command shows us all processes involved with java which, in turn, is obviously associated with our Wiris Desktop Software, because of the fact that it is one hundred per cent pure Java code. The only new process appearing all of a sudden when we clicked on that “file-menu” option involving opening a file, is this one:
whoever 3512 0.2 0.2 13940 4196 pts/7 S 16:43 0:00 /home/whoever/docs/uoc/algebra/soft/WirisDesktop/java/linux/java/lib/i386/gtkhelper gtk-cancel 4 ltr gtk-dialog-error 6 ltr gtk-dialog-info 6 ltr gtk-dialog-question 6 ltr gtk-dialog-warning 6 ltr gtk-no 4 ltr gtk-ok 4 ltr gtk-yes 4 ltr
This software is not open source. We don’t have its sources, so we have to deal with the binary image loaded into memory directly. We begin with the strace command so as to figure out what could be happening with this process, in charge of hanging our Wiris Desktop completely:
15 [ Process PID=3512 runs in 32 bit mode. ]
16 select(3, , , NULL, NULL
It seems perfectly clear; this process is hanged up, in theory waiting for having more data to be read, according to the select system call, on two file descriptors. Taking a quick look at its FDT thanks to the lsof utility, it is quite obvious what files this process is opening in read mode, so that we can be completely sure about which ones we must take care of:
26 gtkhelper 3512 whoever 11r FIFO 0,6 3771446 pipe
27 gtkhelper 3512 whoever 13r FIFO 0,6 3771447 pipe
Well, two pipes. At that very moment, I didn’t know exactly why there was no data available to be read on those pipes. And, as a matter of fact, it was not important at all. The real point was to determine what could happen in case I simulated a broken pipe. Thus, I sent a SIGPIPE to the very process:
# kill -s SIGPIPE 3512
33 [ Process PID=3512 runs in 32 bit mode. ]
34 select(3, , , NULL, NULL) = ? ERESTARTNOHAND (To be restarted)
35 — SIGPIPE (Broken pipe) @ 0 (0) —
36 Process 3512 detached
Immediately after sending that SIGPIPE signal to the gtkhelper process, the gtk open common dialogue appeared. All seemed perfectly normal using Wiris Desktop application then: I could print, save, open, whatever action involved GTK common dialogues and routines to be shown or executed.
Thus, what did I need gtkhelper for?
Fixing the problem
In order to get rid of gtkhelper, I needed to find out where it was called. Don’t forget this is a proprietary piece of code, compiled and written entirely in Java. Once again, using a trivial command like grep revealed me what I was looking for:
grep -R “gtk-dialog-error” *
Coincidència en el fitxer binari java/linux/java/lib/i386/client/classes.jsa
Coincidència en el fitxer binari java/linux/java/lib/rt.jar
Clearly, the best candidate would be java/linux/java/lib/rt.jar .
I couldn’t simply delete gtkhelper, because then Wiris Desktop would fail irremediably. I couldn’t fake gtkhelper by, say, writing down a wrapper so as to impersonate it, because of those pipes I didn’t know how they worked or what they were needed for.
Thus, all I could do was to patch the binary java classes directly, looking for “gtkhelper” string and replacing it with, well, nothingness. Just the void. So as to speak. In theory, because this is a java call to “exec()”, with no binary to be executed, nothing will be executed at all.
Using hexedit, I patched java/linux/java/lib/rt.jar. This way, the string “gtkhelper”, which is shown next:
01FB87E0 67 74 6B 68 65 6C 70 65 72 01 00 0D 69 63 6F 6E 4E 61 6D 65 52 65 67 65 78 01 00 19 6A 61 76 61 2F 61 77 74 2F 63 6F 6C 6F 72 2F 43 gtkhelper…iconNameRegex…java/awt/color/C
was replaced with dots “.” like this:
01FB87E0 2E 2E 2E 2E 2E 2E 2E 2E 2E 01 00 0D 69 63 6F 6E 4E 61 6D 65 52 65 67 65 78 01 00 19 6A 61 76 61 2F 61 77 74 2F 63 6F 6C 6F 72 2F 43 …………iconNameRegex…java/awt/color/C
And it worked perfectly well!
The patch and a demonstrative video at hand!
In order to patch Wiris Desktop rt.jar binary file, you need to install on your GNU/Linux box bsdiff and bspatch utilities. Obviously, we cannot use diff and patch in the usual way: that is binary data!
So, first of all get the patch file wiris-patched-gtkhelper-bsdiff.patch. Then, you need to run bspatch this way:
mv java/linux/java/lib/rt.jar java/linux/java/lib/rt.jar.old
bspatch java/linux/java/lib/rt.jar.old java/linux/java/lib/rt.jar wiris-patched-gtkhelper-bsdiff.patch
At the same time, there’s a Demonstrative Video you can watch so as to witness how Wiris Desktop now is capable of dealing with those awful GTK common dialogues!.