Skip to content

Commit eae01e5

Browse files
committed
Finally, the clear call works
1 parent 676bfee commit eae01e5

File tree

3 files changed

+54
-41
lines changed

3 files changed

+54
-41
lines changed

Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ addr2line = { version = "0.9.0", optional = true, default-features = false, feat
3434
findshlibs = { version = "0.5.0", optional = true }
3535
memmap = { version = "0.7.0", optional = true }
3636
goblin = { version = "0.0.23", optional = true, default-features = false, features = ['std'] }
37+
lazy_static = { version = "1.3", optional = true }
3738

3839
[target.'cfg(windows)'.dependencies]
3940
winapi = { version = "0.3.3", optional = true }
@@ -98,7 +99,7 @@ kernel32 = []
9899
libbacktrace = ["backtrace-sys"]
99100
dladdr = []
100101
coresymbolication = []
101-
gimli-symbolize = ["addr2line", "findshlibs", "memmap", "goblin"]
102+
gimli-symbolize = ["addr2line", "findshlibs", "memmap", "goblin", "lazy_static"]
102103

103104
#=======================================
104105
# Methods of serialization

src/symbolize/gimli.rs

Lines changed: 43 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -11,17 +11,18 @@ use crate::symbolize::ResolveWhat;
1111
use crate::types::BytesOrWideString;
1212
use crate::SymbolName;
1313
use addr2line::gimli;
14-
use core::cell::RefCell;
1514
use core::convert::TryFrom;
1615
use core::mem;
1716
use core::u32;
1817
use findshlibs::{self, Segment, SharedLibrary};
18+
use lazy_static::lazy_static;
1919
use libc::c_void;
2020
use memmap::Mmap;
2121
use std::env;
2222
use std::fs::File;
2323
use std::path::{Path, PathBuf};
2424
use std::prelude::v1::*;
25+
use std::sync::Mutex;
2526

2627
const MAPPINGS_CACHE_SIZE: usize = 4;
2728

@@ -329,57 +330,62 @@ impl Mapping {
329330
}
330331
}
331332

332-
// A very small, very simple LRU cache for debug info mappings.
333-
//
334-
// The hit rate should be very high, since the typical stack doesn't cross
335-
// between many shared libraries.
336-
//
337-
// The `addr2line::Context` structures are pretty expensive to create. Its
338-
// cost is expected to be amortized by subsequent `locate` queries, which
339-
// leverage the structures built when constructing `addr2line::Context`s to
340-
// get nice speedups. If we didn't have this cache, that amortization would
341-
// never happen, and symbolicating backtraces would be ssssllllooooowwww.
342-
static MAPPINGS_CACHE: RefCell<Vec<(PathBuf, Mapping)>>
343-
= RefCell::new(Vec::with_capacity(MAPPINGS_CACHE_SIZE));
333+
lazy_static! {
334+
// A very small, very simple LRU cache for debug info mappings.
335+
//
336+
// The hit rate should be very high, since the typical stack doesn't cross
337+
// between many shared libraries.
338+
//
339+
// The `addr2line::Context` structures are pretty expensive to create. Its
340+
// cost is expected to be amortized by subsequent `locate` queries, which
341+
// leverage the structures built when constructing `addr2line::Context`s to
342+
// get nice speedups. If we didn't have this cache, that amortization would
343+
// never happen, and symbolicating backtraces would be ssssllllooooowwww.
344+
// static MAPPINGS_CACHE: RefCell<Vec<(PathBuf, Mapping)>> = RefCell::new(Vec::with_capacity(MAPPINGS_CACHE_SIZE));
345+
static ref MAPPINGS_CACHE: Mutex<Vec<(PathBuf, Mapping)>> = Mutex::new(Vec::with_capacity(MAPPINGS_CACHE_SIZE));
346+
}
344347

345348
pub fn clear_symbol_cache() {
346-
MAPPINGS_CACHE.borrow_mut().clear()
349+
if let Ok(mut cache) = MAPPINGS_CACHE.lock() {
350+
cache.clear();
351+
}
347352
}
348353

