使用 .NET 4.0、3.5 时,UnmanagedFunctionPointer 会导致堆栈溢出

2024-02-13

我在点击处理程序中有一个简单的函数,它有一个 try catch 块。如果我在此 try catch 块中抛出异常,它会成功捕获异常。

如果我在抛出异常之前调用非托管 DLL,则异常不会被处理且不会被捕获。

未修改的 DLL 调用正在做什么,可能会破坏我的程序异常处理?

如果我在调试模式下运行程序,即使所有异常都未勾选“异常中断”,它也会捕获异常。应用程序不会崩溃并按预期运行。

如果我以“启动而不调试”的方式运行程序,并在崩溃时点击调试,则会收到以下错误“堆栈 cookie 检测代码检测到基于堆栈的缓冲区溢出”

edit:看来堆栈溢出破坏了异常处理

我附上了一个产生崩溃的简化程序。

ISOConnection _comm;  //This is instantiated at another time in the same thread

//C# test function that crashes when run without a debugger attached
bool DoMagic()
{
    try
    {
        //if I uncomment this line the exception becomes unhandled and cannot be caught
        //_comm.ConnectISO15765();

        throw new Exception();
    }
    catch (Exception ex)
    {
        MessageBox.Show("Caught exception")
    }

//Within ISOConnection class
public void ConnectISO15765(){
    ...
    lock(syncLock){
        uint returnCode = J2534Interface.PassThruConnect((uint)DeviceId, (uint)ProtocolID.ISO15765, (uint)ConnectFlag.NONE, (uint)BaudRate.ISO15765, ref ChannelId);


//C# UnmanagedFunctionPointer allocation code
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate uint PassThruConnect(uint deviceId, uint protocolId, uint flags, uint baudRate, ref uint channelId);
public PassThruConnect Connect;

[DllImport("kernel32.dll")]
public static extern IntPtr LoadLibrary(string dllToLoad);

m_pDll = NativeMethods.LoadLibrary(path);
...
pAddressOfFunctionToCall = NativeMethods.GetProcAddress(m_pDll, "PassThruConnect");
if (pAddressOfFunctionToCall != IntPtr.Zero)
    Connect = (PassThruConnect)Marshal.GetDelegateForFunctionPointer(
        pAddressOfFunctionToCall,
        typeof(PassThruConnect));

//C++ function declaration
long PassThruConnect(unsigned long DeviceID, unsigned long ProtocolID, unsigned long Flags, unsigned long Baudrate, unsigned long *pChannelID);

UPDATE

如果我用以下内容替换对 UnmanagedFunctionPointer PassThurConnect 的调用,则不会发生崩溃

[DllImport("op20pt32.dll", EntryPoint = "PassThruConnect", CallingConvention = CallingConvention.Cdecl)]
public static extern uint PassThruConnect2(uint deviceId, uint protocolId, uint flags, uint baudRate, ref uint channelId);

在分配 UnmanagedFunctionPointer 时是否有什么我没有执行或执行不正确会导致缺少调试器而导致 stackoverflow 崩溃?

更奇怪的是,这段代码在几周前似乎可以工作。主要的变化是 try catch 在另一个线程中,并且我没有使用锁(syncLock)。现在所有内容都在一个线程中,但是在后台工作程序中运行时也会发生相同的崩溃。

更新 #2 问题已半解决

好吧,我一一回滚了我的提交,直到它起作用为止。改变的是我从 .NET 3.5 转到 .NET 4.0

无论是否附加调试器,.NET 3.5 都不会崩溃。如果未附加调试器,.NET 4.0 会崩溃。为了排除代码中的错误,我只是删除了日志的 ConcurrentQueue(我使用的唯一 4.0 功能)并将当前的代码库转换回 3.5,并且我没有收到此错误。

为了百分百确定这是 4.0 的问题,我随后将代码库从 3.5 转换回 4.0,并保留了 ConcurrentQueue(实际上只是更改了构建选项并进行了重建),StackOverflow 崩溃又回来了。

我更喜欢使用 4.0,有什么想法如何调试这个问题吗?

编辑:.NET 4.6.1 也崩溃

更新#3 http://codenition.blogspot.com.au/2010/05/pinvokestackimbalance-in-net-40i-beg.html http://codenition.blogspot.com.au/2010/05/pinvokestackimbalance-in-net-40i-beg.html

显然 pinvokestackimbalance 在 .NET 3.5 中基本上被忽略了,所以问题仍然存在,它只是不会使我的应用程序崩溃。

将以下代码添加到 App.Config 会导致 .NET 在转换回托管代码时修复堆栈。虽然性能受到一点影响,但可以解决问题。

虽然这确实解决了问题,但我想知道我的 UnmanagedFunctionPointer 出了什么问题导致了问题。

<configuration> 
  <runtime> 
    <NetFx40_PInvokeStackResilience enabled="1"/>

编辑:该线程不是重复的,另一个已被删除......


好的,问题是调用约定应该是 StdCall 而不是 Cdecl

这是有道理的,因为通用 J2534 API 文档指定了以下标头。虽然我提供的头文件没有做出这个规范。

extern "C" long WINAPI PassThruConnect
(
unsigned long ProtocolID;
unsigned long Flags
unsigned long *pChannelID
)

其中 WINAPI 也称为 StdCall,而不是大多数 C/C++ 库通常使用的 Cdecl。

.NET 3.5 允许错误的调用约定,并将“修复”堆栈。从 4.0 开始,情况不再如此,并且会引发 PinvokeStackImbalance 异常。

您可以强制 4.0 也修复堆栈,并将以下代码添加到您的 App.Config

<configuration> 
  <runtime> 
    <NetFx40_PInvokeStackResilience enabled="1"/>

或者您可以通过将 Cdecl 更改为 StdCall 来简单地修复您的调用约定:

[UnmanagedFunctionPointer(CallingConvention.StdCall)]
public delegate uint PassThruConnect(uint deviceId, uint protocolId, uint flags, uint baudRate, ref uint channelID);
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 .NET 4.0、3.5 时,UnmanagedFunctionPointer 会导致堆栈溢出 的相关文章

  • 尚未注册类型“IServiceProviderFactory[Autofac.ContainerBuilder]”的服务

    当运行以下命令添加数据库迁移脚本时 出现以下错误 dotnet ef migrations add InitialCreate v o Migrations context MyContext 访问 Microsoft Extensions
  • 通过 SocketCAN 进行 boost::asio

    我正在考虑利用升压阿西奥 http www boost org doc libs 1 49 0 doc html boost asio html从a读取数据套接字CAN http en wikipedia org wiki SocketCA
  • 如何在 DataColumn.Expression 中使用 IF/ELSE 或 CASE?

    我有一个包含 1 列的表 状态 我想添加另一列名为 Action 的列 其值如下 如果 Status Yes 则 Action Go 否则 Action Stop 我使用以下代码添加到 操作 列中 但它不起作用 myDataTable Co
  • 在实体框架拦截器中向 DbScanExpression 添加内部联接

    我正在尝试使用实体框架 CommandTree 拦截器通过 DbContext 向每个查询添加过滤器 为了简单起见 我有两个表 一个称为 User 有两列 UserId 和 EmailAddress 另一个称为 TenantUser 有两列
  • 如何保证对象只有一个线程

    我有以下代码 class Service public void start creates thread which creates window and goes to message loop void stop sends WM C
  • 我如何理解这个 C 类型声明?

    double bar int double double double double 在查看讲座幻灯片时 我发现了留给学生的练习 用简单的英语来说 什么是类型bar在这个 C 声明中 Please帮助我解决这个问题 我什至不知道从哪里开始
  • 平滑滚动.net 表单

    您好 我正在 net 中使用表单 并且在运行时动态添加大量链接标签 我将这些链接标签添加到面板并将该面板添加到 winform 当链接标签的数量增加时 表单会显示一个自动滚动条 垂直 现在 当我使用自动滚动向下滚动时 表单在滚动时不会更新其
  • EF Core 通过完全替换断开集合导航属性的更新

    使用 EF Core 5 0 我有一个 SPA 页面 可以加载Group实体及其集合Employee来自 API 的实体 var groupToUpdate await context Groups Include g gt g Emplo
  • 信号处理程序有单独的堆栈吗?

    信号处理程序是否有单独的堆栈 就像每个线程都有单独的堆栈一样 这是在 Linux C 环境中 来自 Linux 手册页signal 7 http kernel org doc man pages online pages man7 sign
  • 与 Qt 项目的静态链接

    我有一个在 Visual Studio 2010 Professional 中构建的 Qt 项目 但是 当我运行它 在调试或发布模式下 时 它会要求一些 Qt dll 如果我提供 dll 并将它们放入 System32 中 它就可以工作 但
  • 如何在 SqlDataReader.Read() 期间从死锁异常中恢复

    我的 NET 应用程序的事件日志显示 它在从 Sql Server 读取数据时偶尔会出现死锁 这种情况通常非常罕见 因为我们已经优化了查询以避免死锁 但有时仍然会发生 过去 我们在调用ExecuteReader函数在我们的SqlComman
  • 为什么这个没有特殊字符的正则表达式会匹配更长的字符串?

    我正在使用此方法来尝试查找匹配项 例如 Regex Match A2 TS OIL TS OIL RegexOptions IgnoreCase Success 我得到了真实的结果 我很困惑 我认为这应该返回 false 因为模式中没有特殊
  • 如何获取 QTableView 的标题列表?

    我有一个QTableView我的对话框中的对象 我需要访问该表的水平标题并将它们放入QStringList object 尽管进行了大量搜索 但我在 Qt 文档中找不到如何获取此标头列表 编辑 我发现的最接近的地方是this https w
  • 如何在 QTabWidget Qt 中展开选项卡

    我有一个QTabWidget像这个 但我想展开选项卡以 填充 整个小部件宽度 如下所示 我怎样才能做到这一点 我在用Qt 5 3 2 and Qt 创建者 3 2 1 Update 我尝试使用setExpanding功能 ui gt myT
  • 将二进制数据从 C# 上传到 PHP

    我想将文件从 Windows C 应用程序上传到运行 PHP 的 Web 服务器 我知道 WebClient UploadFile 方法 但我希望能够分块上传文件 以便我可以监控进度并能够暂停 恢复 因此 我正在读取文件的一部分并使用 We
  • 如何分析组合的 python 和 c 代码

    我有一个由多个 python 脚本组成的应用程序 其中一些脚本正在调用 C 代码 该应用程序现在的运行速度比以前慢得多 因此我想对其进行分析以查看问题所在 是否有工具 软件包或只是一种分析此类应用程序的方法 有一个工具可以将 python
  • 如何在c的case语句中使用省略号?

    CASE expr no commas ELLIPSIS expr no commas 我在c的语法规则中看到了这样的规则 但是当我尝试重现它时 int test float i switch i case 1 3 printf hi 它失
  • IEnumerable.Except 不起作用,那么我该怎么办?

    我有一个 linq to sql 数据库 非常简单 我们有 3 个表 项目和用户 有一个名为 User Projects 的连接表将它们连接在一起 我已经有了一个获得的工作方法IEnumberable
  • 了解使用 Windows 本机 WPF 客户端进行 ADFS 登录

    我已经阅读了大量有关 ADFS 与 NodeJS Angular 或其他前端 Web 框架集成以及一般流程如何工作的文献 并通过 Auth0 Angular 起始代码构建了概念证明 但我不明白如何这可以与本机 WPF Windows 应用程
  • 抛出 Java 异常时是否会生成堆栈跟踪?

    这是假设我们不调用 printstacktrace 方法 只是抛出和捕获 我们正在考虑这样做是为了解决一些性能瓶颈 不 堆栈跟踪是在构造异常对象时生成的 而不是在抛出异常对象时生成的 Throwable 构造函数调用 fillInStack

随机推荐

  • 使用 dplyr::filter() 删除 NA 观测值

    我的数据如下所示 library tidyverse df lt tribble a b c 1 2 3 1 NA 3 NA 2 3 我可以删除所有NA观察与drop na df gt drop na 或者全部删除NA单列中的观察值 a例如
  • 调用 Isolate::New() 后执行位置 0x0000000000000000 时发生访问冲突

    我似乎无法弄清楚如何启动 V8 我有这个代码 if V8Initialized v8 V8 InitializeICU v8 V8 InitializeExternalStartupData x86 this loads ok I chec
  • HTML5可以指定滚动条图像吗?

    我需要显示自定义滚动条 如果可能的话 我想避免使用 jQuery 插件 那么我可以用 HTML5 和 CSS3 来做这样的事情吗 myScrollableBox width 200px height 500px Display scroll
  • 如何根据草图值计算 TextView 的 letterSpacing?

    在设计中 我有一个文本字段 文本大小为 16 字符间距为 0 6 但是 如果我设置这个值android letterSpacing的属性TextView间距将比设计时大得多 那么 将sketch值转换为android值的方法是什么呢 根据
  • 动态调整 SVG 多边形的大小和拖动

    我正在努力寻找一种用鼠标动态调整 svg 多边形大小和拖动多边形的方法 不幸的是 jQueryUi 不适用于 svg 元素 我还检查了拉斐尔库 但找不到任何有关如何实现这一点的文档 片段 除了使用 SVG 之外 还有其他方法可以动态调整多边
  • Julia 中的虚拟变量

    在 R 中 有一个很好的功能 可以针对分类变量的每个级别使用虚拟变量运行回归 例如自动将 R 因子扩展为每个因子水平的 1 0 指标变量的集合 https stackoverflow com questions 5048638 automa
  • 使用 jquery 获取自定义标签值

  • 在 pandasql 中使用字典值

    我有一本字典 其中包含值的数据帧 如下所示 mydict demand demand df supply supply df prod prod df 然后我正在使用pandasql模块来执行简单的查询 query SELECT FROM
  • Linux 变量 $BASH_SUBSHELL 与 $SLVL 之间的区别

    我对两者感到困惑 虽然 BASH SUBSHELL 内部变量指示子 shell 的嵌套级别 但 SLVL 变量显示子 shell 内没有任何更改 它究竟意味着什么 如果我在另一个 shell 中打开一个 shell 则 SLVL 的值会增加
  • 如何通过 Spring 发送电子邮件

    在我的 JavaFx 项目中 我像这样注入控制器 效果很好 Configuration public class AppFactory Bean public HomeController homeController throws IOE
  • 从数据库恢复 TeamCity 项目

    是否可以从现有数据库恢复 TeamCity 项目设置 我为 TeamCity 数据层和应用程序层设置了单独的服务器 TeamCity 应用程序服务器已损坏 我正在尝试从现有数据层恢复它 我正在使用 TeamCity 5 1 2 有任何想法吗
  • javascript中一串一位数字的总和?

    我正在尝试编写一个脚本 添加字符串的左侧并根据右侧对其进行验证 例如 var left 12345 var right 34567 我需要执行某种求和函数 将 1 2 3 4 5 加起来 并检查它是否等于 3 4 5 6 7 我只是不知道该
  • MultipartEntityBuilder 将图片发送到 Rail 服务器

    我正在尝试发送MultipartEntityBuilder 到我的 Rails 服务器 但是 当我尝试构建它时 它崩溃并给出错误 03 25 09 44 50 001 W System err java util concurrent Ex
  • TWRequest 是否适用于 Twitter 流 API?

    我正在尝试制作一个基本的 iPhone 应用程序来显示附近的推文 我使用 TWRequest 对象通过 twitter 搜索 API 来完成此任务 不幸的是 我实际上想使用 GPS 坐标在地图上标记推文 而搜索 api 似乎不会以比城市名称
  • 错误:android studio 中的任务“:app:dexDebug”执行失败

    我面临未知类型的错误 错误 任务 app dexDebug 执行失败 com android ide common process ProcessException org gradle process internal ExecExcep
  • jQuery 函数

    像这样编写 jQuery 函数有什么用 function myFunction 我的意思是为什么将函数包装在 中 我认为你的意思是这样的 function 这是以下内容的简写 document ready function 它的作用是注册一
  • 如何使“.innerText”忽略不可见元素的不可见子元素?

    测试代码结果如下 div 0 innerText aaaaa zzzzz div 1 innerText aaaaa invisible zzzzz 我怎样才能强迫innerText给出相同的结果div 1 因为它给出了div 0 我尝试附
  • 如何在 Ember CLI 应用程序中升级 Ember 版本?

    假设我上周创建了这个 Ember 应用程序 ember new shop cd shop ember install addon ember cli scaffold ember g scaffold product name string
  • 将三个整数编码为单个整数

    我必须将 3 个数字编码为同一个整数 我有这 3 个测量值 uint256 carLength uint256 carWidth uint256 carDepth 我想将这 3 个数字编码为同一个整数 并且可以解码 我的问题是我在这么低的水
  • 使用 .NET 4.0、3.5 时,UnmanagedFunctionPointer 会导致堆栈溢出

    我在点击处理程序中有一个简单的函数 它有一个 try catch 块 如果我在此 try catch 块中抛出异常 它会成功捕获异常 如果我在抛出异常之前调用非托管 DLL 则异常不会被处理且不会被捕获 未修改的 DLL 调用正在做什么 可