3
3
4
4
use core:: { fmt, slice} ;
5
5
use std:: {
6
- borrow:: Cow ,
7
6
env,
8
- fmt:: { Debug , Display , Write } ,
7
+ fmt:: { Debug , Display } ,
9
8
fs,
10
- path:: PathBuf ,
11
9
pin:: Pin ,
12
10
sync:: Mutex ,
13
11
} ;
@@ -21,19 +19,13 @@ use libc::{
21
19
} ;
22
20
use meminterval:: { Interval , IntervalTree } ;
23
21
use num_enum:: { IntoPrimitive , TryFromPrimitive } ;
24
- use object:: Object ;
25
- use rangemap:: RangeMap ;
26
22
27
23
use crate :: {
28
24
emu:: EmulatorModules ,
29
25
modules:: {
30
26
calls:: FullBacktraceCollector ,
31
27
snapshot:: SnapshotModule ,
32
- utils:: {
33
- addr2line_legacy,
34
- filters:: { HasAddressFilter , StdAddressFilter } ,
35
- load_file_section,
36
- } ,
28
+ utils:: filters:: { HasAddressFilter , StdAddressFilter } ,
37
29
AddressFilter , EmulatorModule , EmulatorModuleTuple ,
38
30
} ,
39
31
qemu:: { Hook , MemAccessInfo , QemuHooks , SyscallHookResult } ,
@@ -1348,126 +1340,8 @@ where
1348
1340
/// # Safety
1349
1341
/// Will access the global [`FullBacktraceCollector`].
1350
1342
/// Calling this function concurrently might be racey.
1351
- #[ expect( clippy:: too_many_lines, clippy:: unnecessary_cast) ]
1352
1343
pub 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) ;
1471
1345
eprintln ! ( "=================================================================" ) ;
1472
1346
let backtrace = FullBacktraceCollector :: backtrace ( )
1473
1347
. map ( |r| {
@@ -1478,7 +1352,7 @@ pub unsafe fn asan_report(rt: &AsanGiovese, qemu: Qemu, pc: GuestAddr, err: &Asa
1478
1352
. unwrap_or ( vec ! [ pc] ) ;
1479
1353
eprintln ! ( "AddressSanitizer Error: {err}" ) ;
1480
1354
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) ) ;
1482
1356
}
1483
1357
let addr = match err {
1484
1358
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
1493
1367
} else {
1494
1368
eprintln ! ( "Freed at:" ) ;
1495
1369
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) ) ;
1497
1371
}
1498
1372
eprintln ! ( "And previously allocated at:" ) ;
1499
1373
}
1500
1374
1501
1375
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) ) ;
1503
1377
}
1504
1378
} ;
1505
1379
0 commit comments