1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
|
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
extern crate memmap2;
extern crate rustc_demangle;
extern crate thin_vec;
extern crate uuid;
#[cfg(feature = "parse_elf")]
extern crate object;
mod compact_symbol_table;
#[cfg(feature = "parse_elf")]
mod elf;
#[cfg(feature = "parse_elf")]
use memmap2::MmapOptions;
#[cfg(feature = "parse_elf")]
use std::fs::File;
use compact_symbol_table::CompactSymbolTable;
use rustc_demangle::try_demangle;
use std::ffi::CStr;
use std::mem;
use std::os::raw::c_char;
use std::ptr;
#[cfg(feature = "parse_elf")]
pub fn get_compact_symbol_table_from_file(
debug_path: &str,
breakpad_id: Option<&str>,
) -> Option<CompactSymbolTable> {
let file = File::open(debug_path).ok()?;
let buffer = unsafe { MmapOptions::new().map(&file).ok()? };
elf::get_compact_symbol_table(&buffer, breakpad_id)
}
#[cfg(not(feature = "parse_elf"))]
pub fn get_compact_symbol_table_from_file(
_debug_path: &str,
_breakpad_id: Option<&str>,
) -> Option<CompactSymbolTable> {
None
}
#[no_mangle]
pub unsafe extern "C" fn profiler_get_symbol_table(
debug_path: *const c_char,
breakpad_id: *const c_char,
symbol_table: &mut CompactSymbolTable,
) -> bool {
let debug_path = CStr::from_ptr(debug_path).to_string_lossy();
let breakpad_id = if breakpad_id.is_null() {
None
} else {
match CStr::from_ptr(breakpad_id).to_str() {
Ok(s) => Some(s),
Err(_) => return false,
}
};
match get_compact_symbol_table_from_file(&debug_path, breakpad_id.map(|id| id.as_ref())) {
Some(mut st) => {
std::mem::swap(symbol_table, &mut st);
true
}
None => false,
}
}
#[no_mangle]
pub unsafe extern "C" fn profiler_demangle_rust(
mangled: *const c_char,
buffer: *mut c_char,
buffer_len: usize,
) -> bool {
assert!(!mangled.is_null());
assert!(!buffer.is_null());
if buffer_len == 0 {
return false;
}
let buffer: *mut u8 = mem::transmute(buffer);
let mangled = match CStr::from_ptr(mangled).to_str() {
Ok(s) => s,
Err(_) => return false,
};
match try_demangle(mangled) {
Ok(demangled) => {
let mut demangled = format!("{:#}", demangled);
if !demangled.is_ascii() {
return false;
}
demangled.truncate(buffer_len - 1);
let bytes = demangled.as_bytes();
ptr::copy(bytes.as_ptr(), buffer, bytes.len());
ptr::write(buffer.offset(bytes.len() as isize), 0);
true
}
Err(_) => false,
}
}
|