349354
fn with_mapping_for_path<F>(path: PathBuf, f: F)
350355
where
351356
F: FnMut(&Context<'_>),
352357
{
353-
let mut cache = MAPPINGS_CACHE.borrow_mut();
358+
if let Ok(mut cache) = MAPPINGS_CACHE.lock() {
354359

355-
let idx = cache.iter().position(|&(ref p, _)| p == &path);
360+
let idx = cache.iter().position(|&(ref p, _)| p == &path);
356361

357-
// Invariant: after this conditional completes without early returning
358-
// from an error, the cache entry for this path is at index 0.
362+
// Invariant: after this conditional completes without early returning
363+
// from an error, the cache entry for this path is at index 0.
359364

360-
if let Some(idx) = idx {
361-
// When the mapping is already in the cache, move it to the front.
362-
if idx != 0 {
363-
let entry = cache.remove(idx);
364-
cache.insert(0, entry);
365-
}
366-
} else {
367-
// When the mapping is not in the cache, create a new mapping,
368-
// insert it into the front of the cache, and evict the oldest cache
369-
// entry if necessary.
370-
let mapping = match Mapping::new(&path) {
371-
None => return,
372-
Some(m) => m,
373-
};
365+
if let Some(idx) = idx {
366+
// When the mapping is already in the cache, move it to the front.
367+
if idx != 0 {
368+
let entry = cache.remove(idx);
369+
cache.insert(0, entry);
370+
}
371+
} else {
372+
// When the mapping is not in the cache, create a new mapping,
373+
// insert it into the front of the cache, and evict the oldest cache
374+
// entry if necessary.
375+
let mapping = match Mapping::new(&path) {
376+
None => return,
377+
Some(m) => m,
378+
};
374379

375-
if cache.len() == MAPPINGS_CACHE_SIZE {
376-
cache.pop();
380+
if cache.len() == MAPPINGS_CACHE_SIZE {
381+
cache.pop();
382+
}
383+
384+
cache.insert(0, (path, mapping));
377385
}
378386

379-
cache.insert(0, (path, mapping));
387+
cache[0].1.rent(f);
380388
}
381-
382-
cache[0].1.rent(f);
383389
}
384390

385391
pub unsafe fn resolve(what: ResolveWhat, cb: &mut FnMut(&super::Symbol)) {

src/symbolize/mod.rs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -443,8 +443,6 @@ pub fn clear_symbol_cache() {
443443
clear_imp()
444444
}
445445

446-
fn noop_clear_symbol_cache() {}
447-
448446
cfg_if::cfg_if! {
449447
if #[cfg(all(windows, target_env = "msvc", feature = "dbghelp"))] {
450448
mod dbghelp;
@@ -474,6 +472,8 @@ cfg_if::cfg_if! {
474472
mod coresymbolication;
475473
use self::coresymbolication::resolve as resolve_imp;
476474
use self::coresymbolication::Symbol as SymbolImp;
475+
476+
fn noop_clear_symbol_cache() {}
477477
use noop_clear_symbol_cache as clear_imp;
478478
} else if #[cfg(all(feature = "libbacktrace",
479479
any(unix, all(windows, not(target_vendor = "uwp"), target_env = "gnu")),
@@ -482,18 +482,24 @@ cfg_if::cfg_if! {
482482
mod libbacktrace;
483483
use self::libbacktrace::resolve as resolve_imp;
484484
use self::libbacktrace::Symbol as SymbolImp;
485+
486+
fn noop_clear_symbol_cache() {}
485487
use noop_clear_symbol_cache as clear_imp;
486488
} else if #[cfg(all(unix,
487489
not(target_os = "emscripten"),
488490
feature = "dladdr"))] {
489491
mod dladdr_resolve;
490492
use self::dladdr_resolve::resolve as resolve_imp;
491493
use self::dladdr_resolve::Symbol as SymbolImp;
494+
495+
fn noop_clear_symbol_cache() {}
492496
use noop_clear_symbol_cache as clear_imp;
493497
} else {
494498
mod noop;
495499
use self::noop::resolve as resolve_imp;
496500
use self::noop::Symbol as SymbolImp;
497-
use clear_symbol_cache as clear_imp;
501+
502+
fn noop_clear_symbol_cache() {}
503+
use noop_clear_symbol_cache as clear_imp;
498504
}
499505
}

0 commit comments

Comments
 (0)