仅当在 vscode 中通过 LLDB 启动时才会出现 Rust 恐慌

发布于 2025-01-13 16:45:45 字数 4682 浏览 2 评论 0原文

摘要:

  • 在 vscode 终端窗口中运行 cargo buildcargo run => 成功
  • cargo build my self => 之后 运行在 vscode 终端窗口中创建的 exe 文件成功
  • tasks.json => 中构建货物 成功
  • 通过 launch.json => 中的 LLDB 启动 调试失败
  • 在运行我的 self => 后通过 launch.json 中的 LLDB 附加进行调试成功

目前,我刚刚在 vscode 中运行了以下示例:

extern crate winapi;

use winapi::shared::windef::*;
use winapi::shared::minwindef::*;
use winapi::um::winuser::*;
use winapi::um::wingdi::*;
use winapi::um::libloaderapi::*;

use std::os::windows::ffi::OsStrExt;
use std::ffi::OsStr;

fn to_wstring(s : &str) -> Vec<u16> {
    OsStr::new( s ).encode_wide().chain( std::iter::once( 0 ) ).collect()
}

pub unsafe extern "system" fn window_proc(hwnd : HWND, msg : UINT, wparam : WPARAM, lparam : LPARAM) -> LRESULT {
    if msg == WM_DESTROY {
        PostQuitMessage( 0 );
        return 0;
    }

    return DefWindowProcW( hwnd, msg, wparam, lparam );
}

fn main() {
    unsafe {
        let wc = WNDCLASSEXW {
            cbSize : std::mem::size_of::< WNDCLASSEXW >() as UINT,
            style : CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS,
            lpfnWndProc : Some( window_proc ),
            cbClsExtra : 0,
            cbWndExtra : 0,
            hInstance : GetModuleHandleW( std::ptr::null_mut() ) as HINSTANCE,
            hIcon : std::ptr::null_mut(),
            hCursor : LoadCursorW( std::ptr::null_mut(), IDC_ARROW ),
            hbrBackground : GetStockObject( WHITE_BRUSH as i32 ) as HBRUSH,
            lpszMenuName : std::ptr::null_mut(),
            lpszClassName : to_wstring( "rust_window_class" ).as_ptr(),
            hIconSm : std::ptr::null_mut()
        };
        if RegisterClassExW( &wc ) == 0 {
            panic!( "RegisterClassEx failed" );
        }

        let hwnd = CreateWindowExW( 
            0, wc.lpszClassName, to_wstring( "Rust Window" ).as_ptr(), WS_OVERLAPPEDWINDOW,
            0, 0, 640, 480, std::ptr::null_mut(), std::ptr::null_mut(), wc.hInstance, std::ptr::null_mut()
        );
        if hwnd == std::ptr::null_mut() {
            panic!( "CreateWindowEx failed" );
        }

        ShowWindow( hwnd, SW_SHOW );

        let mut msg = MSG {
            hwnd : std::ptr::null_mut(),
            message : 0,
            wParam : 0,
            lParam : 0,
            time : 0,
            pt : POINT{ x : 0, y : 0 },
        };
        loop {
            let res = GetMessageW( &mut msg, std::ptr::null_mut(), 0, 0 );
            if res == 0 || res == -1 {
                break;
            }

            DispatchMessageW( &msg );
        }
    }
}

它运行良好,Windows 工作正常。 但是在vscode中使用lldb调试失败。

我使用 vscode rust 扩展为 launch.json 创建以下语法:

{
  "type": "lldb",
  "request": "launch",
  "name": "Debug executable 'rust-ex'",
  "cargo": {
      "args": [
          "build",
          "--bin=rust-ex",
          "--package=rust-ex"
      ],
      "filter": {
          "name": "rust-ex",
          "kind": "bin"
      }
  },
  "args": [],
  "cwd": "${workspaceFolder}"
},

作为参考,我的项目名称是“rust-ex”。

launch.json 条目无法运行上面链接 (winapi) 中的示例。

thread 'main' panicked at 'CreateWindowEx failed', src\main.rs:51:13

launch.json 条目对于 hello world 示例运行良好。

并直接在终端窗口中从 Cargo 构建 winapi 示例,并直接运行 exe,两者都运行良好。

这次,使用 vscode LLDB 扩展,创建了以下语法:

{
  "type": "lldb",
  "request": "launch",
  "name": "test",
  "program": "${workspaceFolder}/target/debug/rust-ex.exe",
  "args": [],
  "cwd": "${workspaceFolder}"
},

这也导致了同样的错误。

这次,使用 vscode LLDB 扩展,创建了以下语法:

{
  "type": "lldb",
  "request": "attach",
  "name": "Attach",
  "pid": "${command:pickMyProcess}"
},

我自己运行后效果很好。 (使用 select pid 我自己)

所以这次我将以下内容添加到tasks.json:

{
  "label": "rust test",
  "type": "shell",
  "command": "start",
  "args": [
    "${workspaceFolder}/target/debug/rust-ex.exe"
  ]
}

然后,在 launch.json 中,我尝试:

{
  "type": "lldb",
  "request": "attach",
  "name": "Attach Test",
  "preLaunchTask": "rust test",
  "program": "${workspaceFolder}/target/debug/rust-ex.exe"
},

这按我的预期工作得很好。

