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

Reid Spencer reid at x10sys.com
Tue Nov 22 20:59:38 PST 2005


Evan Jones wrote:

> On Nov 22, 2005, at 19:10, Reid Spencer wrote:
> 
>> 1. What is the path name associated with TmpArchive? If its the same 
>> as the path name associated with archPath then that's a bug, probably 
>> introduced when Path::makeUnique is called from 
>> Path::createTemporaryFileOnDisk which is called from line 377 of 
>> ArchiveWriter.cpp.
> 
> 
> This does not appear to be the problem. I excluded the lines from the 
> strace that created this temporary file. After line 377:
> 
> (gdb) p TmpArchive
> $2 = {path = {static npos = 4294967295,
>     _M_dataplus = {<allocator<char>> = {<No data fields>},
>       _M_p = 0x835407c "temp.GNU.a-PozKFJ"}, static _S_empty_rep_storage 

That looks like mkstemp working correctly.

> = {0,
>       0, 4, 0}}}
> (gdb) p archPath
> $3 = {path = {static npos = 4294967295,
>     _M_dataplus = {<allocator<char>> = {<No data fields>},
>       _M_p = 0x83545f4 "temp.GNU.a5\b"}, static _S_empty_rep_storage = 

What's with the "5\b" at the end? Looks like garbage to me. Not sure what's up 
with that.
> {0, 0,
>       4, 0}}}
> 
> So these two variables are pointing to different files, and the creation 
> of TmpArchive works just fine.  The strace including the parts that 
> reference the temporary file is appended to the end of the email. 

Okay, the previous strace looked like they were both opening "temp.GNU.a"; 
perhaps the names were truncated in the strace.  Anyway, you're right, this 
isn't the problem if the file names are different.

> The 
> very last open to the "archPath" file is at line 429, where it truncates 
> it even though the foreignST pointer refers to data mmaped in that file. 

Yes, the foreignST points to a non-LLVM symbol table which must be retained for 
compatibility with other AR implementations. Unfortunately, it is being held 
from a file that is about to be mmap'd.

> Is this data supposed to be copied out of the original file, 

That's one solution but it defeats the purpose/efficiency of the mmap.

or is
> another temporary supposed to be created and then the original could be 
> replaced using a file move operation instead?

Another temporary file would be even slower than copying the memory in memory.
> 
> I'll try this on my Debian unstable system tomorrow. If ranlib works 
> there, maybe I can track down the difference.

Sounds like a plan. Its a bit difficult to debug this over email. If you get 
stuck, let me know and I'll gen up a debug environment to take a look at it. 
Chances are, however, that I won't be able to replicate this problem on FC3 
since it passes the nightly test here.

> 
  > open("temp.GNU.a", O_RDONLY)            = 3

Original file being opened (read-only, because we're not supposed to modify it)

> fstat64(3, {st_mode=S_IFREG|0600, st_size=4210, ...}) = 0
> mmap2(NULL, 8192, PROT_READ, MAP_PRIVATE, 3, 0) = 0x40017000
> gettimeofday({1132714484, 283020}, NULL) = 0
> getpid()                                = 28656
> open("temp.GNU.a-O1Q6E8", O_RDWR|O_CREAT|O_EXCL, 0600) = 4
The temporary file that will contain the symbol table
> close(4)                                = 0
> open("temp.GNU.a-O1Q6E8", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 4
> close(4)                                = 0
Not sure why this is opened twice .. probably an llvm::sys::Path issue.
> 
> *** SIGNAL HANDLING REMOVED ***
> 
> open("temp.GNU.a-O1Q6E8", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 4
Open yet again the temnporary file into which we'll build the symtab.
> brk(0)                                  = 0x8357000
> brk(0x8359000)                          = 0x8359000
> fstat64(4, {st_mode=S_IFREG|0600, st_size=0, ...}) = 0
> mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 
> 0) = 0x40019000
This mmap is just allocating memory
> _llseek(4, 0, [0], SEEK_CUR)            = 0
> _llseek(4, 0, [0], SEEK_SET)            = 0
> _llseek(4, 0, [0], SEEK_SET)            = 0
> _llseek(4, 0, [0], SEEK_SET)            = 0
> _llseek(4, 0, [0], SEEK_SET)            = 0
> brk(0)                                  = 0x8359000
> brk(0x8369000)                          = 0x8369000
> brk(0)                                  = 0x8369000
> brk(0x836a000)                          = 0x836a000
> mmap2(NULL, 2002944, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, 
> -1, 0) = 0x4013b000
more memory allocations
> munmap(0x4013b000, 2002944)             = 0
> _llseek(4, 0, [0], SEEK_SET)            = 0
> _llseek(4, 0, [0], SEEK_SET)            = 0
> _llseek(4, 0, [0], SEEK_SET)            = 0
> write(4, "!<arch>\nevenlen/        11008330"..., 4040) = 4040
> close(4)                                = 0
> munmap(0x40019000, 4096)                = 0
> access("temp.GNU.a-O1Q6E8", F_OK)       = 0
> open("temp.GNU.a-O1Q6E8", O_RDONLY)     = 4
> fstat64(4, {st_mode=S_IFREG|0600, st_size=4040, ...}) = 0
> mmap2(NULL, 4096, PROT_READ, MAP_PRIVATE, 4, 0) = 0x40019000
map in the contents of the file we wrote.
> open("temp.GNU.a", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 5
wipe out the original file
> fstat64(5, {st_mode=S_IFREG|0600, st_size=0, ...}) = 0
> mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 
> 0) = 0x4001a000
allocate memory
> _llseek(5, 0, [0], SEEK_CUR)            = 0
> --- SIGBUS (Bus error) @ 0 (0) ---

 From this strace it looks to me like the only solution is to copy the data 
pointed to by foreignST into malloc'd space. Its just a symbol table so it 
shouldn't be too huge.  The problem, as you've noted, is that the foreignST 
pointer is pointing into file handle 3. When file handle 5 is opened, the 
O_TRUNC parameter causes the memory pointed to by foreignST to be invalidated 
(unmapped). When we try to read this data in order to write it back to 
temp.GNU.a, it is getting the bus error trying to access the foreignST data.

There's two solutions:
(1) copy the data pointed to by foreignST
(2) build the new file with the symbol table in a 3rd temporary file which is 
later renamed as the original (temp.GNU.a in this case).


Reid.




More information about the llvm-dev mailing list