- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
我在具有 try catch block 的点击处理程序中有一个简单的函数。如果我在此 try catch block 中抛出异常,它会成功捕获异常。
如果我在抛出异常之前调用非托管 DLL,则异常未处理且未被捕获。
未管理的 DLL 调用在做什么,可能会破坏我的程序异常处理?
如果我在 Debug模式下运行程序,即使所有异常都未选中“异常中断”,它也会捕获异常。应用程序不会崩溃并按预期运行。
如果我以“不调试的方式启动”运行程序并在它崩溃时点击调试,我会收到以下错误“堆栈 cookie 检测代码检测到基于堆栈的缓冲区溢出”
编辑:看起来堆栈溢出破坏了异常处理
我附上了一个导致崩溃的简化程序。
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);
更新
如果我用以下代码替换对 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 在另一个线程中,我没有使用 lock(syncLock)。现在一切都在一个线程中,但是在 BackgroundWorker 中运行时也会发生同样的崩溃。
更新 #2 问题已半解决
好的,所以我一个一个地回滚我的提交,直到它起作用。改变的是我从 .NET 3.5 到 .NET 4.0
无论是否附加调试器,.NET 3.5 都不会崩溃。如果未附加调试器,.NET 4.0 会崩溃。为了排除我的代码中的错误,我只是删除了日志的 ConcurrentQueue(我使用的唯一 4.0 功能)并将我当前的代码库转换回 3.5,我没有收到此错误。
为了 100% 确定这是 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
显然 pinvokestackimbalance 在 .NET 3.5 中基本上被忽略了,所以问题仍然存在,它只是没有让我的应用程序崩溃。
将以下代码添加到 App.Config 会导致 .NET 在转换回托管代码时修复堆栈。性能下降很小,但可以解决问题。
虽然这确实解决了问题,但我想知道我的 UnmanagedFunctionPointer 有什么问题首先导致了问题。
<configuration>
<runtime>
<NetFx40_PInvokeStackResilience enabled="1"/>
编辑:这个线程不是重复的,另一个被删除了......
最佳答案
好的,问题是调用约定应该是 StdCall 而不是 Cdecl
这是有道理的,因为通用 J2534 API 文档指定了以下 header 。虽然我提供的头文件没有做这个规范。
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);
关于c# - UnmanagedFunctionPointer 在使用 .NET 4.0、3.5 时会导致 stackoverflow,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40077376/
我正在尝试使用 Spark 从 Cassandra 读取数据。 DataFrame rdf = sqlContext.read().option("keyspace", "readypulse
这是代码: void i_log_ (int error, const char * file, int line, const char * fmt, ...) { /* Get erro
我必须调试一个严重依赖 Gtk 的程序。问题是由于某些原因,在使用 GtkWindow 对象时开始出现许多运行时警告。问题是,即使 Gtk 提示严重错误,它也不会因这些错误而中止。我没有代码库的更改历
我正在尝试从已有效编译和链接的程序中检索二进制文件。我已经通过 GL_PROGRAM_BINARY_LENGTH 收到了它的长度。该文档说有两个实例可能会发生 GL_INVALID_OPERATION
我有一个托管在 Azure 环境中的服务。我正在使用控制台应用程序使用该服务。这样做时,我得到了异常: "The requested service, 'http://xxxx-d.yyyy.be/S
我有以下代码,它被 SEGV 信号杀死。使用调试器表明它被 main() 中的第一个 sem_init() 杀死。如果我注释掉第一个 sem_init() ,第二个会导致同样的问题。我试图弄清楚是什么
目前我正在编写一个应用程序(目标 iOS 6,启用 ARC),它使用 JSON 进行数据传输,使用核心数据进行持久存储。 JSON 数据由 PHP 脚本通过 json_encode 从 MySQL 数
我对 Xamarin.Forms 还是很陌生。我在出现的主页上有一个非常简单的功能 async public Task BaseAppearing() { if (UserID
这是我的代码的简化版本。 public class MainActivity extends ActionBarActivity { private ArrayList entry = new Arr
我想弄明白为什么我的两个 Java 库很难很好地协同工作。这是场景: 库 1 有一个类 A,其构造函数如下: public A(Object obj) { /* boilerplate */ } 在以
如果网站不需要身份验证,我的代码可以正常工作,如果需要,则在打印“已创建凭据”后会立即出现 EXC_BAD_ACCESS 错误。我不会发布任何内容,并且此代码是直接从文档中复制的 - 知道出了什么问题
我在使用 NSArray 填充 UITableView 时遇到问题。我确信我正在做一些愚蠢的事情,但我无法弄清楚。当我尝试进行简单的计数时,我得到了 EXC_BAD_ACCESS,我知道这是因为我试图
我在 UITableViewCell 上有一个 UITextField,在另一个单元格上有一个按钮。 我单击 UITextField(出现键盘)。 UITextField 调用了以下方法: - (BO
我有一个应用程序出现间歇性崩溃。崩溃日志显示了一个堆栈跟踪,这对我来说很难破译,因此希望其他人看到了这一点并能为我指出正确的方向。 基本上,应用程序在启动时执行反向地理编码请求,以在标签中显示用户的位
我开发了一个 CGImage,当程序使用以下命令将其显示在屏幕上时它工作正常: [output_view.layer performSelectorOnMainThread:@selector(set
我正在使用新的 EncryptedSharedPreferences以谷歌推荐的方式上课: private fun securePrefs(context: Context): SharedPrefe
我有一个中继器,里面有一些控件,其中一个是文本框。我正在尝试使用 jquery 获取文本框,我的代码如下所示: $("#").click(function (event) {}); 但我总是得到 nu
在以下场景中观察到 TTS 初始化错误,太随机了。 已安装 TTS 引擎,存在语音集,并且可以从辅助功能选项中播放示例 tts。 TTS 初始化在之前初始化和播放的同一设备上随机失败。 在不同的设备(
maven pom.xml org.openjdk.jol jol-core 0.10 Java 类: public class MyObjectData { pr
在不担心冲突的情况下,可以使用 MD5 作为哈希值,字符串长度最多为多少? 这可能是通过为特定字符集中的每个可能的字符串生成 MD5 哈希来计算的,长度不断增加,直到哈希第二次出现(冲突)。没有冲突的
我是一名优秀的程序员,十分优秀!