33
44use core:: { fmt, slice} ;
55use std:: {
6- borrow:: Cow ,
76 env,
8- fmt:: { Debug , Display , Write } ,
7+ fmt:: { Debug , Display } ,
98 fs,
10- path:: PathBuf ,
119 pin:: Pin ,
1210 sync:: Mutex ,
1311} ;
@@ -21,19 +19,13 @@ use libc::{
2119} ;
2220use meminterval:: { Interval , IntervalTree } ;
2321use num_enum:: { IntoPrimitive , TryFromPrimitive } ;
24- use object:: Object ;
25- use rangemap:: RangeMap ;
2622
2723use crate :: {
2824 emu:: EmulatorModules ,
2925 modules:: {
3026 calls:: FullBacktraceCollector ,
3127 snapshot:: SnapshotModule ,
32- utils:: {
33- addr2line_legacy,
34- filters:: { HasAddressFilter , StdAddressFilter } ,
35- load_file_section,
36- } ,
28+ utils:: filters:: { HasAddressFilter , StdAddressFilter } ,
3729 AddressFilter , EmulatorModule , EmulatorModuleTuple ,
3830 } ,
3931 qemu:: { Hook , MemAccessInfo , QemuHooks , SyscallHookResult } ,
@@ -1348,126 +1340,8 @@ where
13481340/// # Safety
13491341/// Will access the global [`FullBacktraceCollector`].
13501342/// Calling this function concurrently might be racey.
1351- #[ expect( clippy:: too_many_lines, clippy:: unnecessary_cast) ]
13521343pub unsafe fn asan_report ( rt : & AsanGiovese , qemu : Qemu , pc : GuestAddr , err : & AsanError ) {
1353- let mut regions = HashMap :: new ( ) ;
1354- for region in qemu. mappings ( ) {
1355- if let Some ( path) = region. path ( ) {
1356- let start = region. start ( ) ;
1357- let end = region. end ( ) ;
1358- let entry = regions. entry ( path. to_owned ( ) ) . or_insert ( start..end) ;
1359- if start < entry. start {
1360- * entry = start..entry. end ;
1361- }
1362- if end > entry. end {
1363- * entry = entry. start ..end;
1364- }
1365- }
1366- }
1367-
1368- let mut resolvers = vec ! [ ] ;
1369- let mut images = vec ! [ ] ;
1370- let mut ranges = RangeMap :: new ( ) ;
1371-
1372- for ( path, rng) in regions {
1373- let data = fs:: read ( & path) ;
1374- if data. is_err ( ) {
1375- continue ;
1376- }
1377- let data = data. unwrap ( ) ;
1378- let idx = images. len ( ) ;
1379- images. push ( ( path, data) ) ;
1380- ranges. insert ( rng, idx) ;
1381- }
1382-
1383- let arena_data = typed_arena:: Arena :: new ( ) ;
1384-
1385- for img in & images {
1386- if let Ok ( obj) = object:: read:: File :: parse ( & * img. 1 ) {
1387- let endian = if obj. is_little_endian ( ) {
1388- addr2line:: gimli:: RunTimeEndian :: Little
1389- } else {
1390- addr2line:: gimli:: RunTimeEndian :: Big
1391- } ;
1392-
1393- let mut load_section = |id : addr2line:: gimli:: SectionId | -> Result < _ , _ > {
1394- load_file_section ( id, & obj, endian, & arena_data)
1395- } ;
1396-
1397- let dwarf = addr2line:: gimli:: Dwarf :: load ( & mut load_section) . unwrap ( ) ;
1398- let ctx = addr2line:: Context :: from_dwarf ( dwarf)
1399- . expect ( "Failed to create an addr2line context" ) ;
1400-
1401- //let ctx = addr2line::Context::new(&obj).expect("Failed to create an addr2line context");
1402- resolvers. push ( Some ( ( obj, ctx) ) ) ;
1403- } else {
1404- resolvers. push ( None ) ;
1405- }
1406- }
1407-
1408- let resolve_addr = |addr : GuestAddr | -> String {
1409- let mut info = String :: new ( ) ;
1410- if let Some ( ( rng, idx) ) = ranges. get_key_value ( & addr) {
1411- let raddr = ( addr - rng. start ) as u64 ;
1412- if let Some ( ( obj, ctx) ) = resolvers[ * idx] . as_ref ( ) {
1413- let symbols = obj. symbol_map ( ) ;
1414- let mut func = symbols. get ( raddr) . map ( |x| x. name ( ) . to_string ( ) ) ;
1415-
1416- if func. is_none ( ) {
1417- let pathname = PathBuf :: from ( images[ * idx] . 0 . clone ( ) ) ;
1418- let mut split_dwarf_loader = addr2line_legacy:: SplitDwarfLoader :: new (
1419- |data, endian| {
1420- addr2line:: gimli:: EndianSlice :: new (
1421- arena_data. alloc ( Cow :: Owned ( data. into_owned ( ) ) ) ,
1422- endian,
1423- )
1424- } ,
1425- Some ( pathname) ,
1426- ) ;
1427-
1428- let frames = ctx. find_frames ( raddr) ;
1429- if let Ok ( mut frames) = split_dwarf_loader. run ( frames) {
1430- if let Some ( frame) = frames. next ( ) . unwrap_or ( None ) {
1431- if let Some ( function) = frame. function {
1432- if let Ok ( name) = function. raw_name ( ) {
1433- let demangled =
1434- addr2line:: demangle_auto ( name, function. language ) ;
1435- func = Some ( demangled. to_string ( ) ) ;
1436- }
1437- }
1438- }
1439- }
1440- }
1441-
1442- if let Some ( name) = func {
1443- info += " in " ;
1444- info += & name;
1445- }
1446-
1447- if let Some ( loc) = ctx. find_location ( raddr) . unwrap_or ( None ) {
1448- if info. is_empty ( ) {
1449- info += " in" ;
1450- }
1451- info += " " ;
1452- if let Some ( file) = loc. file {
1453- info += file;
1454- }
1455- if let Some ( line) = loc. line {
1456- info += ":" ;
1457- info += & line. to_string ( ) ;
1458- }
1459- } else {
1460- let _ = write ! ( & mut info, " ({}+{raddr:#x})" , images[ * idx] . 0 ) ;
1461- }
1462- }
1463- if info. is_empty ( ) {
1464- let _ = write ! ( & mut info, " ({}+{raddr:#x})" , images[ * idx] . 0 ) ;
1465- }
1466- }
1467- info
1468- } ;
1469-
1470- // TODO, make a class Resolver for resolving the addresses??
1344+ let resolver = crate :: modules:: utils:: addr2line:: AddressResolver :: new ( & qemu) ;
14711345 eprintln ! ( "=================================================================" ) ;
14721346 let backtrace = FullBacktraceCollector :: backtrace ( )
14731347 . map ( |r| {
@@ -1478,7 +1352,7 @@ pub unsafe fn asan_report(rt: &AsanGiovese, qemu: Qemu, pc: GuestAddr, err: &Asa
14781352 . unwrap_or ( vec ! [ pc] ) ;
14791353 eprintln ! ( "AddressSanitizer Error: {err}" ) ;
14801354 for ( i, addr) in backtrace. iter ( ) . rev ( ) . enumerate ( ) {
1481- eprintln ! ( "\t #{i} {addr:#x}{}" , resolve_addr ( * addr) ) ;
1355+ eprintln ! ( "\t #{i} {addr:#x}{}" , resolver . resolve ( * addr) ) ;
14821356 }
14831357 let addr = match err {
14841358 AsanError :: Read ( addr, _) | AsanError :: Write ( addr, _) | AsanError :: BadFree ( addr, _) => {
@@ -1493,13 +1367,13 @@ pub unsafe fn asan_report(rt: &AsanGiovese, qemu: Qemu, pc: GuestAddr, err: &Asa
14931367 } else {
14941368 eprintln ! ( "Freed at:" ) ;
14951369 for ( i, addr) in item. free_backtrace . iter ( ) . rev ( ) . enumerate ( ) {
1496- eprintln ! ( "\t #{i} {addr:#x}{}" , resolve_addr ( * addr) ) ;
1370+ eprintln ! ( "\t #{i} {addr:#x}{}" , resolver . resolve ( * addr) ) ;
14971371 }
14981372 eprintln ! ( "And previously allocated at:" ) ;
14991373 }
15001374
15011375 for ( i, addr) in item. backtrace . iter ( ) . rev ( ) . enumerate ( ) {
1502- eprintln ! ( "\t #{i} {addr:#x}{}" , resolve_addr ( * addr) ) ;
1376+ eprintln ! ( "\t #{i} {addr:#x}{}" , resolver . resolve ( * addr) ) ;
15031377 }
15041378 } ;
15051379
0 commit comments