[LLVMdev] llvm-ranlib: Bus Error in regressions + fix

Evan Jones ejones at uwaterloo.ca
Tue Nov 22 12:46:28 PST 2005


I ran the LLVM regression tests today (via make check) and noticed that 
llvm-ranlib crashes with a Bus Error on my test system (a fairly old 
RedHat 9 system), using the latest CVS version. I did some digging and 
I think I know what the problem is, and I have attached a quick and 
dirty patch that fixes the problem for me, but I need a suggestion 
about how it should be integrated properly. Here are the details:

To reproduce the crash, run llvm-ranlib on the "GNU.a" file in the 
llvm/test/Regression/Archive directory (make a copy first: it corrupts 
it). It then crashes with a Bus Error.

The stack trace is:

#0  0x4207c1aa in memcpy () from /lib/tls/libc.so.6
#1  0x400d55e8 in std::basic_streambuf<char, std::char_traits<char> 
 >::xsputn(char const*, int) () from /usr/lib/libstdc++.so.5
#2  0x4009c818 in std::basic_filebuf<char, std::char_traits<char> 
 >::xsputn(char const*, int) () from /usr/lib/libstdc++.so.5
#3  0x400cbed1 in std::ostream::write(char const*, int) ()
    from /usr/lib/libstdc++.so.5
#4  0x0829c9d0 in llvm::Archive::writeMember(llvm::ArchiveMember 
const&, std::basic_ofstream<char, std::char_traits<char> >&, bool, 
bool, bool) (
     this=0x8356088, member=@0x8356180, ARFile=@0xbfffd630,
     CreateSymbolTable=false, TruncateNames=false, ShouldCompress=false)
     at ArchiveWriter.cpp:294
#5  0x0829d297 in llvm::Archive::writeToDisk(bool, bool, bool) (
     this=0x8356088, CreateSymbolTable=true, TruncateNames=false,
     Compress=false) at ArchiveWriter.cpp:439
#6  0x081a5618 in main (argc=2, argv=0xbfffd9b4) at llvm-ranlib.cpp:76
#7  0x42015574 in __libc_start_main () from /lib/tls/libc.so.6


At frame #4 (Archive::writeMember) looks like this:

>   // Write the (possibly compressed) member's content to the file.
>   ARFile.write(data,fSize);

If I examine the backtrace, fSize equals 46, and "data" points to 46 
null bytes. However, the "data" pointer is invalid, since if I inspect 
it *before* the crash, the crash does not occur.

frame #5 (Archive::writeToDisk) looks like this:

>       // If there is a foreign symbol table, put it into the file now. 
> Most
>       // ar(1) implementations require the symbol table to be first 
> but llvm-ar
>       // can deal with it being after a foreign symbol table. This 
> ensures
>       // compatibility with other ar(1) implementations as well as 
> allowing the
>       // archive to store both native .o and LLVM .bc files, both 
> indexed.
>       if (foreignST) {
>         writeMember(*foreignST, FinalFile, false, false, false);
>       }

So I tracked back the foreignST pointer, and when it is set the "data" 
pointer is *not* 46 null bytes. It is valid data mmap-ed from the 
archive file. But when it gets to the call to writeMember, that data 
pointer is no longer valid. Running "strace" on llvm-ranlib solved the 
mystery. Here are the relevant calls:

open("temp.GNU.a", O_RDONLY)            = 13
fstat64(13, {st_mode=S_IFREG|0600, st_size=4210, ...}) = 0
mmap2(NULL, 8192, PROT_READ, MAP_PRIVATE, 13, 0) = 0x40017000

** The source file is mapped, and a lot of stuff happens **

open("temp.GNU.a", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 15
fstat64(15, {st_mode=S_IFREG|0600, st_size=0, ...}) = 0

** Here the source file is TRUNCATED. Essentially, this invalidates the 
data pointer. Two lines follow in the trace: **

_llseek(15, 0, [0], SEEK_CUR)           = 0
--- SIGBUS (Bus error) @ 0 (0) ---



So the fix is pretty simple: before opening the file again, unlink it. 
This has the effect of creating a *new* file, instead of overwriting 
the old data. I've attached my quick-and-dirty patch that will only 
work on Unix. I'm not sure how this should be solved correctly. The 
other strange part is why hasn't anyone else seen this problem? I would 
think that this would occur pretty reliably on all systems. Any ideas?

Evan Jones

-------------- next part --------------
A non-text attachment was scrubbed...
Name: archive.patch
Type: application/octet-stream
Size: 1071 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20051122/e5d04595/attachment.obj>
-------------- next part --------------

--
Evan Jones
http://evanjones.ca/


More information about the llvm-dev mailing list