- May 7, 2013
- 10,400
Caveat: Before we begin, it would be best to note the subtle difference between 0x1000007E and 0x7E, since while the bugchecks are identical in their cause, their processing by operating system is not. All bugcheck names which have been suffixed with M and subsequently codes which have been prefixed with 0x100000, signify that the crash is a "Minidump" version of that bugcheck. This ensures that a valid context is saved at the time of the exception which will improve the accuracy of the call stack.
Special thanks to @axe0 for bringing this to my attention.
As the bugcheck description implies, this is a very common bugcheck and a very generic one at that, it is almost always caused by a access violation error and tends to be easy to debug, It is quite common for the faulty driver to be present on the call stack. The reason why the bugcheck occurs is because an exception is thrown within a system thread which isn't able to be handled by any given exception handler. System threads are able to be created by a device driver by calling the PsCreateSystemThread function. These threads run in kernel mode and are used by device drivers to perform some form of processing which requires a non-arbitrary thread context. Most of the system threads run within the System process and therefore it is very common to find the process context set to the System process with this crash. Please note that this does not mean that the System process is responsible for the bugcheck.
If we examine the call stack, we can see a system thread being initialised by the operating system:
Now, we have an understanding on how the bugcheck is caused, let's examine the individual parameters and see what they can tell us. The first parameter indicates the type of exception which has occurred, we can use the !error command to see which exception the exception code belongs to.
We can see that the exception was an access violation error. This indicates that a driver has referenced an invalid memory address, which in turn leads to a page fault which isn't able to be resolved, leading to the bugcheck being produced. The second parameter reveals where the exception was raised. Let's dump the context record stored in the fourth parameter and see what instruction this address corresponds to.
It seems that the exception was caused by a driver attempting to execute a call instruction using a completely invalid memory address. This would explain the access violation error shown in the exception record, which can be dumped using the .exr command and the value of the bugcheck's third parameter.
The exception record corresponds directly to what we found in the context record. The driver - SynTP.sys - was referencing the same invalid memory address shown earlier, which resulted in a access violation error being thrown. However, because there was no appropriate exception handler found, the system then decided to bugcheck with Stop 0x7E.
We can check what the driver is associated to by looking up the driver name in the Sysnative driver reference table, and it appears that SynTP.sys is a Synaptics touchpad driver. The driver appears to be from 2017 which is quite old and therefore it is recommend that the driver is updated from the appropriate support page.
If you're unable to find a third-party driver on the call stack, then you can dump the raw thread stack using the dps command. Likewise, if you have the PDE debugger extension library installed, then you can use !dpx as well.
Addendum:
For those who are curious, the .exr and .cxr commands technically parse the _EXCEPTION_RECORD and _CONTEXT structures respectively.
Most of the fields correspond directly to the fields shown by .exr command and so I won't explain those again. The ExceptionRecord field is a pointer to another exception record which is for exceptions which have inner exception information, therefore in most cases, this field will usually be set to null. The ExceptionInformation field is an integer array and contains the exception parameters, as well as, the processor registers saved during the exception. You can dump the ExceptionInformation array as so:
The context record contains all the registers saved when the context record was generated. This includes the EFLAGS register, segment registers and any machine-specific registers. You may noticed a set of peculiar fields called P1Home, P2Home etc. These are known as the homing parameters or homing space of a stack frame, instead of the first four parameters being stored in registers as per the x64 calling convention, the first four parameters are pushed onto the stack instead.
References:
CodeMachine - Article - X64 Deep Dive
Bug Check 0x7E SYSTEM_THREAD_EXCEPTION_NOT_HANDLED - Windows drivers
Bug Check 0x1000007E SYSTEM_THREAD_EXCEPTION_NOT_HANDLED_M - Windows drivers
Question about STOP code differences
winsdk-10/bugcodes.h at master · tpn/winsdk-10
Special thanks to @axe0 for bringing this to my attention.
Rich (BB code):
SYSTEM_THREAD_EXCEPTION_NOT_HANDLED_M (1000007e)
This is a very common bugcheck. Usually the exception address pinpoints
the driver/function that caused the problem. Always note this address
as well as the link date of the driver/image that contains this address.
Some common problems are exception code 0x80000003. This means a hard
coded breakpoint or assertion was hit, but this system was booted
/NODEBUG. This is not supposed to happen as developers should never have
hardcoded breakpoints in retail code, but ...
If this happens, make sure a debugger gets connected, and the
system is booted /DEBUG. This will let us see why this breakpoint is
happening.
Arguments:
Arg1: ffffffffc0000005, The exception code that was not handled
Arg2: fffff80020e3d57b, The address that the exception occurred at
Arg3: fffffb8aed24c0f8, Exception Record Address
Arg4: fffffb8aed24b930, Context Record Address
As the bugcheck description implies, this is a very common bugcheck and a very generic one at that, it is almost always caused by a access violation error and tends to be easy to debug, It is quite common for the faulty driver to be present on the call stack. The reason why the bugcheck occurs is because an exception is thrown within a system thread which isn't able to be handled by any given exception handler. System threads are able to be created by a device driver by calling the PsCreateSystemThread function. These threads run in kernel mode and are used by device drivers to perform some form of processing which requires a non-arbitrary thread context. Most of the system threads run within the System process and therefore it is very common to find the process context set to the System process with this crash. Please note that this does not mean that the System process is responsible for the bugcheck.
If we examine the call stack, we can see a system thread being initialised by the operating system:
Rich (BB code):
3: kd> knL
# Child-SP RetAddr Call Site
00 fffffb8a`ed24b0f8 fffff800`19c121be nt!KeBugCheckEx
01 fffffb8a`ed24b100 fffff800`19bccdd2 nt!PspSystemThreadStartup$filt$0+0x44
02 fffffb8a`ed24b140 fffff800`19c00072 nt!_C_specific_handler+0xa2
03 fffffb8a`ed24b1b0 fffff800`19ae6dd7 nt!RtlpExecuteHandlerForException+0x12
04 fffffb8a`ed24b1e0 fffff800`19ae59d6 nt!RtlDispatchException+0x297
05 fffffb8a`ed24b900 fffff800`19c092ac nt!KiDispatchException+0x186
06 fffffb8a`ed24bfc0 fffff800`19c05443 nt!KiExceptionDispatch+0x12c
07 fffffb8a`ed24c1a0 fffff800`20e3d57b nt!KiPageFault+0x443
[...]
26 fffffb8a`ed24cb70 fffff800`19b55855 nt!ExpWorkerThread+0x105
27 fffffb8a`ed24cc10 fffff800`19bfe808 nt!PspSystemThreadStartup+0x55
28 fffffb8a`ed24cc60 00000000`00000000 nt!KiStartSystemThread+0x28
Now, we have an understanding on how the bugcheck is caused, let's examine the individual parameters and see what they can tell us. The first parameter indicates the type of exception which has occurred, we can use the !error command to see which exception the exception code belongs to.
Rich (BB code):
3: kd> !error c0000005
Error code: (NTSTATUS) 0xc0000005 (3221225477) - The instruction at 0x%p referenced memory at 0x%p. The memory could not be %s.
We can see that the exception was an access violation error. This indicates that a driver has referenced an invalid memory address, which in turn leads to a page fault which isn't able to be resolved, leading to the bugcheck being produced. The second parameter reveals where the exception was raised. Let's dump the context record stored in the fourth parameter and see what instruction this address corresponds to.
Rich (BB code):
3: kd> .cxr 0xfffffb8aed24b930
rax=0000000000000000 rbx=0000447ff7eeb628 rcx=ffffbb8001f1cfa8
rdx=0000447ff7eeb628 rsi=0000000000000127 rdi=ffffbb80081149d0
rip=fffff80020e3d57b rsp=fffffb8aed24c330 rbp=fffffb8aed24c460
r8=fffff80020e8f000 r9=ffffbb8015e46868 r10=ffffbb8001561cf0
r11=fffffb8aed24c2c0 r12=ffffbb8013b79060 r13=fffff8001ca36da0
r14=ffffbb8008a46a08 r15=ffffbb8008a469e8
iopl=0 nv up ei ng nz na pe nc
cs=0010 ss=0018 ds=002b es=002b fs=0053 gs=002b efl=00010282
SynTP+0x3d57b:
fffff800`20e3d57b ff5070 call qword ptr [rax+70h] ds:002b:00000000`00000070=????????????????
It seems that the exception was caused by a driver attempting to execute a call instruction using a completely invalid memory address. This would explain the access violation error shown in the exception record, which can be dumped using the .exr command and the value of the bugcheck's third parameter.
Rich (BB code):
3: kd> .exr 0xfffffb8aed24c0f8
ExceptionAddress: fffff80020e3d57b (SynTP+0x000000000003d57b)
ExceptionCode: c0000005 (Access violation)
ExceptionFlags: 00000000
NumberParameters: 2
Parameter[0]: 0000000000000000
Parameter[1]: 0000000000000070
Attempt to read from address 0000000000000070
The exception record corresponds directly to what we found in the context record. The driver - SynTP.sys - was referencing the same invalid memory address shown earlier, which resulted in a access violation error being thrown. However, because there was no appropriate exception handler found, the system then decided to bugcheck with Stop 0x7E.
We can check what the driver is associated to by looking up the driver name in the Sysnative driver reference table, and it appears that SynTP.sys is a Synaptics touchpad driver. The driver appears to be from 2017 which is quite old and therefore it is recommend that the driver is updated from the appropriate support page.
Rich (BB code):
3: kd> lmvm SynTP
Browse full module list
start end module name
fffff800`20e00000 fffff800`20e9f000 SynTP T (no symbols)
Loaded symbol image file: SynTP.sys
Image path: \SystemRoot\system32\DRIVERS\SynTP.sys
Image name: SynTP.sys
Browse all global symbols functions data
Timestamp: Thu Aug 17 01:51:24 2017 (5994E88C)
CheckSum: 000A7751
ImageSize: 0009F000
Translations: 0000.04b0 0000.04e4 0409.04b0 0409.04e4
Information from resource tables:
If you're unable to find a third-party driver on the call stack, then you can dump the raw thread stack using the dps command. Likewise, if you have the PDE debugger extension library installed, then you can use !dpx as well.
Addendum:
For those who are curious, the .exr and .cxr commands technically parse the _EXCEPTION_RECORD and _CONTEXT structures respectively.
Rich (BB code):
3: kd> dt _EXCEPTION_RECORD
nt!_EXCEPTION_RECORD
+0x000 ExceptionCode : Int4B
+0x004 ExceptionFlags : Uint4B
+0x008 ExceptionRecord : Ptr64 _EXCEPTION_RECORD
+0x010 ExceptionAddress : Ptr64 Void
+0x018 NumberParameters : Uint4B
+0x020 ExceptionInformation : [15] Uint8B
Most of the fields correspond directly to the fields shown by .exr command and so I won't explain those again. The ExceptionRecord field is a pointer to another exception record which is for exceptions which have inner exception information, therefore in most cases, this field will usually be set to null. The ExceptionInformation field is an integer array and contains the exception parameters, as well as, the processor registers saved during the exception. You can dump the ExceptionInformation array as so:
Rich (BB code):
3: kd> dp fffffb8aed24c0f8+0x20
fffffb8a`ed24c118 00000000`00000000 00000000`00000070
fffffb8a`ed24c128 ffffa251`28944fff 00000000`00000000
fffffb8a`ed24c138 00000000`00000000 00000000`00000000
fffffb8a`ed24c148 00000000`00000000 ffffc858`a9754e7d
fffffb8a`ed24c158 00000000`41706e50 ffffbb80`08a469e8
fffffb8a`ed24c168 fffff800`1ca36da0 ffffbb80`08a46a08
fffffb8a`ed24c178 ffffbb80`13b79060 ffffbb80`081149d0
fffffb8a`ed24c188 00000000`00000127 0000447f`f7eeb628
The context record contains all the registers saved when the context record was generated. This includes the EFLAGS register, segment registers and any machine-specific registers. You may noticed a set of peculiar fields called P1Home, P2Home etc. These are known as the homing parameters or homing space of a stack frame, instead of the first four parameters being stored in registers as per the x64 calling convention, the first four parameters are pushed onto the stack instead.
Rich (BB code):
3: kd> dt _CONTEXT
nt!_CONTEXT
+0x000 P1Home : Uint8B
+0x008 P2Home : Uint8B
+0x010 P3Home : Uint8B
+0x018 P4Home : Uint8B
+0x020 P5Home : Uint8B
+0x028 P6Home : Uint8B
+0x030 ContextFlags : Uint4B
+0x034 MxCsr : Uint4B
+0x038 SegCs : Uint2B
+0x03a SegDs : Uint2B
+0x03c SegEs : Uint2B
+0x03e SegFs : Uint2B
+0x040 SegGs : Uint2B
+0x042 SegSs : Uint2B
+0x044 EFlags : Uint4B
+0x048 Dr0 : Uint8B
+0x050 Dr1 : Uint8B
+0x058 Dr2 : Uint8B
+0x060 Dr3 : Uint8B
+0x068 Dr6 : Uint8B
+0x070 Dr7 : Uint8B
+0x078 Rax : Uint8B
+0x080 Rcx : Uint8B
+0x088 Rdx : Uint8B
+0x090 Rbx : Uint8B
+0x098 Rsp : Uint8B
+0x0a0 Rbp : Uint8B
+0x0a8 Rsi : Uint8B
+0x0b0 Rdi : Uint8B
+0x0b8 R8 : Uint8B
+0x0c0 R9 : Uint8B
+0x0c8 R10 : Uint8B
+0x0d0 R11 : Uint8B
+0x0d8 R12 : Uint8B
+0x0e0 R13 : Uint8B
+0x0e8 R14 : Uint8B
+0x0f0 R15 : Uint8B
+0x0f8 Rip : Uint8B
+0x100 FltSave : _XSAVE_FORMAT
+0x100 Header : [2] _M128A
+0x120 Legacy : [8] _M128A
+0x1a0 Xmm0 : _M128A
+0x1b0 Xmm1 : _M128A
+0x1c0 Xmm2 : _M128A
+0x1d0 Xmm3 : _M128A
+0x1e0 Xmm4 : _M128A
+0x1f0 Xmm5 : _M128A
+0x200 Xmm6 : _M128A
+0x210 Xmm7 : _M128A
+0x220 Xmm8 : _M128A
+0x230 Xmm9 : _M128A
+0x240 Xmm10 : _M128A
+0x250 Xmm11 : _M128A
+0x260 Xmm12 : _M128A
+0x270 Xmm13 : _M128A
+0x280 Xmm14 : _M128A
+0x290 Xmm15 : _M128A
+0x300 VectorRegister : [26] _M128A
+0x4a0 VectorControl : Uint8B
+0x4a8 DebugControl : Uint8B
+0x4b0 LastBranchToRip : Uint8B
+0x4b8 LastBranchFromRip : Uint8B
+0x4c0 LastExceptionToRip : Uint8B
+0x4c8 LastExceptionFromRip : Uint8B
References:
CodeMachine - Article - X64 Deep Dive
Bug Check 0x7E SYSTEM_THREAD_EXCEPTION_NOT_HANDLED - Windows drivers
Bug Check 0x1000007E SYSTEM_THREAD_EXCEPTION_NOT_HANDLED_M - Windows drivers
Question about STOP code differences
winsdk-10/bugcodes.h at master · tpn/winsdk-10
Last edited by a moderator: