strspn [was: 0.11.1 debian failures]

Matthias Andree matthias.andree at gmx.de
Tue Mar 11 15:11:27 CET 2003


Clint, I'm using your name below for the questions I have, so if you're
short on time reading this mail, cut short by searching this mail for
your name below.


On Tue, 11 Mar 2003, David Relson wrote:

> >#0  0x401cf302 in strspn () from /lib/libc.so.6
> >No symbol table info available.
> >#1  0x00405882 in read_config_file (fname=0x7ffff825 "0.415", 
> >tilde_expand=false, warn_on_error=true) at configfile.c:229
> >        delim = " \t="
> >        len = 4
> >        buff = "robx\00.415", '\0' <repeats 189 times>
> >        error = false
> >        lineno = 1
> >        fp = (FILE *) 0x421148
> >        filename = 0x420d10 "./checks.12714.20030311T063641/test.cf"
> >        val = 0x7ffff825 "0.415"
> >>>> Done.
> 
> Looking at the parameters and local variables I see several things that are 
> peculiar.
> 
> 1 - Both fname and val point at the same memory address.  This is _wrong_.
> 2 - We know we're at the first line of the config file because of lineno = 
> 1.  As the first line of the file is "robx=0.415", this is confirmed by the 
> value in buff, i.e. "robx\00.415".  The presence of the '\0' is correct at 
> the time strspn() is called.  However the value of len should be 10, not 4.

OK, let me present an ultra-short crash course about optimizers and
processors to make sure you don't waste your time looking at the wrong
figures:

1- Processors have a very limited amount of ultra-fast memory,
   accessible with no or 1 cycle usually, called registers. You probably
   knew that already. If not: these are often (m68k) orders of magnitude
   faster than even L2 caches.

2- Optimizers are anxious to hold variables in registers that need fast
   access, particularly so in loops, but even outside, they'll try to
   hold the important variables in registers. To achieve the optimimum
   register allocation, optimizers analyse the lifetime of a variable
   and if they see the variable's lifetime ends and another one is used
   repeatedly, they may well let go of the former variable and load the
   next one.

3- The debugger knows variable-register assignments, but the register
   allocation may well change over the program flow (line number if you
   wish), so variables that are no longer used and needed at the time
   crashes will have bogus contents in the backtrace because the
   register was reused. Aliased unused variables are normal for
   backtraces of optimized code.

Having said that, the lifetime of the "len" auto variable ends at line
#220, it's last used there, and must reckon the optimizer overwriting
the register with something else, maybe even to hold a temporary result,
an internally-used temporary variable as artifact of code generation,
that we don't get to see unless we look at the disassembly. Likewise,
fname can be invalidated by the optimizer after line #189
"filename = xstrdup(fname);", so don't worry about their contents being
aliases. I'm pretty sure that we'd get the same backtrace from m68k
(which passes our tests); the intial allocation (at least for register
passing, and what I'm used to with SAS/C on m68k/AmigaOS) is
A0: fname, D0: tilde_expand, D1: warn_on_errors, and from line #190
onwards, A0 and D0 are freed and will be reused. Say, fp into A0 and len
into D0. Or something, depending on whether the register scheduling does
round-robin or first-match.

So this basically means: don't bang your head against the wall trying to
figure what the len == 4 or val == fname means unless you compiled with
-O0. We should be able to trust lineno (used below), buff and val to
some extent.

Clint,
can you have buildd recompile the whole lot on S390 with:

1. CFLAGS="-Wall -g -O1" ./configure --prefix=/usr \
    --mandir=\${prefix}/share/man --sysconfdir=/etc

2. CFLAGS="-Wall -g -O0" ./configure --prefix=/usr \
    --mandir=\${prefix}/share/man --sysconfdir=/etc

and send us the resulting URLs?

I want to avoid wasting manpower when there's an optimizer bug, and I
also want to see more useful data in the backtrace (the -O0 will be most
efficient for debugging, but -O1 will be useful for production if -O2
fails for the meanwhile i. e. until the optimizer bug, if there is any,
has been fixed).

> When I step through it on my PIII, all looks fine.  So all is not quite 
> right (and the S390 is likely correct to complain, via SegFault).  More 
> research to follow ...

The PIII has few registers, virtually any other processor type has more
of them.

-- 
Matthias Andree




More information about the bogofilter-dev mailing list