如何解决sprintf参数类型错误导致程序崩溃
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何解决sprintf参数类型错误导致程序崩溃相关的知识,希望对你有一定的参考价值。
sprintf本身不会崩溃,当然你犯2另说,比如%s的参数,你要传一个int. 我们的dump的sprintf从来都没有出过问题,检查下代码吧打个比方,你做了一个功能,在崩溃的时候捕获异常,然后记录日志,然后抛消息给系统自动重启进程。 问题是你在记录日志的时候又崩溃了,你说这个时候系统应该咋给办?无限死循环直到死机吗?
像sprintf这种能完全能通过【肉眼解决】的都不是问题!!!
怕的是内存越界啊之类的,你某些地方少写了边界检查的,或者你用第三方库,里面有BUG造成的,这种才是应该重点考虑的 参考技术A 添加错误处理就不会崩溃了
类型的已垃圾回收委托进行了回调。这可能会导致应用程序崩溃损坏和数据丢失。向非托管代码传递委托时,托管应用程序必须让这些委托保持活动状态,直到确信不会再次调用它们的问题的解决方法
《对“XXX::Invoke”类型的已垃圾回收委托进行了回调。这可能会导致应用程序崩溃、损坏和数据丢失。向非托管代码传递委托时,托管应用程序必须让这些委托保持活动状态,直到确信不会再次调用它们》的问题的解决方法
源程序部分代码如下
- /// <summary>
- /// 安装钩子的函数
- /// </summary>
- /// <param name="idHook"></param>
- /// <param name="lpfn"></param>
- /// <param name="hInstance"></param>
- /// <param name="threadId"></param>
- /// <returns></returns>
- [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
- public static extern int SetWindowsHookEx(int idHook, HookProc lpfn, IntPtr hInstance, int threadId);
- /// <summary>
- /// 卸下钩子的函数
- /// </summary>
- /// <param name="idHook"></param>
- /// <returns></returns>
- [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
- public static extern bool UnhookWindowsHookEx(int idHook);
- /// <summary>
- /// 下一个钩挂的函数
- /// </summary>
- /// <param name="idHook"></param>
- /// <param name="nCode"></param>
- /// <param name="wParam"></param>
- /// <param name="lParam"></param>
- /// <returns></returns>
- [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
- public static extern int CallNextHookEx(int idHook, int nCode, Int32 wParam, IntPtr lParam);
- //定义了一个委托
- public delegate int HookProc(int nCode, Int32 wParam, IntPtr lParam);
- //定义一个代理
- HookProc KeyboardHookDelegate;
- /// <summary>
- /// 创建钩子
- /// </summary>
- public void SetHook()
- {
- KeyboardHookDelegate = new HookProc(KeyboardHookProc);
- Process cProcess = Process.GetCurrentProcess();
- ProcessModule cModule = cProcess.MainModule;
- var mh = GetModuleHandle(cModule.ModuleName);
- hHook = SetWindowsHookEx(WH_KEYBOARD_LL, KeyboardHookDelegate, mh, 0);
- }
- public void UnHook()
- {
- UnhookWindowsHookEx(hHook);
- }
- /// <summary>
- /// 键盘钩子进程
- /// </summary>
- /// <param name="nCode"></param>
- /// <param name="wParam"></param>
- /// <param name="lParam"></param>
- /// <returns></returns>
- private int KeyboardHookProc(int nCode, Int32 wParam, IntPtr lParam)
- {
- //...
- //每到这里就报错
- return CallNextHookEx(hHook, nCode, wParam, lParam);
- }
经过一番搜索,
可能的原因是定义的委托给垃圾回收机制给回收了,这导致报告如题错误,网上很多朋友们说,将委托定义为成员变量,可是我的就是成员变量还是出错,还有的说要定义代理,可我使用的就是代理了,还有的朋友们说要定义为静态的,但是似乎在我这里全部都无济于事,与似乎我我分析了一下,
终于解决了,修改如下
- public void SetHook()
- {
- KeyboardHookDelegate = new HookProc(KeyboardHookProc);
- IntPtr intPtr = Marshal.GetHINSTANCE(System.Reflection.Assembly.GetExecutingAssembly().GetModules()[0]);
- hHook = SetWindowsHookEx(WH_KEYBOARD_LL, KeyboardHookDelegate, intPtr, 0);
- }
原来是获得当前进程,然后获取当前进程的MainModule,再获取MainModule的ModuleName
最后用反射获取到当前程序集,如果程序没有关闭程序集一直是存在的,然后就解决了。
也许我上述理解可能有误,如果理解有误,还望大神斧正。
以上是关于如何解决sprintf参数类型错误导致程序崩溃的主要内容,如果未能解决你的问题,请参考以下文章