为什么相同的代码仅通过 LLDB 启动时会出现错误?

Summary:

  • Run cargo build and cargo run in vscode terminal window => Success
  • Run created exe file in the vscode terminal window after cargo build my self => Success
  • Build cargo from in tasks.json => Success
  • Debugging by LLDB launch in launch.json => Failed
  • Debugging by LLDB attch in launch.json after run my self => Success

Currently, I just ran the following example in vscode:

extern crate winapi;

use winapi::shared::windef::*;
use winapi::shared::minwindef::*;
use winapi::um::winuser::*;
use winapi::um::wingdi::*;
use winapi::um::libloaderapi::*;

use std::os::windows::ffi::OsStrExt;
use std::ffi::OsStr;

fn to_wstring(s : &str) -> Vec<u16> {
    OsStr::new( s ).encode_wide().chain( std::iter::once( 0 ) ).collect()
}

pub unsafe extern "system" fn window_proc(hwnd : HWND, msg : UINT, wparam : WPARAM, lparam : LPARAM) -> LRESULT {
    if msg == WM_DESTROY {
        PostQuitMessage( 0 );
        return 0;
    }

    return DefWindowProcW( hwnd, msg, wparam, lparam );
}

fn main() {
    unsafe {
        let wc = WNDCLASSEXW {
            cbSize : std::mem::size_of::< WNDCLASSEXW >() as UINT,
            style : CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS,
            lpfnWndProc : Some( window_proc ),
            cbClsExtra : 0,
            cbWndExtra : 0,
            hInstance : GetModuleHandleW( std::ptr::null_mut() ) as HINSTANCE,
            hIcon : std::ptr::null_mut(),
            hCursor : LoadCursorW( std::ptr::null_mut(), IDC_ARROW ),
            hbrBackground : GetStockObject( WHITE_BRUSH as i32 ) as HBRUSH,
            lpszMenuName : std::ptr::null_mut(),
            lpszClassName : to_wstring( "rust_window_class" ).as_ptr(),
            hIconSm : std::ptr::null_mut()
        };
        if RegisterClassExW( &wc ) == 0 {
            panic!( "RegisterClassEx failed" );
        }

        let hwnd = CreateWindowExW( 
            0, wc.lpszClassName, to_wstring( "Rust Window" ).as_ptr(), WS_OVERLAPPEDWINDOW,
            0, 0, 640, 480, std::ptr::null_mut(), std::ptr::null_mut(), wc.hInstance, std::ptr::null_mut()
        );
        if hwnd == std::ptr::null_mut() {
            panic!( "CreateWindowEx failed" );
        }

        ShowWindow( hwnd, SW_SHOW );

        let mut msg = MSG {
            hwnd : std::ptr::null_mut(),
            message : 0,
            wParam : 0,
            lParam : 0,
            time : 0,
            pt : POINT{ x : 0, y : 0 },
        };
        loop {
            let res = GetMessageW( &mut msg, std::ptr::null_mut(), 0, 0 );
            if res == 0 || res == -1 {
                break;
            }

            DispatchMessageW( &msg );
        }
    }
}

It ran fine and windows worked fine.
However, debugging using lldb in vscode failed.

I used the vscode rust extension to create the following syntax for launch.json:

{
  "type": "lldb",
  "request": "launch",
  "name": "Debug executable 'rust-ex'",
  "cargo": {
      "args": [
          "build",
          "--bin=rust-ex",
          "--package=rust-ex"
      ],
      "filter": {
          "name": "rust-ex",
          "kind": "bin"
      }
  },
  "args": [],
  "cwd": "${workspaceFolder}"
},

For reference, my project name is "rust-ex".

This launch.json entry failed to run the example in the link(winapi) above

thread 'main' panicked at 'CreateWindowEx failed', src\main.rs:51:13

This launch.json entry worked fine for the hello world example.

And build the winapi example from cargo directly in the terminal window, and run the exe directly, both work well.

This time, using the vscode LLDB extension, the following syntax was created:

{
  "type": "lldb",
  "request": "launch",
  "name": "test",
  "program": "${workspaceFolder}/target/debug/rust-ex.exe",
  "args": [],
  "cwd": "${workspaceFolder}"
},

This also caused the same error.

This time, using the vscode LLDB extension, the following syntax was created:

{
  "type": "lldb",
  "request": "attach",
  "name": "Attach",
  "pid": "${command:pickMyProcess}"
},

This works fine after I run it myself. (with select pid my self)

So this time I added the following to tasks.json:

{
  "label": "rust test",
  "type": "shell",
  "command": "start",
  "args": [
    "${workspaceFolder}/target/debug/rust-ex.exe"
  ]
}

Then, in launch.json , I tried:

{
  "type": "lldb",
  "request": "attach",
  "name": "Attach Test",
  "preLaunchTask": "rust test",
  "program": "${workspaceFolder}/target/debug/rust-ex.exe"
},

This works very well as I intended.

Why does the same code panic when only launch by LLDB?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

浮生面具三千个 2025-01-20 16:45:45

您的程序中至少有一个 UB - 包含窗口类名称的向量在调用 CreateWindowExW 之前被释放。您应该保持该对象处于活动状态,直到使用完该字符串为止。

You have at least one UB in your program - the vector containing window class name gets freed before you call CreateWindowExW. You should keep that object alive until you are done using the string.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文