Error "Access violation - code c0000005 (!!! second chance !!!)" during I/O to serial

HI,

I am stress testing my serial driver at a high baud rate of 256000 bps by Writing to the serial port and reading data back from the serial port (after configuring the serial port for loop back).

At this baud rate, i am seeing that the system crashes with an error “Access violation - code c0000005 (!!! second chance !!!)” very soon after the test is started. As per the crash analysis, my driver is not involved in the I/O. Below is hte crash dump.

!analyze -v
Connected to Windows 7 7601 x86 compatible target at (Tue Sep 30 21:39:52.338 2014 (UTC + 5:30)), ptr64 FALSE
Loading Kernel Symbols



Loading User Symbols

Loading unloaded module list

*** WARNING: Unable to verify checksum for SerialValidation20.exe
*** ERROR: Symbol file could not be found. Defaulted to export symbols for mfehidk.sys -
*** ERROR: Module load completed but symbols could not be loaded for regflt.sys
*** ERROR: Module load completed but symbols could not be loaded for VME.sys
*** ERROR: Module load completed but symbols could not be loaded for spldr.sys
*** ERROR: Module load completed but symbols could not be loaded for e1c6232.sys
*** ERROR: Module load completed but symbols could not be loaded for hbdrvisr.sys
*** ERROR: Symbol file could not be found. Defaulted to export symbols for mfetdik.sys -
*** ERROR: Symbol file could not be found. Defaulted to export symbols for igdkmd32.sys -
*******************************************************************************
* *
* Bugcheck Analysis *
* *
*******************************************************************************

Unknown bugcheck code (0)
Unknown bugcheck description
Arguments:
Arg1: 00000000
Arg2: 00000000
Arg3: 00000000
Arg4: 00000000

Debugging Details:

PROCESS_NAME: SerialValidati

FAULTING_IP:
Wdf01000!FxContextHeaderInit+1c
8bc31889 8b4e1c mov ecx,dword ptr [esi+1Ch]

EXCEPTION_RECORD: ffffffff – (.exr 0xffffffffffffffff)
ExceptionAddress: 8bc31889 (Wdf01000!FxContextHeaderInit+0x0000001c)
ExceptionCode: c0000005 (Access violation)
ExceptionFlags: 00000000
NumberParameters: 2
Parameter[0]: 00000000
Parameter[1]: 11100f3a
Attempt to read from address 11100f3a

ERROR_CODE: (NTSTATUS) 0xc0000005 - The instruction at 0x%08lx referenced memory at 0x%08lx. The memory could not be %s.

EXCEPTION_CODE: (NTSTATUS) 0xc0000005 - The instruction at 0x%08lx referenced memory at 0x%08lx. The memory could not be %s.

EXCEPTION_PARAMETER1: 00000000

EXCEPTION_PARAMETER2: 11100f3a

READ_ADDRESS: 11100f3a

FOLLOWUP_IP:
Wdf01000!FxContextHeaderInit+1c
8bc31889 8b4e1c mov ecx,dword ptr [esi+1Ch]

BUGCHECK_STR: ACCESS_VIOLATION

DEFAULT_BUCKET_ID: VISTA_DRIVER_FAULT

CURRENT_IRQL: 0

LAST_CONTROL_TRANSFER: from 8bc318f9 to 8bc31889

STACK_TEXT:
ad0d7a68 8bc318f9 87246f90 87246ec8 87439010 Wdf01000!FxContextHeaderInit+0x1c
ad0d7a7c 8bc31055 87246ec8 00000002 87442010 Wdf01000!FxObjectAndHandleHeaderInit+0x39
ad0d7aa0 8bc361db 87439010 11100f1e 87442010 Wdf01000!FxDevice::AllocateRequestMemory+0x127
ad0d7ac4 8bc36849 87439010 11100f1e 871f1e48 Wdf01000!FxRequest::_CreateForPackage+0x1e
ad0d7b00 8bc30bc2 871f1e48 87439910 871f1e48 Wdf01000!FxPkgIo::Dispatch+0x297
ad0d7b28 8bc30a33 87439910 871f1e48 8720ed78 Wdf01000!FxDevice::Dispatch+0x155
ad0d7b44 83250c29 87439910 871f1e48 871f1e48 Wdf01000!FxDevice::DispatchWithLock+0x77
ad0d7b5c 83445b29 871f1e48 871f1edc 8720ed78 nt!IofCallDriver+0x63
ad0d7b7c 8347e516 87439910 8720ed78 00000001 nt!IopSynchronousServiceTail+0x1f8
ad0d7c08 832578fa 87439910 871f1e48 00000000 nt!NtReadFile+0x644
ad0d7c08 778e7094 87439910 871f1e48 00000000 nt!KiFastCallEntry+0x12a
006af1ac 778e62c4 75b3cfde 0000001c 0000002c ntdll!KiFastSystemCallRet
006af1b0 75b3cfde 0000001c 0000002c 00000000 ntdll!ZwReadFile+0xc
006af214 76f69bba 0000001c 006af7a8 0000000a KERNELBASE!ReadFile+0xaa
006af25c 013325e1 0000001c 006af7a8 0000000a kernel32!ReadFileImplementation+0xf0
006af890 76f6ed6c 03b50508 006af8dc 7790377b SerialValidation20!comm_read_thread_proc+0x161 [d:\24-09-2014\solution_amat\solution_amat\solution_amat\serialvalidation.cpp @ 604]
006af89c 7790377b 03b50508 77fcb8dc 00000000 kernel32!BaseThreadInitThunk+0xe
006af8dc 7790374e 01332480 03b50508 00000000 ntdll!__RtlUserThreadStart+0x70
006af8f4 00000000 01332480 03b50508 00000000 ntdll!_RtlUserThreadStart+0x1b

