Skip to content

Commit

Permalink
Fix #3
Browse files Browse the repository at this point in the history
  • Loading branch information
OpenByteDev committed Jul 7, 2022
1 parent 070e6d9 commit 98ccac2
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 24 deletions.
36 changes: 12 additions & 24 deletions src/raw/windows.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use crate::utils;

use super::super::err::Error;
use super::common::{AddressInfo, OverlappingSymbol};
use once_cell::sync::Lazy;
use once_cell::sync::{Lazy, OnceCell};
use std::ffi::{CStr, OsStr, OsString};
use std::io::{Error as IoError, ErrorKind};
use std::mem::size_of;
Expand All @@ -14,9 +14,7 @@ use std::sync::Mutex;
use winapi::shared::basetsd::DWORD64;
use winapi::shared::minwindef::{DWORD, HMODULE, TRUE};
use winapi::shared::winerror::ERROR_CALL_NOT_IMPLEMENTED;
use winapi::um::dbghelp::{
SymCleanup, SymFromAddrW, SymGetModuleBase64, SymInitializeW, SYMBOL_INFOW,
};
use winapi::um::dbghelp::{SymFromAddrW, SymGetModuleBase64, SymInitializeW, SYMBOL_INFOW};
use winapi::um::errhandlingapi::{GetLastError, SetErrorMode, SetThreadErrorMode};
use winapi::um::libloaderapi::{
FreeLibrary, GetModuleFileNameW, GetModuleHandleExW, GetProcAddress, LoadLibraryW,
Expand All @@ -40,7 +38,7 @@ static SET_ERR_MODE_DATA: Lazy<Mutex<SetErrorModeData>> = Lazy::new(|| {
previous: 0,
})
});
static OBTAINERS_COUNT: Lazy<Mutex<usize>> = Lazy::new(|| Mutex::new(0));
static SYM_MUTEX: OnceCell<Mutex<()>> = OnceCell::new();

pub type Handle = HMODULE;

Expand All @@ -57,7 +55,7 @@ process.
https://msdn.microsoft.com/pl-pl/library/windows/desktop/dd553630(v=vs.85).aspx
*/

const ERROR_MODE: DWORD = 1; //app handles everything
const ERROR_MODE: DWORD = 1; // app handles everything

enum ErrorModeGuard {
ThreadPreviousValue(DWORD),
Expand Down Expand Up @@ -172,28 +170,26 @@ pub unsafe fn open_lib(name: &OsStr) -> Result<Handle, Error> {

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

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

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

if module_base == 0 {
Expand Down Expand Up @@ -251,15 +247,7 @@ pub unsafe fn addr_info_obtain(addr: *const ()) -> Result<AddressInfo, Error> {
}

#[inline]
pub unsafe fn addr_info_cleanup() {
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);
}
}
pub unsafe fn addr_info_cleanup() {}

#[inline]
pub fn close_lib(handle: Handle) -> Handle {
Expand Down
14 changes: 14 additions & 0 deletions tests/raw.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,3 +68,17 @@ fn example_address_info() {
assert_eq!(os.name, "c_fun_add_two");
assert_eq!(os.addr, c_fun_add_two as *const ())
}

// https://github.com/OpenByteDev/dlopen2/issues/3
#[test]
#[cfg(windows)]
fn double_sym_init_does_not_panic() {
let lib_path = example_lib_path();
let library = Library::open(&lib_path).expect("Could not open library");
let pointer: *const () = unsafe { library.symbol("c_fun_add_two") }.unwrap();

let _ = std::panic::catch_unwind(|| panic!()); // this generates a backtrace. Backtrace::capture() probably works too

// Panics because SymInitializeW returns an error
unsafe { AddressInfoObtainer::new().obtain(pointer) }.unwrap();
}

0 comments on commit 98ccac2

Please sign in to comment.