From 9e6c86a714fc3eda82a60c05241ecb6d81a1ecdc Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Thu, 5 Jun 2014 10:24:34 +0200 Subject: [PATCH 1/2] Add workaround for archive reading bug in LLDB. LLDB contains a bug that makes it crash if an archive it reads contains a file the name of which is exactly 16 bytes long. This bug recently has made it impossible to debug Rust applications with LLDB because some standard libraries triggered it indirectly: For rlibs, rustc includes the LLVM bytecode in the archive, giving it the extension ".bc.deflate". For liballoc (for example) this results in the 16 character filename "alloc.bc.deflate", which is bad. This commit replaces the ".bc.deflate" suffix with ".bytecode.deflate" which itself is already longer than 16 bytes, thus making sure that the bug won't be run into anymore. The bug could still be run into with 14 character filenames because then the .o files will trigger it. However, this is much more rare and working around it would introduce more complexity than necessary at the moment. It can always be done later on, if the need arises. Fixes #14356. --- src/librustc/back/archive.rs | 2 +- src/librustc/back/link.rs | 6 +++++- src/librustc/back/lto.rs | 4 ++-- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/librustc/back/archive.rs b/src/librustc/back/archive.rs index 0b6540640b4cf..edb0a538a03dc 100644 --- a/src/librustc/back/archive.rs +++ b/src/librustc/back/archive.rs @@ -109,7 +109,7 @@ impl<'a> Archive<'a> { pub fn add_rlib(&mut self, rlib: &Path, name: &str, lto: bool) -> io::IoResult<()> { let object = format!("{}.o", name); - let bytecode = format!("{}.bc.deflate", name); + let bytecode = format!("{}.bytecode.deflate", name); let mut ignore = vec!(bytecode.as_slice(), METADATA_FILENAME); if lto { ignore.push(object.as_slice()); diff --git a/src/librustc/back/link.rs b/src/librustc/back/link.rs index 546182aac34e2..b432034b81b56 100644 --- a/src/librustc/back/link.rs +++ b/src/librustc/back/link.rs @@ -958,8 +958,12 @@ fn link_rlib<'a>(sess: &'a Session, // For LTO purposes, the bytecode of this library is also inserted // into the archive. + // Note that we make sure that the bytecode filename in the archive is always at least + // 16 bytes long by adding a 16 byte extension to it. This is to work around a bug in + // LLDB that would cause it to crash if the name of a file in an archive was exactly + // 16 bytes. let bc = obj_filename.with_extension("bc"); - let bc_deflated = obj_filename.with_extension("bc.deflate"); + let bc_deflated = obj_filename.with_extension("bytecode.deflate"); match fs::File::open(&bc).read_to_end().and_then(|data| { fs::File::create(&bc_deflated) .write(match flate::deflate_bytes(data.as_slice()) { diff --git a/src/librustc/back/lto.rs b/src/librustc/back/lto.rs index 09dfc91896795..7449622366fc2 100644 --- a/src/librustc/back/lto.rs +++ b/src/librustc/back/lto.rs @@ -55,10 +55,10 @@ pub fn run(sess: &session::Session, llmod: ModuleRef, let archive = ArchiveRO::open(&path).expect("wanted an rlib"); debug!("reading {}", name); let bc = time(sess.time_passes(), - format!("read {}.bc.deflate", name).as_slice(), + format!("read {}.bytecode.deflate", name).as_slice(), (), |_| { - archive.read(format!("{}.bc.deflate", + archive.read(format!("{}.bytecode.deflate", name).as_slice()) }); let bc = bc.expect("missing compressed bytecode in archive!"); From 570911ffdcf6787451c0817b3a61211e3fe08070 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Thu, 5 Jun 2014 15:31:45 -0700 Subject: [PATCH 2/2] rustc: Avoid 16-byte filenames in rlibs In addition to avoiding 16-byte filenames with bytecode files, this commit also avoids 16-byte filenames with object files pulled in from native libraries. --- src/librustc/back/archive.rs | 9 +++++++++ src/librustc/back/link.rs | 9 +++++---- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/src/librustc/back/archive.rs b/src/librustc/back/archive.rs index edb0a538a03dc..4d921fb97dc50 100644 --- a/src/librustc/back/archive.rs +++ b/src/librustc/back/archive.rs @@ -166,6 +166,15 @@ impl<'a> Archive<'a> { if filename.contains(".SYMDEF") { continue } let filename = format!("r-{}-{}", name, filename); + // LLDB (as mentioned in back::link) crashes on filenames of exactly + // 16 bytes in length. If we're including an object file with + // exactly 16-bytes of characters, give it some prefix so that it's + // not 16 bytes. + let filename = if filename.len() == 16 { + format!("lldb-fix-{}", filename) + } else { + filename + }; let new_filename = file.with_filename(filename); try!(fs::rename(file, &new_filename)); inputs.push(new_filename); diff --git a/src/librustc/back/link.rs b/src/librustc/back/link.rs index b432034b81b56..14369c7bbcd23 100644 --- a/src/librustc/back/link.rs +++ b/src/librustc/back/link.rs @@ -958,10 +958,11 @@ fn link_rlib<'a>(sess: &'a Session, // For LTO purposes, the bytecode of this library is also inserted // into the archive. - // Note that we make sure that the bytecode filename in the archive is always at least - // 16 bytes long by adding a 16 byte extension to it. This is to work around a bug in - // LLDB that would cause it to crash if the name of a file in an archive was exactly - // 16 bytes. + // + // Note that we make sure that the bytecode filename in the archive + // is never exactly 16 bytes long by adding a 16 byte extension to + // it. This is to work around a bug in LLDB that would cause it to + // crash if the name of a file in an archive was exactly 16 bytes. let bc = obj_filename.with_extension("bc"); let bc_deflated = obj_filename.with_extension("bytecode.deflate"); match fs::File::open(&bc).read_to_end().and_then(|data| {