Skip to content

Commit

Permalink
Finally windows address obtainer is thread safe and releases all nece…
Browse files Browse the repository at this point in the history
…ssary resources
  • Loading branch information
szymonwieloch committed Aug 16, 2019
1 parent f827185 commit 9fc15f1
Showing 1 changed file with 38 additions and 23 deletions.
61 changes: 38 additions & 23 deletions src/raw/windows.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ lazy_static! {
count: 0,
previous: 0
});
static ref OBTAINERS_COUNT : Mutex<usize> = Mutex::new(0);
}


Expand Down Expand Up @@ -167,35 +168,45 @@ pub unsafe fn open_lib(name: &OsStr) -> Result<Handle, Error> {

#[inline]
pub unsafe fn addr_info_init(){
let process_handle = GetCurrentProcess();
let result = SymInitializeW(process_handle, null_mut(), TRUE);
assert_eq!(result, TRUE);
//calls to Sym* functions are not thread safe.
let mut lock = OBTAINERS_COUNT.lock().expect("Mutex got poisoned");
if *lock == 0 {
let process_handle = GetCurrentProcess();
let result = SymInitializeW(process_handle, null_mut(), TRUE);
assert_eq!(result, TRUE);
}
*lock += 1;
}

#[inline]
pub unsafe fn addr_info_obtain(addr: * const ()) -> Result<AddressInfo, Error>{

let process_handle = GetCurrentProcess();
let module_base = SymGetModuleBase64(process_handle, addr as u64);

if module_base == 0 {
return Err(Error::AddrNotMatchingDll(get_win_error()));
}
let mut buffer: [WCHAR; PATH_MAX as usize] = uninitialized();

let path_len = GetModuleFileNameW(module_base as HMODULE, buffer.as_mut_ptr(), PATH_MAX);

if path_len == 0 {
return Err(Error::AddrNotMatchingDll(get_win_error()));
}

//calls to Sym* functions are not thread safe.
let mut buffer: [WCHAR; PATH_MAX as usize] = uninitialized();
let mut symbol_buffer: [u8; size_of::<SYMBOL_INFOW>() + MAX_SYMBOL_LEN * size_of::<WCHAR>()] = uninitialized();
let symbol_info: * mut SYMBOL_INFOW = symbol_buffer.as_mut_ptr() as * mut SYMBOL_INFOW;
let (module_base, path_len, symbol_info, result) = {
let mut _lock = OBTAINERS_COUNT.lock().expect("Mutex got poisoned");
let module_base = SymGetModuleBase64(process_handle, addr as u64);

if module_base == 0 {
return Err(Error::AddrNotMatchingDll(get_win_error()));
}


(*symbol_info).SizeOfStruct = size_of::<SYMBOL_INFOW>() as DWORD;
(*symbol_info).MaxNameLen = MAX_SYMBOL_LEN as DWORD;
let mut displacement:DWORD64 = 0;
let result = SymFromAddrW(process_handle, addr as DWORD64, &mut displacement, symbol_info);
let path_len = GetModuleFileNameW(module_base as HMODULE, buffer.as_mut_ptr(), PATH_MAX);
if path_len == 0 {
return Err(Error::AddrNotMatchingDll(get_win_error()));
}
let symbol_info: * mut SYMBOL_INFOW = symbol_buffer.as_mut_ptr() as * mut SYMBOL_INFOW;

(*symbol_info).SizeOfStruct = size_of::<SYMBOL_INFOW>() as DWORD;
(*symbol_info).MaxNameLen = MAX_SYMBOL_LEN as DWORD;
let mut displacement:DWORD64 = 0;
let result = SymFromAddrW(process_handle, addr as DWORD64, &mut displacement, symbol_info);
(module_base, path_len, symbol_info, result)
};

let os = if result == TRUE {
let name_len = (*symbol_info).NameLen as usize;
Expand Down Expand Up @@ -224,9 +235,13 @@ pub unsafe fn addr_info_obtain(addr: * const ()) -> Result<AddressInfo, Error>{

#[inline]
pub unsafe fn addr_info_cleanup(){
let process_handle = GetCurrentProcess();
let result = SymCleanup(process_handle);
assert_eq!(result, TRUE);
let mut lock = OBTAINERS_COUNT.lock().expect("Mutex got poisoned");
*lock -= 1;
if *lock == 0 {
let process_handle = GetCurrentProcess();
let result = SymCleanup(process_handle);
assert_eq!(result, TRUE);
}
}

#[inline]
Expand Down

0 comments on commit 9fc15f1

Please sign in to comment.