STACK_COMMAND: kb

SYMBOL_STACK_INDEX: 0

SYMBOL_NAME: Wdf01000!FxContextHeaderInit+1c

FOLLOWUP_NAME: MachineOwner

MODULE_NAME: Wdf01000

IMAGE_NAME: Wdf01000.sys

DEBUG_FLR_IMAGE_TIMESTAMP: 5010ac41

FAILURE_BUCKET_ID: ACCESS_VIOLATION_Wdf01000!FxContextHeaderInit+1c

BUCKET_ID: ACCESS_VIOLATION_Wdf01000!FxContextHeaderInit+1c

Followup: MachineOwner

2: kd> .exr 0xffffffffffffffff
ExceptionAddress: 8bc31889 (Wdf01000!FxContextHeaderInit+0x0000001c)
ExceptionCode: c0000005 (Access violation)
ExceptionFlags: 00000000
NumberParameters: 2
Parameter[0]: 00000000
Parameter[1]: 11100f3a
Attempt to read from address 11100f3a

From the above, i understand that an attempt has been made to read from an invalid address.
From the stack trace it appears that the application (SerialValidation20) is sending a ReadFile request which the WDF framework is trying to deliver to my driver. But somewhere around FxContextHeaderInit() function it is crashing. My drivers functions are not displayed in stack trace.

SOme information about my target environment:
The target OS is WIndows 7 Embedded Standard SP1. I have 5 multiport serial controllers each of which have 8 ports. I am running the tests on all of the ports simultaneoulsy.

I am not getting any clue how to proceed about debugging these king of issues which don’t seem to be related to my driver. Could somebody please suggest me how to go find out the root cause of this issue?

xxxxx@gmail.com wrote:

I am stress testing my serial driver at a high baud rate of 256000 bps by Writing to the serial port and reading data back from the serial port (after configuring the serial port for loop back).

At this baud rate, i am seeing that the system crashes with an error “Access violation - code c0000005 (!!! second chance !!!)” very soon after the test is started. As per the crash analysis, my driver is not involved in the I/O. Below is hte crash dump.

Do you perhaps have an EvtIoInCallerContext callback that does some
pre-processing and adds a context to the request?


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

Because you see Wdf01000 you think your driver is not involved but it is. The I/O Manager does not use callbacks but DispatchRoutines. The KMDF framework sets up the DispatchRoutines for you and they are located in Wdf01000. So it seems that the framewirk is crashing when it builds the read request object.

Look at your WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE invocation. Do you use WdfObjectAllocateContext ?

I have not registered the call back EvtIoInCallerContext in my code.I am not using WdfObjectAllocateContext for my device context or my request context either.

I have compared the part of using WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE in my code with the sample drivers provided along with WDK. I couldn’t see anything unusual.

One difference in my driver compared to the other drivers is that the read, write and IOCTL queues
that my driver creates use sequential dispatching. I use the below statement.

WDF_IO_QUEUE_CONFIG_INIT(&stQueueConfig,WdfIoQueueDispatchSequential);

Below is the code of my device initialization. COuld you please let me know what aspects should i be checking with WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE?

WDF_PNPPOWER_EVENT_CALLBACKS_INIT(&stPnpPowerCallbacks);

stPnpPowerCallbacks.EvtDeviceD0Entry = PortD0Entry;

stPnpPowerCallbacks.EvtDeviceD0Exit = PortD0Exit;

stPnpPowerCallbacks.EvtDevicePrepareHardware = PortEvtDevicePrepareHardware;

