Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

app crashes if build with --release #310

Open
dumdrak opened this issue Dec 31, 2024 · 3 comments
Open

app crashes if build with --release #310

dumdrak opened this issue Dec 31, 2024 · 3 comments

Comments

@dumdrak
Copy link

dumdrak commented Dec 31, 2024

Hi,

When I use Tab and TabsContainer my app works in debug but crashes in release mode with the error
(exit code: 0xc000001d, STATUS_ILLEGAL_INSTRUCTION)

putting

[profile.release]
opt-level = 0

in cargo.toml makes the app work again in --release but its not optimized

any idea what I'm doing wrong?

the code that makes this happen is

<-- window, layout, file dialogs
//tabs
#[nwg_control()]
#[nwg_layout_item(layout: grid, row: 0, col: 0, col_span: 5, row_span: 9)]
tabs_container: nwg::TabsContainer,
//tab proveedors
#[nwg_control(text: "Proveedors",parent: tabs_container)]
tab_proveedors: nwg::Tab,
-->more controls

@w-flo
Copy link

w-flo commented Jan 17, 2025

I noticed the same issue with code that was working on a previous rustc version. I cross-compile from Ubuntu to the x86_64-pc-windows-gnu target.

After some investigation, I found some suspicious transmute()s in controls/tabs.rs. This fixes some of the crashes for me, but I'm not sure it's enough. There are quite a few transmute()s in the code base that probably shouldn't be there. The docs say:

Transmuting integers to pointers is a largely unspecified operation. It is likely not equivalent to an as cast. Doing non-zero-sized memory accesses with a pointer constructed this way is currently considered undefined behavior.
[..] In particular, doing a pointer-to-integer-to-pointer roundtrip via transmute is not a lossless process

diff --git a/native-windows-gui/src/controls/tabs.rs b/native-windows-gui/src/controls/tabs.rs
index feafa8c..fe438d5 100644
--- a/native-windows-gui/src/controls/tabs.rs
+++ b/native-windows-gui/src/controls/tabs.rs
@@ -265,7 +265,7 @@ impl TabsContainer {
         let handler0 = bind_raw_event_handler_inner(&parent_handle, handle as usize, move |_hwnd, msg, _w, l| { unsafe {
             match msg {
                 WM_NOTIFY => {
-                    let nmhdr: &NMHDR = mem::transmute(l);
+                    let nmhdr: &NMHDR = &*(l as *const NMHDR);
                     if nmhdr.code == TCN_SELCHANGE {
                         let index = SendMessageW(handle, TCM_GETCURSEL, 0, 0) as i32;
                         let data: (HWND, i32) = (handle, index);
@@ -318,7 +318,7 @@ impl TabsContainer {
                     data.tab_offset_y = tab_height;
                     
                     let data_ptr = &data as *const ResizeDirectChildrenParams;
-                    EnumChildWindows(hwnd, Some(resize_direct_children), mem::transmute(data_ptr));
+                    EnumChildWindows(hwnd, Some(resize_direct_children), data_ptr as isize);
                 },
                 _ => {}
             }
@@ -612,7 +612,7 @@ impl Tab {
         let count_ptr = &mut count as *mut usize;
 
         unsafe {
-            EnumChildWindows(tab_view_handle, Some(count_children), mem::transmute(count_ptr));
+            EnumChildWindows(tab_view_handle, Some(count_children), count_ptr as isize);
         }
 
         count
@@ -757,7 +757,7 @@ unsafe extern "system" fn count_children(handle: HWND, params: LPARAM) -> BOOL {
 
     if &wh::get_window_class_name(handle) == "NWG_TAB" {
         let tab_index = (wh::get_window_long(handle, GWL_USERDATA)) as WPARAM;
-        let count: &mut usize = ::std::mem::transmute(params);
+        let count: &mut usize = &mut *(params as *mut usize);
         *count = usize::max(tab_index+1, *count);
     }
     
@@ -768,7 +768,7 @@ unsafe extern "system" fn count_children(handle: HWND, params: LPARAM) -> BOOL {
 unsafe extern "system" fn toggle_children_tabs(handle: HWND, params: LPARAM) -> BOOL {
     use winapi::um::winuser::GWL_USERDATA;
     
-    let &(parent, index): &(HWND, i32) = mem::transmute(params);
+    let &(parent, index): &(HWND, i32) = &*(params as *const (HWND, i32));
     if wh::get_window_parent(handle) == parent {
         let tab_index = wh::get_window_long(handle, GWL_USERDATA) as i32;
         let visible = tab_index == index + 1;

@dumdrak
Copy link
Author

dumdrak commented Jan 20, 2025

I tried using the pull request #308 and the crash stoped.

to do so you have to put in your Cargo.toml the dependence:
native-windows-gui = { git = "https://github.com/nickbeth/native-windows-gui.git", branch = "transmute-ub" }

its only in the 1.0.12 version (main its 1.0.13) but works with optimizations.

@nickbeth
Copy link

Hi, I'm the author of #308.

Since I'm using this library in my app, I've made a fork of this repo with the "transmute fix" applied. Just wanted to clarify how the fork works:

  • Branch transmute-ub is version 1.0.13 (latest) with the fix applied
  • Branch transmute-ub-1.0.12 is version 1.0.12 with the fix applied

I had to make a fix for v1.0.12 as well because v1.0.13 broke nested flex layouts, which I was using in my app.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants