如何解决sprintf参数类型错误导致程序崩溃

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何解决sprintf参数类型错误导致程序崩溃相关的知识,希望对你有一定的参考价值。

  sprintf本身不会崩溃,当然你犯2另说,比如%s的参数,你要传一个int. 我们的dump的sprintf从来都没有出过问题,检查下代码吧
  打个比方,你做了一个功能,在崩溃的时候捕获异常,然后记录日志,然后抛消息给系统自动重启进程。 问题是你在记录日志的时候又崩溃了,你说这个时候系统应该咋给办?无限死循环直到死机吗?
像sprintf这种能完全能通过【肉眼解决】的都不是问题!!!

怕的是内存越界啊之类的,你某些地方少写了边界检查的,或者你用第三方库,里面有BUG造成的,这种才是应该重点考虑的
参考技术A 添加错误处理就不会崩溃了

类型的已垃圾回收委托进行了回调。这可能会导致应用程序崩溃损坏和数据丢失。向非托管代码传递委托时,托管应用程序必须让这些委托保持活动状态,直到确信不会再次调用它们的问题的解决方法

《对“XXX::Invoke”类型的已垃圾回收委托进行了回调。这可能会导致应用程序崩溃、损坏和数据丢失。向非托管代码传递委托时,托管应用程序必须让这些委托保持活动状态,直到确信不会再次调用它们》的问题的解决方法

源程序部分代码如下

[csharp] view plain copy
 
  1. /// <summary>  
  2. /// 安装钩子的函数  
  3. /// </summary>  
  4. /// <param name="idHook"></param>  
  5. /// <param name="lpfn"></param>  
  6. /// <param name="hInstance"></param>  
  7. /// <param name="threadId"></param>  
  8. /// <returns></returns>  
  9. [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]  
  10. public static extern int SetWindowsHookEx(int idHook, HookProc lpfn, IntPtr hInstance, int threadId);  
  11. /// <summary>  
  12. /// 卸下钩子的函数  
  13. /// </summary>  
  14. /// <param name="idHook"></param>  
  15. /// <returns></returns>  
  16. [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]  
  17. public static extern bool UnhookWindowsHookEx(int idHook);  
  18. /// <summary>  
  19. /// 下一个钩挂的函数  
  20. /// </summary>  
  21. /// <param name="idHook"></param>  
  22. /// <param name="nCode"></param>  
  23. /// <param name="wParam"></param>  
  24. /// <param name="lParam"></param>  
  25. /// <returns></returns>  
  26. [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]  
  27. public static extern int CallNextHookEx(int idHook, int nCode, Int32 wParam, IntPtr lParam);  
  28.   
  29. //定义了一个委托  
  30. public delegate int HookProc(int nCode, Int32 wParam, IntPtr lParam);  
  31.   
  32.   
  33. //定义一个代理  
  34. HookProc KeyboardHookDelegate;  
  35.   
  36.   
  37. /// <summary>  
  38. /// 创建钩子  
  39. /// </summary>  
  40. public void SetHook()  
  41. {  
  42.     KeyboardHookDelegate = new HookProc(KeyboardHookProc);  
  43.     Process cProcess = Process.GetCurrentProcess();  
  44.     ProcessModule cModule = cProcess.MainModule;  
  45.     var mh = GetModuleHandle(cModule.ModuleName);  
  46.     hHook = SetWindowsHookEx(WH_KEYBOARD_LL, KeyboardHookDelegate, mh, 0);  
  47. }  
  48.   
  49.   
  50. public void UnHook()  
  51. {  
  52.     UnhookWindowsHookEx(hHook);  
  53. }  
  54.   
  55.   
  56. /// <summary>  
  57. /// 键盘钩子进程  
  58. /// </summary>  
  59. /// <param name="nCode"></param>  
  60. /// <param name="wParam"></param>  
  61. /// <param name="lParam"></param>  
  62. /// <returns></returns>  
  63. private int KeyboardHookProc(int nCode, Int32 wParam, IntPtr lParam)  
  64. {  
  65. //...  
  66. //每到这里就报错  
  67. return CallNextHookEx(hHook, nCode, wParam, lParam);  
  68. }  


经过一番搜索,
可能的原因是定义的委托给垃圾回收机制给回收了,这导致报告如题错误,网上很多朋友们说,将委托定义为成员变量,可是我的就是成员变量还是出错,还有的说要定义代理,可我使用的就是代理了,还有的朋友们说要定义为静态的,但是似乎在我这里全部都无济于事,与似乎我我分析了一下,
终于解决了,修改如下

[csharp] view plain copy
 
  1. public void SetHook()  
  2. {  
  3.     KeyboardHookDelegate = new HookProc(KeyboardHookProc);  
  4.     IntPtr intPtr = Marshal.GetHINSTANCE(System.Reflection.Assembly.GetExecutingAssembly().GetModules()[0]);  
  5.     hHook = SetWindowsHookEx(WH_KEYBOARD_LL, KeyboardHookDelegate, intPtr, 0);  
  6. }  



原来是获得当前进程,然后获取当前进程的MainModule,再获取MainModule的ModuleName
最后用反射获取到当前程序集,如果程序没有关闭程序集一直是存在的,然后就解决了。
也许我上述理解可能有误,如果理解有误,还望大神斧正。

以上是关于如何解决sprintf参数类型错误导致程序崩溃的主要内容,如果未能解决你的问题,请参考以下文章

sprintf函数用法详解

3d max 2016修改渲染设置参数导致程序崩溃怎么办?

如何解决错误:无法调用类型为 `......` 的参数列表类型为 `...` 的初始化程序?

sprintf转换类型和参数类型必须一致么

接口测试常见bug

Android Studio 中的 React Native 应用程序:导致参数类型不匹配