I'm debugging a game and I often come across an exception (EXCEPTION_PRIV_INSTRUCTION)
The debugger pauses on the address where it stops, now I want to step over one command at a time but when I step over it doesn't go one command at a time
I'm debugging a game and I often come across an exception (EXCEPTION_PRIV_INSTRUCTION)
The debugger pauses on the address where it stops, now I want to step over one command at a time but when I step over it doesn't go one command at a time
Exceptions are complicated business. I will attempt to explain briefly how SEH (Structured Exception Handling) in Windows works to invoke the appropriate exception handler. Your game probably does not use SEH, however, since your question is too broad so will be my answer. I based it on SEH since it's the easiest to understand and you can work your way up.
There are hardware and software exceptions. Hardware exceptions are thrown by the CPU - for example on illegal memory access, division by 0...
Software exceptions (which are caused by e.g. throw
in C++ use the RaiseException
call under Windows (refer MSDN).
The OS stores an exception-handler list - a list of routines that can deal with exceptions. These routines are usually the instructions in your catch
block. Each routine determines, when it is called, whether on not it wants to handle the exception. If your routine decides not to handle the exceptions it tells the OS to keep looking.
The handler list is stored in the thread information block (TIB):
_NT_TIB:
+0x000 ExceptionList
+0x004 StackBase
+0x008 StackLimit
+0x00C SubSytemTib
+0x010 FiberData
+0x010 Version
+0x014 ArbitaryUserPointer
+0x018 Self
The TIB is available atFS:[0]
.
The ExceptionList
field is the head of the current thread's exception handler list.
The list is a chain of _EXCEPTION_REGISTRATION_RECORD
structures:
_EXCEPTION_REGISTRATION_RECORD
+0x000 Next
+0x004 Handler
How are exceptions dispatched (page-fault example)
The processor generates a page-fault interrupt INT 0x0E
and calls [IDT+0x0E]
. In Windows this is usually KiTrap0E
.
Windows then calls into a user-mode exception dispatcher routine KiUserExceptionDispatcher
in NTDLL.DLL
.
The dispatcher then calls into RtlDispatchException
which iterates through the ExceptionList
.
You can see from above why your program jumps around and you cannot follow it line by line - when an exception occurs the processor itself calls the KiTrap0E
- you cannot see that call. Then as the handlers are invoked there is also a lot of "jumping around" - the RtlDispatchException
function iterates through all the registered exception handlers. You need to locate the appropriate handler and see what your game does with your exception.