Latest Tweets

Wiris software hangs up whenever opening a GTK common dialog on GNU/Linux 64 bits platforms

The issue

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, [2], [], NULL, NULL
17 …

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, [2], [], 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:

cd /path/to/WirisDesktop

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!.