Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to debug "Invalid parameter passed to C runtime function"?

Tags:

c++

debugging

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. ...

like image 980
Joran Dox Avatar asked May 01 '16 15:05

Joran Dox


3 Answers

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:

enter image description here

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:

enter image description here

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.

like image 189
Pavel P Avatar answered Oct 24 '22 07:10

Pavel P


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().

like image 11
mcgoo Avatar answered Oct 24 '22 08:10

mcgoo


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.
like image 2
Joran Dox Avatar answered Oct 24 '22 08:10

Joran Dox