@@ -10,10 +10,12 @@ use crate::{
10
10
use anyhow:: { anyhow, Context , Result } ;
11
11
use core:: mem:: size_of;
12
12
use ddcommon:: Endpoint ;
13
+ use rangemap:: RangeInclusiveMap ;
13
14
use serde:: { Deserialize , Serialize } ;
14
15
use std:: ffi:: { c_void, OsString } ;
15
16
use std:: fmt;
16
17
use std:: mem:: MaybeUninit ;
18
+ use std:: ops:: RangeInclusive ;
17
19
use std:: os:: windows:: ffi:: OsStringExt ;
18
20
use std:: ptr:: { addr_of, read_unaligned} ;
19
21
use std:: sync:: Mutex ;
@@ -339,7 +341,7 @@ struct AlignedContext {
339
341
fn walk_thread_stack (
340
342
process_handle : HANDLE ,
341
343
thread_id : u32 ,
342
- modules : & [ ModuleInfo ] ,
344
+ modules : & RangeInclusiveMap < usize , ModuleInfo > ,
343
345
) -> Result < StackTrace > {
344
346
let mut stacktrace = StackTrace :: new_incomplete ( ) ;
345
347
let thread_handle = unsafe { OpenThread ( THREAD_ALL_ACCESS , false , thread_id) ? } ;
@@ -403,10 +405,7 @@ fn walk_thread_stack(
403
405
frame. sp = Some ( format ! ( "{:x}" , native_frame. AddrStack . Offset ) ) ;
404
406
405
407
// Find the module
406
- let module = modules. iter ( ) . find ( |module| {
407
- module. base_address <= native_frame. AddrPC . Offset
408
- && native_frame. AddrPC . Offset < module. base_address + module. size
409
- } ) ;
408
+ let module = modules. get ( & ( native_frame. AddrPC . Offset as usize ) ) ;
410
409
411
410
if let Some ( module) = module {
412
411
frame. module_base_address = Some ( format ! ( "{:x}" , module. base_address) ) ;
@@ -417,7 +416,8 @@ fn walk_thread_stack(
417
416
frame. path . clone_from ( & module. path ) ;
418
417
419
418
if let Some ( pdb_info) = & module. pdb_info {
420
- frame. build_id = Some ( format ! ( "{:x}{:x}" , pdb_info. signature, pdb_info. age) ) ;
419
+ // in the backend we expect the AGE to be a uppercase hex number
420
+ frame. build_id = Some ( format ! ( "{:x}{:X}" , pdb_info. signature, pdb_info. age) ) ;
421
421
frame. build_id_type = Some ( BuildIdType :: PDB ) ;
422
422
frame. file_type = Some ( FileType :: PE ) ;
423
423
}
@@ -432,21 +432,23 @@ fn walk_thread_stack(
432
432
Ok ( stacktrace)
433
433
}
434
434
435
+ #[ derive( Clone , Eq , PartialEq ) ]
435
436
struct ModuleInfo {
436
437
base_address : u64 ,
437
438
size : u64 ,
438
439
path : Option < String > ,
439
440
pdb_info : Option < PdbInfo > ,
440
441
}
441
442
443
+ #[ derive( Clone , Eq , PartialEq ) ]
442
444
struct PdbInfo {
443
445
age : u32 ,
444
446
signature : Guid ,
445
447
}
446
448
447
- fn list_modules ( process_handle : HANDLE ) -> anyhow:: Result < Vec < ModuleInfo > > {
449
+ fn list_modules ( process_handle : HANDLE ) -> anyhow:: Result < RangeInclusiveMap < usize , ModuleInfo > > {
448
450
// Use EnumProcessModules to get a list of modules
449
- let mut module_infos = Vec :: new ( ) ;
451
+ let mut module_infos: RangeInclusiveMap < usize , ModuleInfo > = RangeInclusiveMap :: new ( ) ;
450
452
451
453
// Get the number of bytes required to store the array of module handles
452
454
let mut cb_needed = 0 ;
@@ -494,12 +496,18 @@ fn list_modules(process_handle: HANDLE) -> anyhow::Result<Vec<ModuleInfo>> {
494
496
495
497
let module_path = get_module_path ( process_handle, hmodule) ;
496
498
497
- module_infos. push ( ModuleInfo {
498
- base_address : module_info. lpBaseOfDll as u64 ,
499
- size : module_info. SizeOfImage as u64 ,
500
- path : module_path. ok ( ) ,
501
- pdb_info : get_pdb_info ( process_handle, module_info. lpBaseOfDll as u64 ) . ok ( ) ,
502
- } ) ;
499
+ module_infos. insert (
500
+ RangeInclusive :: new (
501
+ module_info. lpBaseOfDll as usize ,
502
+ ( module_info. lpBaseOfDll as usize ) . saturating_add ( module_info. SizeOfImage as usize ) ,
503
+ ) ,
504
+ ModuleInfo {
505
+ base_address : module_info. lpBaseOfDll as u64 ,
506
+ size : module_info. SizeOfImage as u64 ,
507
+ path : module_path. ok ( ) ,
508
+ pdb_info : get_pdb_info ( process_handle, module_info. lpBaseOfDll as u64 ) . ok ( ) ,
509
+ } ,
510
+ ) ;
503
511
}
504
512
505
513
Ok ( module_infos)
@@ -565,6 +573,7 @@ struct ImageNtHeadersGeneric {
565
573
566
574
#[ repr( C ) ]
567
575
#[ derive( Debug ) ]
576
+ #[ derive( Clone , Eq , PartialEq ) ]
568
577
struct Guid {
569
578
pub data1 : u32 ,
570
579
pub data2 : u16 ,
0 commit comments