Illegal instruction problem

Hi there.

I've just committed new versions of some of my packages in SourceForge:

v3c-2.2.0-01
treedb-1.2.0-02
meta-treedb-1.3.0-03

I've got a problem with the release build (which uses -03 optimisation) of treedb.

The "fuse" tests fail with an illegal instruction fault.

This is with llvm/clang 2.9.svn-r145196.

They work fine with the debug build (-O0 optimisation).

Debug and release builds test fine with gcc.

I made a lot of changes to get this to even compile with clang, as it's more picky,
and this process helped me clean up warnings and even find the odd bug.

I know you'd prefer if I provided stand-alone code to demonstrate the problem, but
building and installing v3c (which treedb needs) with treedb in a "sandbox" takes
about 5 minutes on a modern machine, and that includes the time to download them
from SourceForge.

The problem is reproducible.
"$" denotes the command prompt for typing commands

STEPS:

1. install fuse-dev
    The fuse tests need fuse-dev installed or they will be skipped.
2. download and unpack v3c and treedb from SourceForge.
3. type

    $ v3c_default_build_mode=release bash v3c/v3c-tryout treedb-1.2.0-02 tryout

    from the directory that contains the v3c and treedb directories.

4. When it's done type

    $ tryout/enter-env

    which will take you into a shell with the environment set up to play around.
    You'll notice that the command prompt changes to remind you you're in a sandbox.

5. Then type

    $ cd treedb-1.2.0-02; make release check

and after a minute or two you'll get to the error.

Regards,
Philip Ashmore

Sorry - you need to git-clone the projects:

git clone git://v3c.git.sourceforge.net/gitroot/v3c/v3c
git clone git://treedb.git.sourceforge.net/gitroot/treedb/treedb

Philip

Hi Philip,

The most likely cause of this is that you're using undefined behavior (e.g. an uninitialized variable, array out of bounds, etc) in your code that the optimizer is detecting. Please see:
http://blog.llvm.org/2011/05/what-every-c-programmer-should-know.html

for more information.

-Chris

Sorry Chris for sending this to you personally before - I meant to send it to the list.

Hi there.

I've just committed new versions of some of my packages in SourceForge:

v3c-2.2.0-01
treedb-1.2.0-02
meta-treedb-1.3.0-03

I've got a problem with the release build (which uses -03 optimisation)
of treedb.

The "fuse" tests fail with an illegal instruction fault.

Hi Philip,

The most likely cause of this is that you're using undefined behavior (e.g. an uninitialized variable, array out of bounds, etc) in your code that the optimizer is detecting. Please see:
http://blog.llvm.org/2011/05/what-every-c-programmer-should-know.html

for more information.

-Chris

OK. Well, I did find a problem in v3c with valgrind - I'll push a new release after writing
this. It has nothing to do with this problem though - fcntl(F_GETLK) doesn't set l_pid if
there's no lock.

Unfortunately valgrind can't go through setuid/setgid programs, which is what the fuse library does
- it runs fusermount, so I couldn't valgrind the whole test.

So I tried another way.

1. In treedb
    $ cd build/v3c/3-comet
    $ mkdir fuse
2. Run the daemon in foreground mode on the "fuse" directory and add debug output 'cause we can:
    $ TREEDB_FUSE_TMPDIR=$(readlink -f .) LD_LIBRARY_PATH=.libs:../.libs ./lt-treedb-malloc-daemon-d -d fuse
3. Debug malloc-test-d
    $ kdbg .libs/malloc-test-d
4. Set the command line argument to reserve a 50M heap : kdbg->Execution->Arguments 50M
5. Set environment variables in kdbg->Execution->Arguments->Environment
    LD_LIBRARY_PATH=.libs:../.libs
    V3C_TREEDB_MALLOC_FUSE_DIR=fuse
6. Run the program kdbg->Execution->Run or F5

It hit an "ud2" instruction - kdbg reports SIGILL - Illegal instruction, at treedb's v3c/avl-impl.h line
227, in treedb_malloc_AvlAllocator_used_insert_node_after_64 - the function name is a macro expansion
and I've expanded it here as that's what's in the stack trace.

Unfortunately v3c/avl-impl.h line 227 isn't in the above function - it's inside
AVL_TREE_NS(unpack_node)(...) - I won't expand the macro-mangled name here.

So either kdbg-2.5.0-1 is wrong (not impossible) or the debug information or llvm/clang is wrong.

Is it asking too much to take a look?

Regards,
Philip Ashmore

Sorry Chris for sending this to you personally before - I meant to send
it to the list.

Hi there.

I've just committed new versions of some of my packages in SourceForge:

v3c-2.2.0-01
treedb-1.2.0-02
meta-treedb-1.3.0-03

I've got a problem with the release build (which uses -03 optimisation)
of treedb.

The "fuse" tests fail with an illegal instruction fault.

Hi Philip,

The most likely cause of this is that you're using undefined behavior
(e.g. an uninitialized variable, array out of bounds, etc) in your
code that the optimizer is detecting. Please see:
http://blog.llvm.org/2011/05/what-every-c-programmer-should-know.html

for more information.

-Chris

OK. Well, I did find a problem in v3c with valgrind - I'll push a new
release after writing
this. It has nothing to do with this problem though - fcntl(F_GETLK)
doesn't set l_pid if
there's no lock.

Unfortunately valgrind can't go through setuid/setgid programs, which is
what the fuse library does
- it runs fusermount, so I couldn't valgrind the whole test.

So I tried another way.

1. In treedb
$ cd build/v3c/3-comet
$ mkdir fuse
2. Run the daemon in foreground mode on the "fuse" directory and add
debug output 'cause we can:
$ TREEDB_FUSE_TMPDIR=$(readlink -f .) LD_LIBRARY_PATH=.libs:../.libs
./lt-treedb-malloc-daemon-d -d fuse
3. Debug malloc-test-d
$ kdbg .libs/malloc-test-d
4. Set the command line argument to reserve a 50M heap :
kdbg->Execution->Arguments 50M
5. Set environment variables in kdbg->Execution->Arguments->Environment
LD_LIBRARY_PATH=.libs:../.libs
V3C_TREEDB_MALLOC_FUSE_DIR=fuse
6. Run the program kdbg->Execution->Run or F5

It hit an "ud2" instruction - kdbg reports SIGILL - Illegal instruction,

LLVM generates a ud2 in some cases where it can locally prove code is
unreachable because it has undefined behavior. You're most likely
hitting that.

at treedb's v3c/avl-impl.h line
227, in treedb_malloc_AvlAllocator_used_insert_node_after_64 - the
function name is a macro expansion
and I've expanded it here as that's what's in the stack trace.

Unfortunately v3c/avl-impl.h line 227 isn't in the above function - it's
inside
AVL_TREE_NS(unpack_node)(...) - I won't expand the macro-mangled name here.

So either kdbg-2.5.0-1 is wrong (not impossible) or the debug
information or llvm/clang is wrong.

Are you sure it isn't due to inlining?

-Eli

insert_node_after() calls unpack_node(), not the other way around, so yes, I'm sure.

Please give it a try.

Philip