stPnpPowerCallbacks.EvtDeviceReleaseHardware = PortEvtDeviceReleaseHardware;

/* registers a driver’s Plug and Play and power management event callback functions. */
WdfDeviceInitSetPnpPowerEventCallbacks(DeviceInit, &stPnpPowerCallbacks);

//
// Initialize all the properties specific to the device.
// Framework has default values for the one that are not
// set explicitly here. So please read the doc and make sure
// you are okay with the defaults.
//
WdfDeviceInitSetExclusive(DeviceInit, TRUE);

//set device type
WdfDeviceInitSetDeviceType(DeviceInit,FILE_DEVICE_SERIAL_PORT);

//
// Initialize attributes structure to specify size and accessor function
// for storing device context.
//
WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&stRequestAttributes, REQUEST_CONTEXT);

//Sets object attributes that will be used for all of the framework request
//objects that the framework delivers to the driver from the device’s I/O queues
WdfDeviceInitSetRequestAttributes(DeviceInit, &stRequestAttributes);

lStatus = RtlUnicodeStringPrintf(&devName, DEVICE_NAME L"%d", InterlockedIncrement(&NumDevName));

if(!NT_SUCCESS(lStatus))
{

return lStatus;
}
//Assiging a name to FDO
lStatus = WdfDeviceInitAssignName(DeviceInit,&devName);

if (!NT_SUCCESS(lStatus))
{

}

//
// Initialize attributes structure to specify size and accessor function
// for storing device context.
//
WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&stDeviceAttributes, DEVICE_CONTEXT);

//Create Device Object
lStatus = WdfDeviceCreate(&DeviceInit, &stDeviceAttributes, &hDevice);

if (!NT_SUCCESS(lStatus))
{
return status;
}

else
{

//
pstDeviceContext = WdfObjectGet_DEVICE_CONTEXT(hDevice);

pstDeviceContext->PrivateDeviceData = 0;

pstDeviceContext->hDevice = hDevice;
pstDeviceContext->hCurrentReadRequest = NULL;
lStatus = Create_MemoryObject(pstDeviceContext);

if(!NT_SUCCESS(lStatus))
{

return lStatus;
}
//Create Interrupt objects

// Do query for interfaces
lStatus = Do_QueryInterface(pstDeviceContext);

if (!NT_SUCCESS(lStatus))
{

return STATUS_UNSUCCESSFUL;
}

// Queue initialization
lStatus = Serial_QueueInitialize( hDevice );

if(!NT_SUCCESS(lStatus))
{
return lStatus;
}

//Create Spinlock
WDF_OBJECT_ATTRIBUTES_INIT(&stSpinLockAttributes);
stSpinLockAttributes.ParentObject = hDevice;
lStatus = WdfSpinLockCreate(
&stSpinLockAttributes,
&pstDeviceContext->hPortSpinLock
);
if(!NT_SUCCESS(lStatus))
{
return lStatus;
}

// create timers and DPCs
lStatus = SerialCreateTimersAndDpcs(pstDeviceContext);
if (!NT_SUCCESS(lStatus))
{

KdPrint((“SerialCreateTimersAndDpcs failed %x\n”, lStatus));
return lStatus;
}

Is there something wrong with the contents of my REQUESTCONTEXT structure? Below is the definition of the same

typedef struct _REQUEST_CONTEXT
{
ULONG_PTR pulInformation;
NTSTATUS lStatus;
ULONG ulLength;
PVOID pvRefCount;
PVOID pvSystemBuffer;
UCHAR ucMajorFunction;
PFN_WDF_REQUEST_CANCEL fpCancelRoutine;
BOOLEAN bCancelled;
PVOID pvType3InputBuffer;
PDEVICE_CONTEXT pstDeviceContext;
ULONG ulIoctlCode;
ULONG ulBytesNeedtoTransmit;
ULONG ulBytesAtStartOfRequest;
BOOLEAN bMarkCancelableOnResume;
BOOLEAN bReadTotalTimerRequired;
BOOLEAN bReadIntervalTimerRequired;
BOOLEAN bDefaultTimeouts;
BOOLEAN bSendAvailableToRequest;
SERIAL_TIMEOUTS stRequestTimeout;
LARGE_INTEGER stRequestTotalTime;
} REQUEST_CONTEXT, *PREQUEST_CONTEXT;

xxxxx@gmail.com wrote:

Is there something wrong with the contents of my REQUESTCONTEXT structure? Below is the definition of the same

Why on earth do you want to store all of that stuff in every request?
Everything in there, through ulBytesNeedToTransmit, is already directly
available from the request itself. It seems to me you’re just asking
for trouble by keeping a second copy around.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.