Tech Support > Microsoft Windows > Drivers > RemoveHeadList crashes system
RemoveHeadList crashes system
Posted by Kid of the neon on May 13th, 2008


Crash dump analysis:

-----------------------------------------------
DRIVER_IRQL_NOT_LESS_OR_EQUAL (d1)
An attempt was made to access a pageable (or completely invalid) address at an
interrupt request level (IRQL) that is too high. This is usually
caused by drivers using improper addresses.
If kernel debugger is available get stack backtrace.
Arguments:
Arg1: 00000000, memory referenced
Arg2: 00000002, IRQL
Arg3: 00000000, value 0 = read operation, 1 = write operation
Arg4: ba2edb33, address which referenced memory

Debugging Details:
------------------


READ_ADDRESS: 00000000

CURRENT_IRQL: 2

FAULTING_IP:
Interrupt!RemoveHeadList+13 [e:\winddk\3790.1830\inc\ddk\wnet\ntddk.h @ 3308]
ba2edb33 8b02 mov eax,dword ptr [edx]

DEFAULT_BUCKET_ID: DRIVER_FAULT

BUGCHECK_STR: 0xD1

PROCESS_NAME: System

TRAP_FRAME: f78a2f18 -- (.trap 0xfffffffff78a2f18)
ErrCode = 00000000
eax=ba2f11f8 ebx=ffdff000 ecx=00000000 edx=00000000 esi=8681258c edi=86812328
eip=ba2edb33 esp=f78a2f8c ebp=f78a2f94 iopl=0 nv up ei ng nz ac po nc
cs=0008 ss=0010 ds=0023 es=0023 fs=0030 gs=0000 efl=00000292
Interrupt!RemoveHeadList+0x13:
ba2edb33 8b02 mov eax,dword ptr [edx]
ds:0023:00000000=????????
Resetting default scope

LAST_CONTROL_TRANSFER: from ba2edb33 to 804e2158

STACK_TEXT:
f78a2f18 ba2edb33 badb0d00 00000000 f78a2f54 nt!KiTrap0E+0x233
f78a2f94 ba2edb02 ba2f11f8 8050589d 805058cb Interrupt!RemoveHeadList+0x13
[e:\winddk\3790.1830\inc\ddk\wnet\ntddk.h @ 3308]
f78a2fa8 ba2edb9d 00000000 ba2ed0b0 f78a2fc8 Interrupt!queue_get_next+0x22
[d:\interruptdriver\buffer.c @ 77]
f78a2fc0 ba2ed11c 8958a910 00000000 ffdff980 Interrupt!queue_execute+0xd
[d:\interruptdriver\buffer.c @ 87]
f78a2fd0 804dc179 8958a8cc 8958a858 00000000
Interrupt!InterruptDpcRoutine+0x2c [d:\interruptdriver\interrupt.c @ 59]
f78a2ff4 804dbe2d f78d2b50 00000000 00000000 nt!KiRetireDpcList+0x46
f78a2ff8 f78d2b50 00000000 00000000 00000000 nt!KiDispatchInterrupt+0x2a
WARNING: Frame IP not in any known module. Following frames may be wrong.
804dbe2d 00000000 00000009 bb835675 00000128 0xf78d2b50


STACK_COMMAND: kb

FOLLOWUP_IP:
Interrupt!RemoveHeadList+13 [e:\winddk\3790.1830\inc\ddk\wnet\ntddk.h @ 3308]
ba2edb33 8b02 mov eax,dword ptr [edx]

FAULTING_SOURCE_CODE:
3304: PLIST_ENTRY Flink;
3305: PLIST_ENTRY Entry;
3306:
3307: Entry = ListHead->Flink;
3310: Flink->Blink = ListHead;
3311: return Entry;
3312: }
3313:


SYMBOL_STACK_INDEX: 1

SYMBOL_NAME: Interrupt!RemoveHeadList+13

FOLLOWUP_NAME: MachineOwner

MODULE_NAME: Interrupt

IMAGE_NAME: Interrupt.sys

DEBUG_FLR_IMAGE_TIMESTAMP: 48297c3d

FAILURE_BUCKET_ID: 0xD1_VRF_Interrupt!RemoveHeadList+13

BUCKET_ID: 0xD1_VRF_Interrupt!RemoveHeadList+13

Followup: MachineOwner
---------------------------------

List head is initiailised in DriverEntry routine, and crash appeared in
first call to DpcRoutine (where queue_execute is called).

list management code:

LIST_ENTRY head;
SIZE_T QUEUE_ENTRY_SIZE, PMOVE_VARS_SIZE, SETSPEED_VARS_SIZE;
const ULONG POOL_TAG = 'pool';

void queue_initialize()
{
QUEUE_ENTRY_SIZE = sizeof(QUEUE_ENTRY);
PMOVE_VARS_SIZE = sizeof(PMOVE_VARS);
SETSPEED_VARS_SIZE = sizeof(SETSPEED_VARS);
InitializeListHead(&head);
}

void queue_dispose()
{
PQUEUE_ENTRY entry;
while ((entry = queue_get_next()) != NULL)
my_free(entry);
}

void queue_add_pmove_vars(int ch, int dir1, int speed1, long step1, int
dir2, int speed2, long step2, int dir3, int speed3, long step3)
{
PQUEUE_ENTRY entry = my_malloc(QUEUE_ENTRY_SIZE);
PPMOVE_VARS pmove_vars = my_malloc(PMOVE_VARS_SIZE);

pmove_vars->ch = (unsigned char)ch;
pmove_vars->dir1 = (unsigned char)dir1;
pmove_vars->speed1 = (unsigned char)speed1;
pmove_vars->step1 = step1;
pmove_vars->dir2 = (unsigned char)dir2;
pmove_vars->speed2 = (unsigned char)speed2;
pmove_vars->step2 = step2;
pmove_vars->dir3 = (unsigned char)dir3;
pmove_vars->speed3 = (unsigned char)speed3;
pmove_vars->step3 = step3;

entry->data = pmove_vars;
entry->data_type = DATA_TYPE_PMOVE_VARS;
InsertTailList(&head, &(entry->ListEntry));
}

void queue_add_setspeed_vars(int ch, unsigned long Temp_r1, unsigned long
Temp_r2, unsigned long Temp_r3, unsigned long Temp_r4)
{
PQUEUE_ENTRY entry = my_malloc(QUEUE_ENTRY_SIZE);
PSETSPEED_VARS setspeed_vars = my_malloc(SETSPEED_VARS_SIZE);

setspeed_vars->ch = (unsigned char)ch;
setspeed_vars->Temp_r1 = Temp_r1;
setspeed_vars->Temp_r2 = Temp_r2;
setspeed_vars->Temp_r3 = Temp_r3;
setspeed_vars->Temp_r4 = Temp_r4;

entry->data = setspeed_vars;
entry->data_type = DATA_TYPE_SETSPEED_VARS;

InsertTailList(&head, &(entry->ListEntry));
}

PQUEUE_ENTRY queue_get_next()
{
PLIST_ENTRY ListEntry;
PQUEUE_ENTRY entry;

if (IsListEmpty(&head)) return NULL;

ListEntry = RemoveHeadList(&head); // !!!!! CRASH
entry = CONTAINING_RECORD(ListEntry, QUEUE_ENTRY, ListEntry);
return entry;
}

void queue_execute()
{
PPMOVE_VARS pmove_vars;
PSETSPEED_VARS setspeed_vars;
PQUEUE_ENTRY entry = queue_get_next();

KdPrint( ( "Interrupt.sys queue_execute\n" ) );

if (entry != NULL)
{
switch (entry->data_type)
{
case DATA_TYPE_PMOVE_VARS:
pmove_vars = (PPMOVE_VARS)(entry->data);
pmove(pmove_vars->ch,
pmove_vars->dir1,
pmove_vars->speed1,
pmove_vars->step1,
pmove_vars->dir2,
pmove_vars->speed2,
pmove_vars->step2,
pmove_vars->dir3,
pmove_vars->speed3,
pmove_vars->step3,
0,0,0);
my_free(pmove_vars);
break;
case DATA_TYPE_SETSPEED_VARS:
setspeed_vars = (PSETSPEED_VARS)(entry->data);
set_speed(setspeed_vars->ch,
setspeed_vars->Temp_r1,
setspeed_vars->Temp_r2,
setspeed_vars->Temp_r3,
setspeed_vars->Temp_r4);
my_free(setspeed_vars);
queue_execute();
break;
}
my_free(entry);
}
}


Posted by Don Burn on May 13th, 2008


The list is corrupted so you crash. Somehow head.flink is NULL which will
fail the IsListEmpty test which checks for the head.flink == &head, but once
you try to reference the list you will crash. You will have to work through
you code on this one.


--
Don Burn (MVP, Windows DDK)
Windows 2k/XP/2k3 Filesystem and Driver Consulting
Website: http://www.windrvr.com
Blog: http://msmvps.com/blogs/WinDrvr
Remove StopSpam to reply



"Kid of the neon" <Kidoftheneon@discussions.microsoft.com> wrote in message
news0094306-C8D4-4680-832B-50DC0E12896F@microsoft.com...


Posted by Tim Roberts on May 14th, 2008


Kid of the neon <Kidoftheneon@discussions.microsoft.com> wrote:
Why would you use global memory variables for this, requiring a memory
access to fetch the value, instead of leaving these as compile-time
constants? I suggest you replace this:
SIZE_T QUEUE_ENTRY_SIZE, PMOVE_VARS_SIZE, SETSPEED_VARS_SIZE;
with this:
#define QUEUE_ENTRY_SIZE sizeof(QUEUE_ENTRY)
#define PMOVE_VARS_SIZE sizeof(PMOVE_VARS)
#define SeTSPEED_VARS_SIZE sizeof(SETSPEED_VARS)

My initial estimate here would be that you forgot to call queue_initialize
from DriverEntry. You might sprinkle some KdPrints in a few of these
routines.
--
Tim Roberts, timr@probo.com
Providenza & Boekelheide, Inc.


Similar Posts