简体   繁体   中英

how to debug “Invalid parameter passed to C runtime function”?

Background

I've got about a terabyte of files with raw data, with a relatively small subset of labelled data. I've written c++ code (calling some ancient MSVC++2003 code I heavily modified to get it to compile on recent compilers) to aggregate the annotated data slices.

A big part of that labelled data is concentrated in one file, but that file turns out to be the one where my program crashes.

Problem

I'm getting

Invalid parameter passed to C runtime function.
Invalid parameter passed to C runtime function.
terminate called after throwing an instance of 'int'

In my Qt output window, and windows tells me the same in a popup, but at this point it's too late to get any useful info out of the executable / debugger it seems (though I'm not experienced at all with Qt's debugger).

What I have tried

I've googled all over and found plenty of people with this error message but it's so generic that none of their issues could be the same as mine, and there's such a long list of different C runtime functions that sifting through all of them is slow and it doesn't seem to help.

My question

"Find a man a bug, and you help him for a day. Teach a man to debug and you help him for a lifetime. Post the way on stackoverflow and you help many men and get a lot of upvotes."

Is there a generic method to find what C runtime function the problem was and what the argument was? Did I miss some fancy debugger features? Is there anything else you could recommend or info I could provide?

I'd hope to get a catch-all answer to this to help everyone with this problem, not just me, but I'll be glad if I'm helped too of course.

Specific to my problem:

My stack trace is as follows:

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

and gdb can't get a better trace it seems (anything I try to do with it gets me a timeout error).

After trying a couple more functions just to be sure everything gave a timeout trying "backtrace" once again did give me a result. I guess I just never put this much time in gdb after it timeouting on me once.

That said, I might be able to find something with this new info. Consider my specific problem closed, but my general point is still valid I believe: I've now found the function with the problem (I think), but not why it is a problem, nor what the invalid parameter is. Even better, I've traced it to a line where it says "throw 1". So now I'm assuming windows/Qt translates that to the "invalid parameter". But it's not true.

It can just be some bad code, it does not even need to be a C function, and nothing needs to be wrong with your parameters.

...

#17 0x00c17d72 in libstdc++-6!.cxa_throw () from C:\\Qt\\5.5\\mingw492_32\\bin\\libstdc++-6.dll No symbol table info available. ...

Since the log is printed to the debug console then it should be reported by OutputDebugStringA function. You can place a breakpoint on the function to see who results in that log. To place a breakpoint on a function you can Ctrl+B in Visual Studio and enter function name:

在此处输入图片说明

But this might not work, or you may have too many other messages logged using OutputDebugStringA . Usually Invalid parameter passed to C runtime function is reported by _invalid_parameter , so, you may as well try to place a breakpoint on _invalid_parameter function. This might not work as well because it could be reported from some other system dll that your process links to: ntdll.dll , KernelBase.dll etc. To place a breakpoint on a function exported by a dll you need to use: <dll>!<exportname> :

_invalid_parameter
ntdll.dll!__invalid_parameter
KernelBase.dll!__invalid_parameter
msvcrt.dll!__invalid_parameter
ucrtbase.dll!__invalid_parameter

All of these are different functions and you can see their addresses:

在此处输入图片说明

In my case only when I set a breakpoint on ntdll.dll!__invalid_parameter I was able to see backtrace and the log message was caused by GetAdaptersAddresses winapi . The reason breakpoint on OutputDebugStringA wasn't helpful was because the log was printed through DbgPrint api. Placing breakpoint on DbgPrint works in this case.

In Visual Studio 2017 at least, you can hit CTRL+B and add a function breakpoint on _invalid_parameter . This will stop your program at the point where the message would have been logged, which will let you find the offending function in the call stack. It will work even if someone else's code undoes your call to _CrtSetReportMode() .

Things I learned from this question (and that might help people searching for this question) :

  1. Turns out that this error could be traced back to a line of code saying
    throw 1;
    This means It can just be some bad code, it does not even need to be a C function, and nothing needs to be wrong with your parameters. Searching your code and libraries' source for "throw"
  2. Turns out that getting timeouts on gdb are not an indicator of anything. Keep trying things and retrying and maybe at one time you might get a stack trace.

Personally, on a Linux terminal, I use gcc for compiling and gdb for debugging. To compile a program with debugging options using gcc, you simply have to add a -g to your other flags. Ex: gcc file.c -o file -std=c99 -g . You can then type gdb file and you enter into an interactive debugger. Among other helpful things, you can run the program, call functions and insert breakpoints. For a full and well explained usage go to this website- http://www.tutorialspoint.com/gnu_debugger/index.htm

I ran into this same error message "Invalid parameter..." while debugging a windows driver. The technique on this page, even though for Windows and not exactly addressing for this question, might be useful to someone who is looking for this particular error message. IOW HTH..

http://dennisyurichev.blogspot.com/2013/05/warning-invalid-parameter-passed-to-c.html

So in summary you have to narrow down specific to your environment where a debug string is being output by possibly a debugging "helper" library function. Once known, set a breakpoint there and then look back up the call stack. IMHO, it's a very clever solution to what can be a tough location to find.

If you are using MinGW only (no Visual Studio build stuff). Try compiling your application for the Console subsystem instead of the Windows subsystem when building debug version. In that case when an invalid argument is passed to a C function the function will fail and will trip your error handling code instead of the standard library's error box which should give you better control over what is happening.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM