mailing-list for TeXmacs Users

Text archives Help


Re: [TeXmacs] maple interface


Chronological Thread 
  • From: Enrique Perez-Terron <address@hidden>
  • To: address@hidden
  • Subject: Re: [TeXmacs] maple interface
  • Date: Fri, 24 Oct 2008 10:21:39 +0200

On Fri, 2008-10-24 at 02:18 +0200, Joris van der Hoeven wrote:
> Dear Andrea,
>
> On Thu, Oct 23, 2008 at 02:51:04AM +0200, Andrea Gamba wrote:
> > I am using texmacs 1.07 and the maple interface doesn't work, it just
> > freezes
> > the program. Things were working instead with 1.06.4
> >
> > I had this problem already many times and I tried to solve it along
> > previous
> > lines:
> > https://bugs.launchpad.net/ubuntu/+source/texmacs/+bug/73393
> >
> > but it doesn't work, this time the program tm_maple_9.c is in its place.
> >
> > In my .TeXmacs/bin/ I have my old tm_maple_9 tm_maple_9.sh which
> > apparently
> > don't work. If I delete them, new ones are not produced.
> >
> > A persistent problem with Ubuntu has been their use of dash instead of
> > bash,
> > but this is not the case here:
> >
> > $ sudo dpkg-reconfigure dash
> > and choose <No> to set /bin/sh -> bash
> >
> > does not solve the problem.
> >
> > Can somebody help? use of external programs like maple is one of the
> > strong
> > points of texmacs, but it is always so difficult to make it work... How
> > could I
> > debug this problem?
>
> This is a tricky point, because I do not have Maple myself.
> I probably will have to look at the problem myself in order to fix it,
> unless you are a hacker and manage to track down the problem...


Andrea, this looks like a case for strace. You can use strace to find
out what the programs are doing when they appear to hang. You can also
see what files they try to open, and where. If you have a config file in
the wrong directory, or if the config file does not have read
permission, all such things show in strace.

With suitable command line options to strace, it is even possible to see
byte for byte what data programs are exchanging through the pipes. Most
of the time, such errors show up very early in the streams, and most
programs exchange ascii data.

Install strace if you don't have already. Run texmacs as usual. Just
before you intend to activate the maple interface, open a terminal
window, determine the process number of the texmacs process (ps -ef |
grep texmacs | grep -v grep; the first number in the output; say it's
12345), then do

strace -p 12345 -f -o /tmp/tm.strace

Leave the terminal window running, go back to texmacs, activate maple,
return to the terminal window and hit ctrl-c to interrupt strace.

Then look through the file /tmp/tm.strace. It is voluminous and hard to
understand unless you habitually hack C code, yet you should be able to
discern some things:

Use an editor that offers searching. Search for "clone" or "fork". You
will find lines like "nnnn clone( ... ) = xyz" where xyz is a new
process number. Note on a piece of paper, "nnnn -> xyz". Then search
for

"zyz execv"

(there are TWO spaces). There may be zero, one, or more hits. A hit
looks like

5994 execve("/usr/bin/spamc", ["spamc", "-c", "-t", "60", "-U",
"/home/enrique/.evolution/cache/t"...], [/* 22 vars */]) = 0

Add to your notes that process 5994 runs the program "/usr/bin/spamc",
and the command line is shown in brackets. Long strings are truncated,
but you can add an option "-s 1024" to the strace command line. The
second brackets are the environment variables, but contents are not
shown unless you add another options to the "strace" command line.

Once you know all process numbers and programs that were started from
texmacs, try to figure out what each is doing. Each process starts
attaching to their shared libraries, and that is a noisy procedure that
fills pages in the strace file.

If you see a process opening a number of files, each time receiving an
error like this:

29927 open("DB_CONFIG", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or
directory)

that is mostly normal. E.g., programs typically look for config files a
number of places:

/etc/myap.config
/usr/share/myapp/myapp.config
/var/share/myapp/myapp.config
/home/goodguy/.myapp/myapp.config

yet this list may be exactly what you are looking for.

Often when a program A wants to start a program B, it starts first
/bin/bash with command line -c B. In that case, the same process number
has two "execv" lines, and only the second is of interest. If the path
to B was not given, bash may try to exec /bin/B, /usr/bin/B,
/usr/local/bin/B, etc. It is no faster to "look" in the directories
than to just issue the exec calls.

Look for "= 0" at the end, that is the successful one.

For each process, look for the last line with that process number, and
work backwards. That helps skip the initial shared library noise.

You will see e.g. "read(7,"... and "write(12,... and you then need to
find out what files are 7 and 12 (in these examples). Look backwards for
e.g. "open(...) = 7". Notice that a program can do

open("file_1", ... ) = 7
...
close(7) = 0
open("file_2", ... ) = 7

Another request that opens files is "socket". It is used for network
connections, but also for e.g. connecting to the X server. With sockets,
there is no open, just e.g. socket(...) = 7. With sockets, read and
write happen using the same file number. "close" works with all types of
files.

Similarly, for pipes, there is no "open". With pipes, reading and
writing use different numbers. The pattern is as follows.

Program A wants to run program B, and communicate with it through
pipes. Program B does not know that. Program B starts without knowing
how it was started. It will use the numbers 0, 1 and 2 respectively, to
read or write stdin, stdout, and stderr. It does not know what kind of
files these actually are.

Program A has its own files 0,1,2, but those are other files.

Program A runs in process nnn. It does

nnn pipe([7,8]) = 0
nnn pipe([9,10]) = 0

This creates two pipes. This assigns the numbers 7 and 8 to the first
pipe, and numbers 9 and 10 to the second pipe. 7 and 9 are for reading
the pipes, 8 and 10 for writing. The "= 0" part means the pipes were
created OK, no error.

nnn clone(...) = xyz

A new process that eventually will run program B, but first some
housekeeping. At this point, the new process still runs code that is
part of program A. The new process has access to the same files as the
old process.

xyz dup2(7, 0) = 0
xyz dup2(10, 1) = 0

Associate the numbers 0 and 1 with the pipes, forgetting what files 0
and 1 were before. That is, now 0 and 7 are the same file. This only
happens in process xyz. In process nnn, 0 and 1 are still the standard
input and output respectively of A.

xyz close(7) = 0
xyz close(8) = 0
xyz close(9) = 0
xyz close(10) = 0

Disassociate the numbers 7..10 from any files. The pipes are still open,
accessible in process xyz as 0 and 1. In process nnn, the pipes are
still accessible as 7, 8, 9, and 10. Notice that process xyz now can
only read, not write, the first pipe, since it has no longer any number
associated with the write end of that pipe. With the second pipe, it
can only write, not read, since 1 was associated with the write end
(10).

xyz execv("/usr/bin/B", ...) = 0

Now B is running in process xyz, with stdin and stdout connected to the
pipes. As shown here, program B would still have its stderr connected
to the same file as program A's stderr. If A want to capture B's stderr,
a third pipe is needed, or it could do "dup2(10, 2)". In that case, when
A reads the pipe, it cannot know if the data entered the pipe by B
writing to stdout or to stderr.

Program A in process nnn will now write to B like this

nnn write(8, "Hello, how are the cycles?\n", 27) = 27

and read responses like this

nnn read(9, "Fine.\n", 1024) = 6

1024 is the size of the buffer that receives the data read. 6 is the
number of bytes actually received.

This should go a long way in the cases where the underlying problem is
trivial (once discovered). If instead you find the maple process is
issuing a call like "futex(... unfinished" then there is some
programming error, and mapple is waiting for some internal thread which
is again probably waiting for something that never happens.

If a program is hanging like this

nnn read(3, <unfinished ...>

then you have to find out what process has the writing end of the same
pipe. Why is that program not writing?

In some cases you might perhaps see texmacs doing "select" or "poll"
again and again. That means texmacs actually wants to read some pipe,
but it does not want to read unless in can know that there are some data
in it. If there are no data, the operating system would make texmacs
hang until there are data available on that particular pipe. That would
mean texmacs could not respond to keyboard input in the mean time.

A call to select looks like

20011 select(8, [7], NULL, NULL, {300, 0} <unfinished ...>
...
20011 <... select resumed> ) = 1 (in [7], left {299, 994000})

Here process 20011 wanted to wait up to 300 seconds (and 0 microseconds)
or until file 7 becomes readable. "8" is just one more than the highest
file number involved in the request. The first "NULL" could have been
e.g. [3, 5], in which case the program would be requesting to be
notified also if files 3 or 5 become writable (as opposed to readable)
without danger of hanging.

The result (= 1) is the number of serviceable files. "in [7]" says which
files are serviceable in what way. "left" is the time left of the
specified max wait.

Poll is similar, but more verbose. I don't have any example handy.

-Enrique




Archive powered by MHonArc 2.6.19.

Top of page