Reading Crash Logs
1. Foreword
This paper is intended to instruct non-developers in reading Crash Logger SSE (and to some extent trainwreck) crash logs. You will most likely not find anything useful here, if you already know the Assembly language.
I've dabbled with Assembly for well over 10 years now. I've managed to temporarily delete my OS by writing to the wrong part of the RAM memory. I've solved issues in 3rd party software that confused the developers. I've cracked old software for educational purposes and sniffed out passwords for data recovery. I've spent 4-ish years on LoversLab solving what must be hundereds of crashing issues. But I still consider myself to be only adept at the subject.
If you ever find yourself writing MASM or something similar, and manage to accidentally get your computer to tell you you have no Operating System the next time you reboot - do not panic. Turn the machine off, and pull your RAM sticks out. Go make a cup of coffee. When you return, your OS will be back from its vacation. Promise.
If you intend to ask for help reading a crash log, please use Crash Logger SSE:
https://www.nexusmods.com/skyrimspecialedition/mods/59818
If you want to skip straight to how to read a crash log, see section 4 below.
2. Disclaimer
The log examples used here are fictional: mod names do not represent any real world mods.
3. Definitions
Images and modules in the context of computer software:
An image is a block of executable code, binary data and embedded resources (icons, images or bitmaps, layouts, sounds, ...). In Windows its typically a file with an exe or dll extension, but its by no means limited to these. Dll images are usually called modules.
https://en.wikipedia.org/wiki/Executable
A debugger disassembles live programs:
Note that it is not possible to get a debugger into SkyrimSE.exe as-is. How to do it I can't mention here for what should be obvious reasons.
A disassembler disassembles a program when it's not running:
In the case of SkyrimSE.exe it is not practical to use a disassembler as-is. Again, I can't really comment on how to use a disassembler on Skyrim without potentially breaking a law or 2.
x86 and x86-64/amd64 assembly languages:
The next step up from machine code. Usually not necessary for solving issues with Skyrim, thanks to the excellent crash loggers we have. Knowing what it looks like could be useful when reading crash logs. You don't need to understand what it does to be able to identify it and skip over it.
For those that want to look into it a bit closer, the flavour of Assembly we're using is Intel. The flavour only changes the way the disassembly looks; it has no effect on the bytecode.
https://en.wikipedia.org/wiki/X86_assembly_language
https://en.wikipedia.org/wiki/X86-64
https://en.wikipedia.org/wiki/Assembly_language
Exception throwing, raising an exception:
The process of reporting an error/exception. The exception can be handled in an exception handler. If it was not handled, it becomes an unhandled exception and proceeds to crash the application. Handling an exception could mean directing code flow to an alternate path, logging the error and/or terminating the application. A handled exception that ends in the application terminating (i.e. it will look like a crash, but isn't) will not be caught by a crash logger which is watching for unhandled exceptions.
A bug:
Traditionally, the meaning of the word "bug" in software development is an error that would crash the application. An application is bug-free when it never crashes, regardless of how bad the user experience might be.
A thread:
In some sense you could think of this as a program within a program. On multi-threaded CPUs (i.e. practically all modern devices), multiple threads can do work at the same time.
A thread context:
This is the state the CPU was in with this specific thread at some point in time. The context usually shows the values of all CPU registers among other things. When it comes to crash logs, the thread context is almost always the exact moment the crash occured. See section 6 below for when this may not be the case.
A stack frame:
A section of memory allocated in the stack for a function. It may reveal things like arguments passed to the function, or memory allocated in the function itself. The size of the stack frame varies.
Machine code or bytecode:
The bits from which the Assembly representation is created. The bits are what instruct the CPU to do things, Assembly is the next step up from that and humanity's first (maybe?) attempt at making machine code readable. This is as far as you can practically get from JavaScript "programming"; the opposite end of the spectrum.
Function calling convention:
This is defined by the compiler that created the machine code. The calling convention defines things such as which register will hold the return value, and which registers will hold the arguments passed to the function, among other things. It is not essential to know the convention used, even when delving into a crash log with a debugger or disassembler in hand.
Threadproc:
Probably short for thread procedure, where procedure could also be called method or function depending on how picky you are with their definitions. It's typically used in conjunction with thread creation. The threadproc is the "main" function a thread is running. When the threadproc function returns, the thread terminates.
User-land:
https://en.wikipedia.org/wiki/Protection_ring
Program databases or PDB files:
Mods that contain dll files sometimes come with pdb files included. These pdb files are optional, the mod will work just fine without them, but they're essential in debugging (i.e. what we're doing here). The PDB file reveals the names of functions and variables as they were in the source code, among other useful things. The difference between having a pdb file and not having one could be weeks or months of work. So, while these files are optional and usually relatively large, I recommend you keep them around for when things aren't working so good. Crash Logger SSE will make use of these, thus vastly improving the quality of the log output.
4. Generic Log Overview
The most important take-away in this section is the order in which the different parts of the log should be read:
- Callstack: top-to-bottom, most relevant first, least relevant last.
- Registers: Ignore for now.
- Stack: usually top-to-bottom, most relevant first, least relevant last.
- Ignore callstack entries marked as being found by stack scanning (marked with an "S" in square brackets).
4.1 Faulting offset
EXCEPTION_ACCESS_VIOLATION at 0x7FFB34F139B4 BestCloakMod2.dll+00739B4
At the top of the crash log you have the address where the exception occurred and what kind of an exception it was. Here we had an access denied exception thrown from (most likely) an SKSE plugin called BestCloakMod2.dll. BestCloakMod2.dll has a bug in it.
Access denied errors are the most common, because crashes almost always happen when Skyrim tries to read or write memory it didn't have access to. This does not mean that you must run the game UAC elevated (or as an administrator), in fact it's extremely unlikely it has anything to do with it. The errors you see here should be seen from the point of view of the CPU. If the error is something other than access denied, I would Google its meaning; but keep in mind that the same (or a similar) error in Windows may not have any relation.
TIP: Running Skyrim UAC elevated is a horrible idea from a security perspective, especially now that dll-mods are getting popular. A dll is identical to an executable in what it can do. Any loaded dll has the same security token as its host process - if Skyrim can edit your system files and settings, then so can BestHatMod2.dll when loaded into Skyrim.
The unique signature of your crash, and the thing that defines whether or not you're having the same problem as someone else is the faulting offset and the version of the image that offset resides in. In the example above it's the offset and version of the BestCloakMod2.dll that defines the signature: "Best Cloak Mod version 1.2, BestCloakMod2.dll+00739B4". For offsets in SkyrimSE.exe it's the game version. When you search for information related to your crash, use only the offset: "BestCloakMod2.dll+00739B4" but be aware that a different version of the image could have (however unlikely it is) crashed at the same offset for an entirely different reason - take it as a hint, not as fact.
If the faulting offset is suggesting the crash occured in a system module, like KERNELBASE or the VCRUNTIME, look instead at the callstack entries that came before this. While technically (as per the definition of a bug in section 3 above) the issue is in one of these, you'll have more luck fixing what came before it. It's also far safer to mess with Skyrim rather than the OS itself. What's usually going on in these cases is that something in Skyrim (be it the game itself or an SKSE plugin) is passing invalid data to a system function, and then neglecting (perhaps on purpose) to handle the result properly.
4.2 Callstack
[ 0] 0x7FFB34F139B4 BestCloakMod2.dll+00739B4
[ 1] 0x7FF6E15DDE05 SkyrimSE.exe+143DE05 -> 104651+0x205 test al, al
...
[13] 0x7FFB86F3259D KERNEL32.DLL+001259D
[14] 0x7FFB886AAF78 ntdll.dll+005AF78
This is the path code execution took from the creation of the thread to where it crashed. To read it in chronological order, start from the bottom (the creation of the thread). The point where it crashed is at the top (chronologically the newest entry). The higher up something is, the more relevant to the crash it is, thus I recommend you read it from the top down, and not in chronological order.
The first entry of the callstack is always the faulting offset. The faulting offset is technically very different from the other callstack entries and thus in my opinion doesn't belong there. So, when I start reading the stack, I start with callstack entry #1 rather than entry #0.
UPDATE: Note that starting with Crash Logger versions from late 2025 or early 2026 the callstack is displayed in a different way from how it is normally (in other applications):
CALL STACK ([P]robable / [S]tack scan):
[ 0][P] 0x7FF60CA77F08 SkyrimSE.exe+0D17F08 -> 70187+0x78 mov rax, [rdi]
[ 1][P] 0x7FF60C279425 SkyrimSE.exe+0519425 -> 32030+0x75 mov rdi, rax
...
[18][P] 0x7FFB97F8259D KERNEL32.DLL+001259D
[19][P] 0x7FFB99ECAF78 ntdll.dll+005AF78
...
[72][S] 0x7FFB97392580 KERNELBASE.dll+0182580
[73][S] 0x7FFB99ECAF50 ntdll.dll+005AF50
When reading a log like this, don't assume the thread was created at the bottom like previously stated. The hint here is that KERNELBASE is not the same as KERNEL32. Start at the top and search for the first ntdll/KERNEL32 pair, then read from the top down until that entry like usual. In the example above, the relevant bit ends at callstack entry #19 rather than at entry #73. I do not know what the purpose is of reading beyond the stack frames relevant to the current thread context, this seems very misleading to me.
CURIOSITY: The callstack is not really a concept that exists in assembly, it's one of the many conveniences provided to you by the crash logger. It is constructed from the stack in a process called stack unwinding. It's possible for this to fail, however it's quite rare (or nonexistent) with modern Skyrim crash loggers. If stack unwinding fails, assume the callstack is not reliable unless you can spot where it failed; everything above the point where it went wrong should be reliable. See section 6 below for what it looks like when it fails.
4.3 Registers
RAX 0x7FFA6915E37F (void* -> BestCloakMod2.dll+011E37F mov rax, [rax])
RCX 0x83229AE630 (void*)
RDX 0x83229ADF49 (void*)
...
R12 0x0 (size_t) [0]
R13 0x7FF6E03C48D0 (void* -> SkyrimSE.exe+02248D0 mov [rsp+0x08], rbx)
R14 0x7FFA75399B88 (char*) "SKSE"
R15 0x8 (size_t) [8]
Registers may contain things that were, things that are and things that will be. It's impossible to tell which register is relevant to the crash without using a debugger or disassembler or knowing the calling convention of the function that contains the faulting offset.
This is the thread context, i.e. the state the CPU was in when the exception occured. The technical reason for why Skyrim crashed is always visible here, but usually you'd rather know which hat, shoe or NPC it was that crashed the game.
TIP: I usually ignore this bit, unless something warrants looking into it more closely.
4.4 Stack
[RSP+0 ] 0x193CFCF5A80 (void*)
...
[RSP+30 ] 0x7FFB85F600AC (void* -> KERNELBASE.dll+00600AC nop [rax+rax*1], eax)
...
[RSP+D8 ] 0x7FFA6919213B (void* -> BestCloakMod2.dll+015213B mov rbx, [rsp+0x70])
Like the registers, the stack may contain things that were, things that are and things that will be.
If you're using trainwreck the amount of information you get from the stack will be very limited compared to what you get with Crash Logger SSE. Hence why I always recommend switching from trainwreck to Crash Logger SSE. Trainwreck is by no means bad, but it's geared more towards someone that is capable of using a debugger; or another way to put that might be to say it's not as user-friendly as Crash Logger SSE. Trainwreck thus also makes remote assistance situations far more difficult.
While the stack is also in a kind of chronological order with the newest and most relevant bit at the top, it's possible for callstack entry #1 to be further down the stack rather than at the top. The most relevant entry should be at the top, but it is not guaranteed. Hence, when I start reading the stack I copy callstack entry #1 (not #0), and search for it in the stack and begin reading from there. Check a few lines above where you landed, then work your way down. Do not read past the last callstack entries.
Pick out the things you can read. Ignore the blocks of numbers. Do you see strings, plugin names or records (like an Actor, a door, a shoe or a bush) or perhaps parts of a mesh? Make notes of the things you can read, Google the parts that you don't understand.
The further down the stack you get, the less likely it is the things you see will be directly related to the bug that caused the crash. For instance, if you're seeing bits of a mesh (like NiNode names) working your way down the stack may reveal the nif file name where these nodes came from; or perhaps even the form or reference id of an NPC that was wearing that mesh. The nif or NPC is obviously relevant despite being further down, but when it comes to the reason why it crashed, it probably wasn't the nif file or NPC specifically but rather some value within them.
A mod that shows up in practically all crash logs is SMP, simply because of how and where it has its hooks. Just because something is in the callstack or the stack is not a 100% guarantee that it is part of the problem; but figuring this out with little or no experience can be difficult or impossible. Thus it might be wise to plot out a tree structure with branches leading to various things you think could be relevant.
A quick way of navigating the stack is to use the entries in the callstack to jump between stack frames. The bit above the callstack entry, and the entry that came before it is the stack frame. Example callstack:
[ 0] 0x7FFB85F600AC KERNELBASE.dll+00600AC
[ 1] 0x7FFA6919213B BestCloakMod2.dll+015213B
...
In this example (and using the stack above), callstack entry #0 starts at RSP+30 and its frame is above that (RSP+30 -> RSP+0). Callstack entry #1 starts at RSP+D8 and its frame is above that (RSP+D8 -> RSP+38).
5. A Closer Look
5.1 Faulting offset
Unhandled exception at 0x7FFB85F600AC SkyrimSE.exe+00600AC mov [rcx], eax
In the example used in the generic overview of the faulting offset, the problematic mod was easy to spot: Skyrim crashed because of a bug in BestCloakMod2.dll. More often than not the faulting offset will however be somewhere in SkyrimSE.exe. So, unless the answer is given to us on a platter right here, I typically skip over this. I only grab the assembly code from the faulting offset and move on, but you can ignore that part unless you want to try your hand at some Assembly. Analyzing a faulting offset in SkyrimSE.exe any further requires the use of a debugger, and we're not quite that desperate yet.
If the faulting offset is outside of any known module, it will most likely show up as just "Unhandled exception at <address> <assembly>" and nothing more. See section 7.6 for more on this.
As discussed in the generic overview section, the signature of the crash (i.e. the thing that defines whether or not you're having the same issue as someone else) is the faulting offset and the version of the image that offset resides in. To mix-n-match between versions, one decent hint I use myself is to compare the Assembly code at the faulting offset and the top 3-4 callstack entries. If the assembly code is same leading up to the crash, the crash was in the same image, and the stack looks suspiciously similar, it's quite likely what you're seeing is the same bug in 2 different builds (or versions) of an image.
Since version numbers of an image are usually manually set by people (in non-professional environments) there tends to be inconsistencies in them, and errors like forgetting to update them. A better way to define the version of an image is to calculate the MD5 file checksum of it:
get-filehash .\CommunityShaders.dll -algorithm md5 | select-object hash
So instead of saying you're using Community Shaders version 1.3.4, you should say (or add) that the checksum of its dll is 5B3B9F56353326D217DD6A0F80853B3D. With this hash, anyone else in the world can verify that they're looking at the same file as you, even if CS was to rerelease 1.3.4 with a stealth hotfix or accidentally release 1.3.5 labeled as 1.3.4. If even a single byte is different, it will show in the hash.
If you do not recognize the image name that caused the crash, find where it's being loaded from:
- Look for it in the Data\SKSE\Plugins directory of the game. Remember that MO2 has the USVFS which requires you to inspect this directory in an unusual way to see the files as the game would.
- If the game remains stable long enough, you can use Process Explorer from Sysinternals (Microsoft). Inspect the modules of SkyrimSE.exe.
- In situations where the game crashes before you get a chance to inspect it with any other utility, use Process Monitor from Sysinternals (Microsoft). Have it log only file IO traffic, and filter for paths ending with the image file name you're looking for (or just ".dll" if you want them all). In addition to that, also set it to only include events where the process name matches "SkyrimSE.exe".
If the image that is crashing is a system file (i.e. it's loaded from %SystemRoot%\System32) inspect instead the callstack entry that came before this. Do not start troubleshooting by reinstalling or otherwise changing system components. Your issue is more likely going to be in BestHatMod9.dll, rather than a framework module used globally in all Windows systems.
5.2 Callstack
Do a sanity check here and make sure the stack unwinding looks ok. See section 6 for an example of it gone wrong. Copy the module name and offset of entry #1 (not #0) and move on.
CURIOSITY: Functions are not a concept that exists in Assembly, but for the sake of simplicity I'm calling these shared code blocks by their more common name: functions.
CURIOSITY: Just like something appearing in the callstack is not a guarantee that it has anything to do with the crash, it's also possible for code blocks (or functions) to have been involved that do not show up in the callstack. This ties in with the note above about functions not really being a thing. You need a debugger to see these.
5.3 Registers
REGISTERS:
...
RCX 0x0 (void*)
...
To get the technical reason for why Skyrim crashed, you need the Assembly code from the faulting offset (see example above). In our case it was a mov instruction that tried to dereference (note the square brackets) the value in the RCX register. In our example here, the RCX register is 0x0 i.e. null, or since it's being dereferenced: a null pointer. While it may not seem like knowing this is going to lead you any closer to figuring out which shoe, hat or NPC caused the crash, it can sometimes be useful to know kind of what you're looking for:
- The way I'd correlate a null pointer to the game is by looking for unassigned fields in related ESL, ESP and ESM plugins, unassigned fields in a mesh or a Papyrus script that doesn't do None checks before using objects like Actors or ObjectReferences. The answer to which type of object you should be looking in is in the stack further down.
- In cases where the value is something other than null it could be invalid input or arithmetic gone wrong. Invalid input could for instance be trying to use a nif file made for Skyrim SE/AE on an older incompatible version of Skyrim. Arithmetic gone wrong could for instance mean a form list, which is limited to 128 entries, looking for the 129th entry.
5.4 Stack
Usually the stack frame of the first callstack entry is at the top of the stack, but this is not always the case. I'm not certain why this happens, as my understanding is that every function is responsible for essentially truncating the stack by adjusting the RSP and/or RBP registers. This is most likely up to the compiler to decide, and I'm sure there's a valid reason for it.
So, starting from callstack entry #1 look at what came before it in the stack. This is the data that is most relevant to the crash. Note that not everything is visible in the stack, but usually there's enough to get an idea of what is going on in a function. If more information is needed, you need to set a breakpoint in this function with a debugger. If you happen to have a log where callstack entry #1 lands you somewhere half way down the stack, then read about 3-7 lines above where you landed and assume that's the relevant stack frame.
TIP: If you keep practicing reading logs, even if it's a log you've already solved, you can train your eyes to instantly pick out details from the stack. The 2 things you really need is 1) where the relevant part of the stack begins (i.e. where callstack entry #1 is) and 2) where the threadproc was started (i.e. where ntdll.dll and KERNEL32.dll appear in the stack). Scan through the lines within these bounds and pick out everything you can read, sort them in order of importance and there's your problem description. Going beyond this quite quickly lands you in a situation where you need a debugger in SkyrimSE.exe while it's live and running.
6. When Things Go Wrong
6.1 When Crash Logger SSE dumps the wrong thread context
Unhandled exception at 0x0
...
PROBABLE CALL STACK:
...
[ 1] 0x7FFB85F600AC CrashLogger.dll+00600AC
Occasionally Crash Logger SSE has been known to (seemingly) dump the wrong thread context. In these logs it will most likely say the exception occured at address 0x0, and that the exception occured in Crash Logger SSE's own dll file (or soon after it). The current and most likely explanation for why this happens is when a null pointer is fed to a jmp or call instruction, and RIP jumps to 0x0. To put that another way, code execution jumped to memory address 0x0 (which is not valid), and caused a crash.
From what I've seen so far in these logs, the stack and registers are relevant to the crash, but the callstack isn't. I would ignore the registers and read the stack as if the first frame was at the top. Drop the reliability of the information in the stack to "most likely".
6.2 When stack unwinding fails
PROBABLE CALL STACK:
...
[11] 0x7FFB86F3259D 0x24
[12] 0x7FFB886AAF78 BestCloakMod2.dll+600B
This was mostly a quirk of the old .Net Script Framework mod's built-in crash logger, but it can in theory happen to any application attempting to unwind the stack. There is no reason to use this old crash logger anymore, when far superior ones exist. A sign of unwinding having gone wrong is to check the last 2 callstack entries: there is, to my knowledge, no other way to create a thread in user-land than to go through the Windows API in KERNEL32.DLL and ntdll.dll. Thus, if the last 2 callstack entries are not in these dll files, like in the example above, assume the unwinding went sideways at some point before (above) that.
PROBABLE CALL STACK: [0] 0x7FF65F1D8207 SkyrimSE.exe+0D18207 -> 70199+0x7 mov dword ptr [rcx+0x08], 0x00
Crash Logger SSE very rarely creates a callstack where only the faulting offset is present like in the example above. In these cases I'd read the stack assuming it starts at the top, and ends at the usual KERNEL32.DLL and ntdll.dll stack frames. I'd drop the reliability of the information to a "probably", especially if the stack is very large.
7. When Things Get Complicated
7.1 Fixing things properly
Removing or changing (i.e. upgrading, downgrading or replacing) the problematic mod is the simple workaround for a problem. It's a different thing entirely to actually try to fix a crash. As an example, lets say you trace a crash down to the texture of a rock in bushes behind Riften, you now got 2 options:
- You can use NifSkope to get the texture file name, and your mod manager to remove or change it.
- Instead of working around it, you can look into the Programming Guide for DDS and get an understanding of the file format so that you can go in there with a hex editor and nudge the bits back to where they should be.
From a learning perspective doing it properly is going to be far more valuable than just working around the problem. But as with everything, there's a cost-benefit consideration to be made.
7.2 Bytecode patching
Any image loaded in Skyrim has the capability to modify any other image currently loaded or loading in the future. Translating that to English, it means when you're crashing somewhere in SkyrimSE.exe, and you have a mod with a dll loaded, you need to keep in mind that that dll might have modified SkyrimSE.exe. These modifications can be (mostlikely will be) invisible in a crash log. It may have applied a patch that something else doesn't agree with, or perhaps the patch itself is flawed. Finding these requires a debugger.
7.3 Nothing in this paper seems to help
So you've gone through the log several times and you just can't figure it out. You've seen that there's one or more SKSE plugins mentioned in the callstack, registers or stack but none of it looks relevant. In these situations I'd recommend you start removing these mods, regardless of how unlikely it is that they're involved. Simplify the log. Start with the ones with the highest likelihood and the ones that are easiest to remove. If you're lucky, you accidentally remove the problem. Keep a close eye on how the crash behaves; if the problem moves or otherwise changes: that's a hint.
TIP: Be careful to not mislabel crashes: if the signature changes, then all you did was create a new problem; or perhaps you solved the current one and exposed a new one.
7.4 (Seemingly) random crashes
You're crashing frequently, and every time the signature is different. When facing issues like these there's 2 approaches I use:
- Gather crash logs from different parts of the game world: Indoors, outdoors, in Markarth, in Riften, while cooking, while fighting, ... Cross-reference these to find things that show up reliably everywhere. Usually 3-4 logs is enough. Isolate the problem by finding a reliably repeatable crash.
- One way that sometimes works is to save every 2-3 minutes. When a crash happens, your last save will hopefully only be a minute from where it can be repeated. This ties in heavily with section 7.5 below, as this is quite literally: "learn how to break it reliably".
7.5 Crashes that take a long time to replicate
My approach to issues like this is to learn how to break it on demand, rather than learning how to fix it. Maybe the crash always seems to occur outdoors, or indoors, or in a specific building. If it's NPC related, maybe you could use the console to spawn in 100 Whiterun guards to try to trigger it. This approach perhaps requires extensive knowledge of game mechanics, but it's worth considering as cutting down the time to test to sub-2 minutes is essential in some cases. I also find that more often than not, when I learn how to break something I'm also half way to learning where the problem is.
TIP: Be careful to not mislabel crashes: if the signature changes, then all you did was create a new problem.
7.6 The faulting offset is not within any known module
Unhandled exception "EXCEPTION_ACCESS_VIOLATION" at 0x7FF6E10BB0AF mov rcx, [rax] ... PROBABLE CALL STACK: [ 0] 0x7FF6E10BB0AF mov rcx, [rax] [ 1] 0x7FF6E0D100A2 SkyrimSE.exe+0B700A2 -> 62359+0x62 mov rbx, [rsp+0x58] ...
The log example above is fictional and may look slightly different in the real world. Note however that the faulting offset was not "translated" to a relative address i.e. "SkyrimSE.exe+0F1B0AF" (or similar). This indicates that it is outside the known start and end offsets of currently loaded images.
It's possible for any image to allocate memory, populate it with code and change the allocation's protection to allow execution. To put that another way, executable code can exist outside of any known memory segment (i.e. outside of memory allocated for an image). These will show up as absolute memory offsets rather than relative memory offsets. You need a debugger to see these, and it's quite likely you need to catch it before it's allocated to see where it's coming from.
I typically ignore these in crash logs unless something warrants looking into them:
- When encountering an absolute memory address as the faulting offset, ignore it.
- When encountering an absolute memory address in the callstack, see what came before (below) it. Keep in mind that the thing that came before may not have anything to do with what created the code at the absolute address.
- When encountering an absolute memory address in the stack, read it's stack frame like you would with any other callstack entry. Also look for hints as to which mod might have allocated this memory block.
The tricky part with these is that any loaded image could have allocated this memory, then modified the code of another image (like SkyrimSE.exe) to call into this new memory block. If a crash occurs in this newly allocated memory, it would show up as an absolute address followed by SkyrimSE.exe, perhaps making it look like Skyrim itself was causing issues when in reality the mod that injected the faulty code remains hidden. This is simulated in the example above.
Edited by traison
8 Comments
Recommended Comments