I am resurrecting old code from a few years ago, and I unfortunately have little documentation as to how it was compiled and what environment it was built in. At this point, I have successfully gotten it to build, but there are errors at execution, specifically an unhandled exception error on a memory access. The error text is:

Unhandled exception at 0x0002cb80 in Lab4_2008.exe: 0xC0000005: Access violation reading location 0x0002cb80.

It is always the same memory address that is the location, and when I break out of the program it takes me to the following function:

UINT   
CHapticThread::GetClosestPossiblePeriod(UINT period)
{
    TIMECAPS    timecaps;
    MMRESULT    mmRes;

    mmRes = ::timeGetDevCaps( &timecaps, sizeof(TIMECAPS) );
    assert(mmRes == TIMERR_NOERROR);

    if ( period < timecaps.wPeriodMin )
        return timecaps.wPeriodMin;

    if ( period > timecaps.wPeriodMax )
        return timecaps.wPeriodMax;

    return period;
}

Specifically, it's the call to timeGetDevCaps that is where the error occurs. I don't pretend to know all the intricacies of how pointers work - I am a mechanical engineer who has picked up some programming. However, that's the only thing that I can think of because of the association with an address. Any suggestions?

Dani AI

Generated

This crash almost always means the fault is a symptom, not the root cause. The fact that a small standalone test of the same call ran fine (as reported) and that recommended breaking at the call are both strong indicators: some earlier code is corrupting stack or heap state and the problem only shows up when execution enters system code. Treat the call into the OS library as the first reproducible symptom and focus on catching the corruption earlier.

Practical checklist (in order):

  • Run under the debugger and make it break on first-chance C++ exceptions. Put a breakpoint on the line immediately before the system call, then step over and step into to see whether control crashes on entry or immediately after return. Inspect ESP/RSP and the saved return address on the stack.

  • Turn on the MSVC debug heap and break on a specific allocation number to catch corruptors at the point of allocation:

    _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
    _CrtSetBreakAlloc(1234);
  • Use Page Heap (gflags) to make heap corruption crash where it happens:

    gflags /p /enable Lab4_2008.exe /full

    Disable it after testing with /disable.

  • Run a runtime memory tool (Application Verifier or Dr. Memory) to detect heap overruns, use-after-free and heap metadata corruption.

Common causes to inspect: stack-buffer overruns, writes past array bounds in other threads, use-after-free, mismatched calling conventions or structure packing when passing data across module boundaries, and different CRT allocators between modules. Also check for corrupted function pointers or vtable slots if the crash address looks like an invalid jump (as suggested).

Isolation strategy: build a debug, unoptimized version with runtime checks and single-thread the code if possible. Add simple guard patterns (fill buffers with 0xAA) and assert integrity before the system call. Incrementally re-enable modules until the crash returns — that will localize the corruptor.

Recommended Answers

All 6 Replies

well, show us your timeGetDevCaps function for start :)

I think it's just this.
http://msdn.microsoft.com/en-us/library/ms713416.aspx

But the execution address and the read address being the same seems kinda odd to me.

If that really is the case, then the code took a flying jump off a cliff (typically, following an uninitialised function pointer). The "stack" at that point is pretty much meaningless, so I wouldn't put too much store in that.

Putting a breakpoint at the call, then trying "step over" would give more concrete information as to whether this was the cause, or merely the last bit of salvageable stack from the disaster which follows.

Sorry, you lost me on the execution address and the read address being the same. The attempted read address is repeated twice, if that's what you are referring to, but that's what happened everywhere else I saw the error.

Salem is correct - the timeGetDevCaps function is a part of the winmm.lib file, which means that I can't see the code and don't know how the constructor initializes everything.

The same means this:
Unhandled exception at 0x0002cb80 in Lab4_2008.exe: 0xC0000005: Access violation reading location 0x0002cb80.

But did you do as I suggest, put a breakpoint on mmRes = ::timeGetDevCaps( &timecaps, sizeof(TIMECAPS) ); then step over it?

It that works, then the problem is somewhere else.

Well I tried putting your stuff in a standalone program and it works without any difficulties.

It is possible that you have code elsewhere which is corrupting your stack, and the problem shows up when you call timeGetDevCaps. Have you considered running your code through a memory checking tool ?

> Well I tried putting your stuff in a standalone program and it works without any difficulties.
Yeah, tests like that pretty much nail the "it's a bug elsewhere" argument.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.