如何调试"传递给C运行时函数的无效参数"?

Jor*_*Dox 19 c++ debugging

背景

我有大约1TB的原始数据文件,标记数据的子集相对较小.我编写了c ++代码(调用了一些古老的MSVC++ 2003代码,我对其进行了大量修改以使其在最近的编译器上进行编译)来聚合带注释的数据切片.

标记数据的很大一部分集中在一个文件中,但该文件最终成为程序崩溃的文件.

问题

我越来越

Invalid parameter passed to C runtime function.
Invalid parameter passed to C runtime function.
terminate called after throwing an instance of 'int'
Run Code Online (Sandbox Code Playgroud)

在我的Qt输出窗口中,Windows在弹出窗口中告诉我相同的内容,但此时从可执行文件/调试器中获取任何有用的信息为时已晚(尽管我对Qt的调试器没有任何经验).

我试过了什么

我已经google了一遍,发现很多人都有这个错误消息,但它是如此通用,以至于他们的问题都没有和我的一样,并且有很长的不同C运行时函数列表,筛选所有这些函数很慢它似乎没有帮助.

我的问题

"找一个男人一个虫子,你帮助他一天.教一个男人调试,你帮助他一辈子.在stackoverflow上发布你的方式,你可以帮助很多男人并得到很多赞成."

是否有一个通用的方法来查找问题的C运行时函数以及参数是什么?我错过了一些花哨的调试器功能吗?还有什么可以推荐或我可以提供的信息吗?

我希望得到一个全能的答案,以帮助每个人解决这个问题,而不仅仅是我,但如果我当然得到帮助,我会很高兴.

具体到我的问题:

我的堆栈跟踪如下:

0 ntdll!DbgBreakPoint 0x7727000d
1 ntdll!DbgUiRemoteBreakin 0x772ff156
2 ?? 0x6f06eaa1
3 KERNEL32!BaseThreadInitThunk 0x7501338a
4 ntdll!RtlInitializeExceptionChain 0x77299902
5 ntdll!RtlInitializeExceptionChain 0x772998d5
6 ??

并且gdb似乎无法获得更好的跟踪(我尝试用它做的任何事都会给我一个超时错误).

在尝试了几个函数之后,为了确保一切都超时,尝试"回溯"再一次给了我一个结果.我想我曾经把时间浪费在我身上,从来没有把这么多时间花在gdb上.

也就是说,我可能能够找到这个新信息的东西.考虑我的具体问题已经关闭,但我的一般观点仍然有效我相信:我现在已经找到了问题的函数(我认为),但不是为什么它是一个问题,也不是无效参数是什么.更好的是,我已经将它追溯到一条线,上面写着"扔1".所以现在我假设windows/Qt将其转换为"无效参数".但事实并非如此.

它可能只是一些不好的代码,它甚至不需要是一个C函数,并且您的参数不需要出错.

...

#17 0x00c17d72在libstdc ++中 - 6!.cxa_throw()来自C:\ Qt\5.5\mingw492_32\bin\libstdc ++ - 6.dll没有可用的符号表信息....

Pav*_*l P 11

由于日志已打印到调试控制台,因此应按OutputDebugStringA功能进行报告。您可以在函数上放置一个断点,以查看谁在该日志中生成结果。要在函数上放置断点,可以Ctrl+B在Visual Studio中输入函数名称:

在此处输入图片说明

但这可能不起作用,或者您可能使用记录了太多其他消息OutputDebugStringA。通常Invalid parameter passed to C runtime function_invalid_parameter报告,因此,您也可以尝试在_invalid_parameter函数上放置一个断点。这可能无法正常工作,因为它可能会从您的进程链接到的其他系统dll中报告ntdll.dllKernelBase.dll等等。要在dll导出的函数上放置断点,您需要使用<dll>!<exportname>

_invalid_parameter
ntdll.dll!__invalid_parameter
KernelBase.dll!__invalid_parameter
msvcrt.dll!__invalid_parameter
ucrtbase.dll!__invalid_parameter
Run Code Online (Sandbox Code Playgroud)

所有这些都是不同的功能,您可以看到它们的地址:

在此处输入图片说明

就我而言,仅当我在其中设置断点时,ntdll.dll!__invalid_parameter我才能看到回溯,并且日志消息是由GetAdaptersAddresseswinapi引起的。断点OutputDebugStringA没有用的原因是因为日志是通过DbgPrintapi 打印的。DbgPrint在这种情况下,将断点放置在工程上。


小智 8

至少在Visual Studio 2017中,您可以按CTRL + B并在上添加函数断点_invalid_parameter。这将使您的程序停在记录消息的位置,这将使您在调用堆栈中找到有问题的功能。即使其他人的代码撤消了您对的调用,它也将起作用_CrtSetReportMode()


Wil*_*cke 1

就我个人而言,在 Linux 终端上,我使用 gcc 进行编译,使用 gdb 进行调试。要使用 gcc 编译带有调试选项的程序,您只需将 a 添加-g到其他标志即可。前任:gcc file.c -o file -std=c99 -g。然后您可以键入gdb file并进入交互式调试器。除其他有用的功能外,您还可以运行程序、调用函数和插入断点。有关完整且解释良好的用法,请访问此网站 - http://www.tutorialspoint.com/gnu_debugger/index.htm