<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Blog | Software Verify</title>
	<atom:link href="https://www.softwareverify.com/blog/feed/" rel="self" type="application/rss+xml" />
	<link>https://www.softwareverify.com/blog/</link>
	<description>Troubleshoot your software</description>
	<lastBuildDate>Tue, 19 May 2026 16:55:31 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=7.0</generator>
	<item>
		<title>AQTime Is Shutting Down. Here&#8217;s What Replaces It.</title>
		<link>https://www.softwareverify.com/blog/aqtime-alternative-replacement/</link>
		
		<dc:creator><![CDATA[Stephen Kellett]]></dc:creator>
		<pubDate>Tue, 19 May 2026 16:55:31 +0000</pubDate>
				<category><![CDATA[Blog]]></category>
		<guid isPermaLink="false">https://www.softwareverify.com/?p=13054</guid>

					<description><![CDATA[<p>SmartBear has confirmed that AQTime will reach end of life in June/July 2026. If you&#8217;re using AQTime for memory analysis, code coverage, or performance profiling, [&#8230;]</p>
<p>The post <a href="https://www.softwareverify.com/blog/aqtime-alternative-replacement/">AQTime Is Shutting Down. Here&#8217;s What Replaces It.</a> appeared first on <a href="https://www.softwareverify.com">Software Verify</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>SmartBear has confirmed that AQTime will reach end of life in June/July 2026. If you&#8217;re using AQTime for memory analysis, code coverage, or performance profiling, you need to find a replacement.</p>
<p>This post covers what replaces what, what you gain in the migration, and the one gap we&#8217;re honest about. For a complete profiler-by-profiler mapping, see the <a href="https://www.softwareverify.com/aqtime-migration/">AQTime migration guide</a>.</p>
<h2>What AQTime covered</h2>
<p>AQTime was a single product that bundled 15 profilers: memory leak detection, resource tracking, COM reference counting, code coverage (two variants), performance profiling (instrumented and sampling), plus several secondary tools for exception tracing, fault injection, function tracing, and static analysis.</p>
<p>The appeal was obvious — one licence, one UI, one installation. The three capabilities that most developers actually used were: memory analysis, code coverage, and performance profiling. Those three map directly to three Software Verify products.</p>
<h2>The thing worth knowing before you migrate</h2>
<p>AQTime&#8217;s native-code profiling support stopped at Visual Studio 2010.</p>
<p>That&#8217;s not a typo. AQTime&#8217;s profilers for unmanaged C++ code support MSVC version 4 through 10 — that&#8217;s Visual Studio up to and including VS 2010. Any developer writing C++11, C++14, C++17, C++20, or C++23 in Visual Studio 2012 or later cannot fully use AQTime&#8217;s native profilers. The documentation hasn&#8217;t been updated since January 2022, and the compiler support hadn&#8217;t been updated for years before that.</p>
<p>If you&#8217;ve been struggling to get meaningful results from AQTime on a modern build, this is likely why.</p>
<p>Our tools support MSVC from Visual C++ 6 through Visual Studio 2026. Every version in between. The same applies to GCC, Clang, Delphi, and Rust — if we can read debug information from the compiler, we can instrument the application.</p>
<h2>Memory analysis → Memory Validator</h2>
<p>AQTime split memory tracking across three separate profilers:</p>
<ul>
<li>The <strong>Allocation Profiler</strong> tracked heap memory — but allocation tracking was disabled by default. You had to specifically enable &#8220;Check system memory allocations&#8221; before any allocation data appeared. Their own documentation acknowledged this generated lots of results and could cause out-of-memory issues within AQTime itself.</li>
<li>The <strong>Resource Profiler</strong> tracked Windows handles, GDI objects, fonts, brushes, bitmaps, registry handles, COM objects, and print spooler entries.</li>
<li>The <strong>Reference Count Profiler</strong> tracked COM AddRef/Release on interface objects.</li>
</ul>
<p>Memory Validator covers all three in one tool, with everything enabled by default. You don&#8217;t prepare a project, don&#8217;t configure which resource types to track, and don&#8217;t worry about which profiler covers which category. Load your application, run it, see what leaked.</p>
<p>On top of what AQTime covered, Memory Validator also tracks GDI handles, Windows kernel handles, and .NET handles — all of which AQTime&#8217;s Resource Profiler did not track separately. If GDI exhaustion or Windows handle exhaustion has been a problem you&#8217;ve been debugging manually, Memory Validator surfaces these automatically.</p>
<h2>Code coverage → Coverage Validator</h2>
<p>AQTime offered two coverage tools: Coverage Profiler for thorough line-by-line tracking with hit counts, and Light Coverage Profiler for faster runs without hit counts — useful for daily regression testing.</p>
<p>Coverage Validator handles both use cases through a single instrumentation setting. The default mode gives full line coverage with visit counts at practical speed. If you need maximum throughput for a regression pipeline, switching to the lighter instrumentation mode takes seconds. AQTime required two separate products; we handle it with one dial.</p>
<p>Coverage Validator supports every compiler version AQTime&#8217;s coverage profiler supported, and every compiler version AQTime&#8217;s profiler never got to: VS 2012 through 2026, modern GCC, Clang, Delphi, Rust.</p>
<h2>Performance profiling → Performance Validator</h2>
<p>AQTime&#8217;s Performance Profiler was an instrumented profiler with 13 measurement counters — elapsed time, CPU cache misses, context switches, page faults, and several others. It also had a documented BSOD risk when certain counters were used with the Windows DDK installed, and timing accuracy caveats for SpeedStep processors and virtual machines.</p>
<p>Performance Validator is an instrumented profiler with a sampling option. The instrumented mode gives exact call counts, complete call graphs, and line-level timing. It works with any application where debug information is available — which means VS 6 through 2026, Delphi, GCC, Clang, and anything else that produces a PDB, TDS or DWARF output. No BSOD risk, no hotfix requirements.</p>
<p>AQTime also had a Sampling Profiler — statistical profiling that polls at intervals rather than instrumenting every call. It was unmanaged code only, and their documentation recommended quad-core hardware for accuracy. Performance Validator covers both approaches: use instrumented mode for exact call counts and full call graphs, or switch to sampling mode when you want lower overhead.</p>
<h2>The gap we&#8217;ll be honest about</h2>
<p>AQTime&#8217;s <strong>Failure Emulator</strong> injected controlled failures into Windows API calls — COM failures, file access failures, memory allocation failures, registry failures — to test how an application handles error paths. This is genuinely useful work: most applications handle the happy path well and fall apart when malloc returns NULL or a registry key goes missing.</p>
<p>We don&#8217;t have a direct equivalent right now. Fault Validator is something we plan to build — AQTime&#8217;s Failure Emulator showed the demand was real, and their exit leaves a gap in the market. If fault injection was a core part of your workflow, we don&#8217;t have a replacement today and we&#8217;re not going to pretend otherwise.</p>
<h2>AQTime&#8217;s Function Trace</h2>
<p>AQTime&#8217;s Function Trace profiler logged every function call with actual parameter values — a powerful debugging aid for tracing exact execution paths. Our equivalent is <strong>Bug Validator</strong>, which records parameter values, local variable values, and register values at every function entry, exit, and line visit. It covers more than AQTime&#8217;s Function Trace did. The honest caveat: Bug Validator is currently in beta and 32-bit only. If you were using Function Trace on 64-bit code, 64-bit Bug Validator support is in development.</p>
<h2>Starting the migration</h2>
<p>If the single-licence appeal of AQTime was important to you, we have suites that cover the same ground.</p>
<p>The <strong><a href="https://www.softwareverify.com/suites/#supportsuite">Support Suite</a></strong> includes Memory Validator and Performance Validator.</p>
<p>The <strong><a href="https://www.softwareverify.com/suites/#qasuite">QA Suite</a></strong> includes Memory Validator, Coverage Validator, and Performance Validator — the three tools that replace AQTime&#8217;s core capabilities.</p>
<p>The <strong><a href="https://www.softwareverify.com/suites/#developersuite">Developer Suite</a></strong> includes Memory Validator, Coverage Validator, Performance Validator, and Thread Validator for thread analysis and deadlock detection.</p>
<p>All tools are available as fully functional 30-day trials. No feature restrictions during the trial.</p>
<p>If you have questions about specific AQTime workflows and how they map to our tools, <a href="https://www.softwareverify.com/contact/">contact us directly</a>. We&#8217;re happy to walk through your setup.</p>
<hr />
<p><em>AQTime 8 documentation is available at support.smartbear.com/aqtime/docs/ until the end of June 2026, if you need to reference it during migration.</em></p>
<p>The post <a href="https://www.softwareverify.com/blog/aqtime-alternative-replacement/">AQTime Is Shutting Down. Here&#8217;s What Replaces It.</a> appeared first on <a href="https://www.softwareverify.com">Software Verify</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Parasoft Insure++ Is Being Discontinued. Here&#8217;s What Replaces It.</title>
		<link>https://www.softwareverify.com/blog/parasoft-insure-is-being-discontinued-heres-what-replaces-it/</link>
		
		<dc:creator><![CDATA[Stephen Kellett]]></dc:creator>
		<pubDate>Tue, 19 May 2026 16:53:45 +0000</pubDate>
				<category><![CDATA[Blog]]></category>
		<guid isPermaLink="false">https://www.softwareverify.com/?p=13058</guid>

					<description><![CDATA[<p>Parasoft has announced that Insure++ is being discontinued in June/July 2026. If you have been using Insure++ for C/C++ memory debugging on Windows, you need [&#8230;]</p>
<p>The post <a href="https://www.softwareverify.com/blog/parasoft-insure-is-being-discontinued-heres-what-replaces-it/">Parasoft Insure++ Is Being Discontinued. Here&#8217;s What Replaces It.</a> appeared first on <a href="https://www.softwareverify.com">Software Verify</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>Parasoft has announced that Insure++ is being discontinued in June/July 2026. If you have been using Insure++ for C/C++ memory debugging on Windows, you need a replacement.</p>
<p>This post covers what Memory Validator replaces, where it goes further, and the one area where you will need a separate tool. For a full capability mapping, see the <a href="https://www.softwareverify.com/parasoft-insure-migration/">Insure++ migration guide</a>.</p>
<h2>What Insure++ did</h2>
<p>Insure++ was a C and C++ memory debugger for Windows. Its headline capability was patented source code instrumentation — to get full analysis, you compiled and linked your application through Insure++, which generated its own instrumented build and passed it to your actual compiler. The result was deep visibility into memory errors: heap corruption, buffer overflows, use-after-free, double-free, uninitialized memory reads, array out of bounds. Insure++ also included built-in code coverage and a graphical memory visualisation view.</p>
<p>It was a well-regarded tool with 25 years in the market. Boeing, Lockheed Martin, L3Harris, and Thales were among its customers. If it was part of your workflow, finding a replacement that actually covers what you need is worth doing carefully.</p>
<h2>Compiler and OS support</h2>
<p>Insure++ supported Visual Studio 2015, 2017, and 2019. Visual Studio 2022 and 2026 were not supported. On the OS side, Insure++ supported Windows 10, Windows Server 2008, Windows Server 2012, and Windows Server 2019. Windows 11 and Windows Server 2022 were not supported.</p>
<p>Memory Validator supports Visual C++ 6 through Visual Studio 2026, and runs on all versions of Windows from XP through Windows 10 and 11, and all equivalent server versions.</p>
<h2>The recompile requirement</h2>
<p>The most significant workflow difference between Insure++ and Memory Validator is instrumentation approach. Insure++ required you to recompile and relink your application every time you wanted a full analysis run. Memory Validator instruments at the binary level, at runtime. You do not recompile. You do not relink. You attach to your existing build and run.</p>
<p>For daily debugging work, this compounds quickly. Every iteration that would have triggered a recompile-and-relink cycle with Insure++ is an immediate run with Memory Validator.</p>
<h2>Memory errors: what Memory Validator covers</h2>
<p>Memory Validator detects heap memory leaks, heap corruption, and buffer overwrites. It also detects double-free and use-after-free — in Memory Validator this is called deleted-this detection. Deleted-this is off by default because it adds an instrumentation step, but enabling it requires no recompile. It is a settings change.</p>
<p>Memory Validator can see leaks in all DLLs your application loads — including third-party libraries you do not own source for. The only leaks it does not report are those originating inside Microsoft&#8217;s own DLL internals, where the allocation is paired with a deallocation you cannot intercept, and any DLLs you have explicitly told Memory Validator to ignore. Everything else is visible.</p>
<h2>Beyond what Insure++ tracked</h2>
<p>Insure++ tracked heap memory. Memory Validator tracks heap memory, GDI handles, Windows kernel handles, and .NET handles.</p>
<p>GDI handle exhaustion and Windows handle exhaustion are genuine problems in Windows applications — they surface as crashes or degraded behaviour after extended runtime, and they are difficult to diagnose without a tool that specifically tracks them. Insure++ did not track these. If you have been relying on Insure++ for memory analysis and hitting handle-related problems separately, Memory Validator covers both in the same session.</p>
<h2>The displays</h2>
<p>Insure++ had memory visualisation. Memory Validator&#8217;s graphical displays are more detailed: more dedicated views showing the collected data from different angles, colour coding that conveys information at a glance, and richer callstack data per allocation. If you found Insure++&#8217;s visualisation useful, Memory Validator&#8217;s is better.</p>
<h2>Code coverage</h2>
<p>Insure++ bundled code coverage alongside memory analysis in a single product. Memory Validator does not include code coverage — that is a separate product, Coverage Validator. If code coverage was part of your Insure++ workflow, you will need both Memory Validator and Coverage Validator to replace it.</p>
<p>Coverage Validator is available individually or as part of the QA Suite, which bundles Memory Validator, Coverage Validator, and Performance Validator in a single purchase.</p>
<h2>Suites</h2>
<p>If you want a single-licence option:</p>
<p>The <strong><a href="https://www.softwareverify.com/suites/#supportsuite">Support Suite</a></strong> includes Memory Validator and Performance Validator.</p>
<p>The <strong><a href="https://www.softwareverify.com/suites/#qasuite">QA Suite</a></strong> includes Memory Validator, Coverage Validator, and Performance Validator.</p>
<p>The <strong><a href="https://www.softwareverify.com/suites/#developersuite">Developer Suite</a></strong> includes Memory Validator, Coverage Validator, Performance Validator, and Thread Validator.</p>
<h2>Starting the migration</h2>
<p>Memory Validator and Coverage Validator are both available as fully functional 30-day trials. No feature restrictions during the trial.</p>
<p>If you have questions about how your specific Insure++ workflow maps to our tools, <a href="https://www.softwareverify.com/contact/">contact us directly</a>.</p>
<p>The post <a href="https://www.softwareverify.com/blog/parasoft-insure-is-being-discontinued-heres-what-replaces-it/">Parasoft Insure++ Is Being Discontinued. Here&#8217;s What Replaces It.</a> appeared first on <a href="https://www.softwareverify.com">Software Verify</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>We added a thread to keep the GUI responsive. Then we broke it.</title>
		<link>https://www.softwareverify.com/blog/we-added-a-thread-to-keep-the-gui-responsive-then-we-broke-it/</link>
		
		<dc:creator><![CDATA[Stephen Kellett]]></dc:creator>
		<pubDate>Fri, 15 May 2026 16:08:03 +0000</pubDate>
				<category><![CDATA[Blog]]></category>
		<guid isPermaLink="false">https://www.softwareverify.com/?p=13028</guid>

					<description><![CDATA[<p>Memory Validator is a multi-threaded application. The main thread runs the user interface. If the main thread blocks, the UI becomes unresponsive — and if [&#8230;]</p>
<p>The post <a href="https://www.softwareverify.com/blog/we-added-a-thread-to-keep-the-gui-responsive-then-we-broke-it/">We added a thread to keep the GUI responsive. Then we broke it.</a> appeared first on <a href="https://www.softwareverify.com">Software Verify</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>Memory Validator is a multi-threaded application. The main thread runs the user interface. If the main thread blocks, the UI becomes unresponsive — and if it stays unresponsive long enough, users assume the software has hung.</p>
<p>The standard solution to problems like this is to do the work onto dedicated worker threads. MV&#8217;s timeline view does exactly this: a dedicated thread periodically samples memory use and posts a refresh event to the GUI thread when new data is ready. The GUI thread processes the refresh and updates the display.</p>
<h2>Avoiding a deadlock</h2>
<p>The catch is how you post that event.</p>
<p>From a worker thread you must use <code>PostMessage()</code>, not <code>SendMessage()</code>.</p>
<p>Using <code>SendMessage()</code> from a non-GUI thread will cause a deadlock.</p>
<h2>What went wrong</h2>
<p>Under certain settings and workloads the timeline thread was generating data faster than the GUI thread could process refresh events. The thread kept posting update events. The message queue kept filling with events to process. Eventually the GUI thread was spending all its time processing refresh events and nothing else — including user input. The UI locked completely.</p>
<p>The irony is hard to miss. We added a dedicated worker thread specifically to keep the GUI thread free and responsive. Then we made the GUI thread unresponsive by sending it too many events.</p>
<h2>The fix</h2>
<p>Two changes.</p>
<p>Before posting a refresh event, check whether one is already pending. If a refresh is already queued, there is no point adding another — the queued one will handle it:</p>
<p><code>if (!m_bRefreshQueued)</code><br />
<code>{</code><br />
<code>    m_bRefreshQueued = true;</code><br />
<code>    PostMessage(WM_REFRESH_TIMELINE, 0, 0);</code><br />
<code>}</code></p>
<p><code>// In the message handler:</code></p>
<p><code>void OnRefreshTimeline()</code><br />
<code>{</code><br />
<code>    m_bRefreshQueued = false;</code><br />
<code>    // ... update the timeline view</code><br />
<code>}</code></p>
<p>The second change: check the session state. If the session is in standby — the monitored process has ended, data collection is finished — there is nothing to refresh. Skipping the event in that case cleaned up the post-session screen behaviour:</p>
<p>
<code>if (m_session.IsStandby())</code><br />
<code>    return;</code></p>
<p><code>if (!m_bRefreshQueued)</code><br />
<code>{</code><br />
<code>    m_bRefreshQueued = true;</code><br />
<code>    PostMessage(WM_REFRESH_TIMELINE, 0, 0);</code><br />
<code>}</code></p>
<p>
There was no need to change how we posted the events. We kept the <code>PostMessage()</code> API call.</p>
<h2>What to take away</h2>
<p>If you have a worker thread posting UI updates, add a pending flag before each <code>PostMessage()</code> call.</p>
<p>Check session or application state too — there is no point refreshing a view that has nothing new to show.</p>
<p>The post <a href="https://www.softwareverify.com/blog/we-added-a-thread-to-keep-the-gui-responsive-then-we-broke-it/">We added a thread to keep the GUI responsive. Then we broke it.</a> appeared first on <a href="https://www.softwareverify.com">Software Verify</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Crash Analysis Tools: Complete Guide for 2026</title>
		<link>https://www.softwareverify.com/blog/crash-analysis-tools-complete-guide-for-2026/</link>
		
		<dc:creator><![CDATA[Stephen Kellett]]></dc:creator>
		<pubDate>Tue, 21 Apr 2026 12:57:40 +0000</pubDate>
				<category><![CDATA[Blog]]></category>
		<guid isPermaLink="false">https://www.softwareverify.com/?p=12937</guid>

					<description><![CDATA[<p>Your application crashed in production, and all you have is a dump file and a stack trace full of hexadecimal addresses. Without the right tools, [&#8230;]</p>
<p>The post <a href="https://www.softwareverify.com/blog/crash-analysis-tools-complete-guide-for-2026/">Crash Analysis Tools: Complete Guide for 2026</a> appeared first on <a href="https://www.softwareverify.com">Software Verify</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>Your application crashed in production, and all you have is a dump file and a stack trace full of hexadecimal addresses. Without the right tools, that file is nearly useless.</p>
<p>Crash analysis tools translate those raw memory snapshots into readable call stacks, variable values, and exception details—the information you actually need to fix the bug. With <a href="https://stackoverflow.co/company/press/archive/stack-overflow-2025-developer-survey/">45% of developers reporting AI-generated code</a> harder to debug according to Stack Overflow&#8217;s 2025 survey, these tools are more essential than ever. This guide covers how crash analysis works, the different tool types available, and how to integrate crash analysis into your development workflow.</p>
<h2>What are crash analysis tools?</h2>
<p>Crash analysis tools are software that developers use to figure out what went wrong when an application crashes. You feed them a crash dump file—a snapshot of your program&#8217;s state at the moment it failed—and they show you the call stack, memory contents, and variable values that explain the failure. </p>
<p>The core functions break down like this:</p>
<ul>
<li><strong>Crash dump reading:</strong> Opens minidump or full memory dump files captured when your application failed</li>
<li><strong>Symbol resolution:</strong> Translates raw memory addresses into function names and source line numbers</li>
<li><strong>Call stack extraction:</strong> Reconstructs the sequence of function calls leading up to the crash</li>
</ul>
<p>Without one of these tools, you&#8217;re looking at hexadecimal addresses and guessing. With one, you can trace exactly which function failed and often see why.</p>
<h2>How crash analysis works</h2>
<p>When an application crashes, Windows can capture a snapshot of the process—threads, memory, loaded modules, and the exception that triggered the failure.</p>
<p>Your crash analysis tool reads that snapshot and reconstructs what was happening at the exact moment things went wrong.</p>
<h3>Reading debug symbols</h3>
<p>Symbols connect compiled code to human-readable names. For minidumps, symbols are stored in the debug information your compiler generates alongside the executable. On Windows, the most common debug information format is <a href="https://www.softwareverify.com/product/dbghelp-browser/">PDB (Program Database)</a>. Alternative debug information formats are <a href="https://www.softwareverify.com/product/tds-browser/">TDS</a>, <a href="https://www.softwareverify.com/product/dwarf-browser/">DWARF</a>, STABS, COFF, Metrowerks and CodeView. Additionally <a href="https://www.softwareverify.com/product/map-file-browser/">MAP</a> files can sometimes be used to source debug information (this is very compiler/linker dependent and can vary by version of the compiler/linker).</p>
<p>Which format of debug information is available depends on the compiler used to build the software. PDB information is always referenced via a PDB file, which either stores the debug information or serves as a database index pointing to where it is located. TDS data can be stored in separate files or with the executable. STABS, COFF and CodeView data are always stored with the executable.</p>
<p>When you load a crash dump, the tool uses debug information to translate addresses like <code>0x00007FF6A1B2C3D4</code> into something like <code>MyApp!ProcessData+0x42</code>. </p>
<p>If you don&#8217;t have the matching debug information, you&#8217;ll see raw addresses instead of function names. This is why keeping debug information for every release build matters—you can&#8217;t analyze a production crash if you&#8217;ve lost the symbols for that build.</p>
<p>PDB files contain identifiers linking them to a specific executable. You can&#8217;t just rebuild the binary and use the generated PDB, because it will have its own unique identifier. This is why keeping PDB files for every release build matters.</p>
<p>For kernel dumps, symbol information is always stored in PDB files.</p>
<h3>Extracting call stacks</h3>
<p>The <a href="https://www.softwareverify.com/blog/how-to-collect-crash-callstacks/">call stack</a> shows which functions called which, leading up to the crash. Your tool unwinds the stack frames to reconstruct this chain, with the faulting frame at the top.</p>
<p>A typical call stack looks like:</p>
<pre><code>MyApp!ProcessData+0x42
MyApp!HandleRequest+0x1A3
MyApp!WorkerThread+0x8F
kernel32!BaseThreadInitThunk+0x14
</code></pre>
<p>Reading from bottom to top, <code>WorkerThread</code> called <code>HandleRequest</code>, which called <code>ProcessData</code>, where the crash occurred. The <code>+0x42</code> <a href="https://www.softwareverify.com/documentation/html/dwarfBrowser/decoding-a-symbol-relative-cra.html">tells you how far into the function</a> the crash happened.</p>
<h3>Inspecting memory and variables</h3>
<p>Once you&#8217;ve found where the crash occurred, you can examine local variables, CPU registers, and memory contents at that location. If a null pointer caused the crash, you&#8217;ll see it here. If a buffer overflowed, you can inspect surrounding memory to understand what went wrong.</p>
<p>This is where crash analysis becomes <a href="https://www.softwareverify.com/blog/debugging-a-crash-with-single-stepping/">actual debugging</a>—you&#8217;re not just finding the crash location, you&#8217;re understanding the cause.</p>
<h2>Types of crash analysis tools</h2>
<p>Different tools fit different workflows. Some developers prefer visual interfaces for exploring unfamiliar crashes. Others want command-line tools they can script into automated pipelines.</p>
<h3>GUI-based crash analyzers</h3>
<p>GUI tools provide visual interfaces for browsing threads, call stacks, and variables. You can click through stack frames, expand data structures, and visually search memory. They&#8217;re well-suited for interactive investigation where you&#8217;re exploring a crash you haven&#8217;t seen before.</p>
<p>The tradeoff is that GUI tools are harder to automate. If you&#8217;re processing one crash dump, a GUI works fine. If you&#8217;re processing fifty from an overnight test run, you&#8217;ll want something scriptable.</p>
<h3>Command-line crash tools</h3>
<p>Command-line tools accept arguments and produce text output. You can run them from scripts, capture output to log files, and integrate them into CI pipelines. For batch processing or automated test infrastructure, command-line tools are the practical choice.</p>
<p>Many tools offer both modes—a GUI for interactive work and a command-line interface for automation.</p>
<h3>Debugger extensions and plugins</h3>
<p>Extensions add capabilities to existing debuggers like WinDbg or Visual Studio. They might provide specialized commands, better visualization for specific data types, or support for particular frameworks. If you already have a debugger workflow you like, extensions let you enhance it without switching tools entirely.</p>
<table>
<thead>
<tr>
<th>Tool Type</th>
<th>Best For</th>
<th>Automation Support</th>
</tr>
</thead>
<tbody>
<tr>
<td>GUI-based</td>
<td>Interactive debugging</td>
<td>Limited</td>
</tr>
<tr>
<td>Command-line</td>
<td>CI/CD integration</td>
<td>Full</td>
</tr>
<tr>
<td>Debugger plugins</td>
<td>Extending existing workflow</td>
<td>Varies</td>
</tr>
</tbody>
</table>
<h2>Understanding crash dump formats</h2>
<p>Not all crash dumps contain the same information. The format determines how much you can learn—and how large the file will be.</p>
<h3>Minidump files</h3>
<p><a href="https://www.softwareverify.com/product/minidump-browser/">Minidumps</a> are compact files containing thread stacks, loaded module lists, and exception information. They&#8217;re typically a few hundred kilobytes to a few megabytes. <a href="https://www.softwareverify.com/product/event-log-crash-browser/">Windows Error Reporting</a> generates minidumps by default, and most crash reporting systems use this format because the files are small enough to upload quickly.</p>
<p>The tradeoff is that minidumps don&#8217;t include full heap contents. You can see the call stack and local variables, but you can&#8217;t inspect arbitrary objects allocated on the heap.</p>
<h3>Full memory dumps</h3>
<p>A full memory dump captures everything—the complete process memory at the moment of the crash. The files can be gigabytes in size, but they let you examine any variable, any heap allocation, any data structure in the process.</p>
<p>When a minidump doesn&#8217;t give you enough information, a full dump often will. The challenge is collecting and transferring files that large, especially from production systems or remote machines.</p>
<h3>Kernel dumps</h3>
<p><a href="https://www.softwareverify.com/product/minidump-browser/">Kernel dumps</a> capture operating system state, not just your application. They&#8217;re used for driver crashes, blue screens, and other system-level failures—the 2024 CrowdStrike outage, which <a href="https://edition.cnn.com/2024/07/24/tech/crowdstrike-outage-cost-cause">crashed 8.5 million Windows devices</a>, was diagnosed through kernel dump analysis of an out-of-bounds memory read.</p>
<p>Analyzing kernel dumps requires different tools and symbols—specifically, the Windows kernel symbols from Microsoft&#8217;s symbol server.</p>
<p>If you&#8217;re debugging application code, you&#8217;ll rarely work with kernel dumps. If you&#8217;re writing drivers or diagnosing system-level issues, they become essential.</p>
<h2>How to perform crash analysis</h2>
<p>Here&#8217;s a practical walkthrough. The specifics vary by tool, but the process follows the same pattern regardless of which analyzer you use.</p>
<h3>1. Collect the crash dump file</h3>
<p>Crash dumps come from several sources:</p>
<ul>
<li><a href="https://www.softwareverify.com/blog/identifying-crashes-with-the-windows-event-log/"><strong>Windows Error Reporting</strong></a><strong>:</strong> Captures dumps automatically for many crashes</li>
<li><strong>Custom crash handlers:</strong> Your application can call MiniDumpWriteDump to <a href="https://www.softwareverify.com/blog/how-to-create-minidumps-using-visual-studio-windbg-and-exception-tracer/">create dumps programmatically</a></li>
<li><strong>Crash reporting services:</strong> Third-party services collect dumps from end users and upload them centrally</li>
<li><strong>Manual capture:</strong> You can attach a debugger and create a dump on demand</li>
</ul>
<p>However you get the dump, make sure you also have the matching PDB files for the exact build that crashed. A dump without symbols is much harder to analyze.</p>
<h3>2. Load symbols and debug information</h3>
<p>Before analysis, configure your tool&#8217;s symbol path. On Windows, this typically includes your local symbol cache, your build server&#8217;s symbol store, and Microsoft&#8217;s public <a href="https://www.softwareverify.com/documentation/html/threadValidator/symbolserversettings.html">symbol server</a> for OS components.</p>
<h4>WinDbg</h4>
<p>For WinDbg, you&#8217;d use the <strong>.sympath</strong> command:</p>
<pre><code>.sympath srv*C:\Symbols*https://msdl.microsoft.com/download/symbols</code></pre>
<h4>Visual Studio</h4>
<p>For Visual Studio, you&#8217;d open the <strong>Tools &gt; Options</strong> dialog box and navigate to <strong>Debugging &gt; Symbols</strong>, and enable the <strong>Microsoft Symbol Servers</strong>.</p>
<p>You can see that this user has also added a path to the development version of one of <a href="https://www.softwareverify.com/product/performance-validator/">Performance Validator&#8217;s</a> projects.</p>
<p><img fetchpriority="high" decoding="async" class="alignnone size-full wp-image-12944" src="https://www.softwareverify.com/wp-content/uploads/2026/04/VisualStudioSymbolServerSettings.png" alt="Visual Studio Symbol Server Settings" width="744" height="526" srcset="https://www.softwareverify.com/wp-content/uploads/2026/04/VisualStudioSymbolServerSettings.png 744w, https://www.softwareverify.com/wp-content/uploads/2026/04/VisualStudioSymbolServerSettings-300x212.png 300w" sizes="(max-width: 744px) 100vw, 744px" /></p>
<h4>Minidump Browser</h4>
<p>For Minidump Browser, you&#8217;d open the <strong>Settings &gt; Edit Settings</strong> dialog box, navigate to <strong>Symbol Servers</strong>, and click <strong>Add&#8230;</strong> to add a symbol server.</p>
<p>You can see in the image below that the Microsoft Symbol Server has already been added and enabled.</p>
<p><img decoding="async" class="alignnone size-full wp-image-12945" src="https://www.softwareverify.com/wp-content/uploads/2026/04/MiniDumpBrowserSymbolServerSettings.png" alt="Minidump Browser Symbol Server Settings" width="733" height="391" srcset="https://www.softwareverify.com/wp-content/uploads/2026/04/MiniDumpBrowserSymbolServerSettings.png 733w, https://www.softwareverify.com/wp-content/uploads/2026/04/MiniDumpBrowserSymbolServerSettings-300x160.png 300w" sizes="(max-width: 733px) 100vw, 733px" /></p>
<p>The tool you&#8217;re using downloads symbols as needed and caches them locally. First-time analysis of a new build might take a minute while symbols download; subsequent analysis of the same build uses the cache.</p>
<h3>3. Locate the faulting thread</h3>
<p>Most applications have multiple threads running when they crash. Only one thread triggered the exception. Your tool usually highlights this thread automatically, but you may want to examine the <a href="https://www.softwareverify.com/blog/exceptions-codes-youve-never-heard-of/">exception record</a> to confirm which thread faulted and what exception occurred.</p>
<p>Common <a href="https://www.softwareverify.com/product/exception-tracer/">exceptions</a> include access violations (null pointer dereferences, invalid memory access), stack overflows, and unhandled C++ exceptions.</p>
<h4>Visual Studio</h4>
<p>The threads windows displays the crashed application&#8217;s threads, and highlights the crashed thread.</p>
<p>If a filename and line number can be determined for the top of the thread&#8217;s callstack, the source code is displayed, highlighting the relevant line.</p>
<p><img decoding="async" class="alignnone size-full wp-image-12947" src="https://www.softwareverify.com/wp-content/uploads/2026/04/VisualStudioCrashedThread.png" alt="Visual Studio Crashed Thread" width="940" height="293" srcset="https://www.softwareverify.com/wp-content/uploads/2026/04/VisualStudioCrashedThread.png 940w, https://www.softwareverify.com/wp-content/uploads/2026/04/VisualStudioCrashedThread-300x94.png 300w, https://www.softwareverify.com/wp-content/uploads/2026/04/VisualStudioCrashedThread-768x239.png 768w" sizes="(max-width: 940px) 100vw, 940px" /></p>
<h4>Minidump Browser</h4>
<p>If a loaded minidump contains an exception, the Exception display is shown automatically. This displays the faulting thread id, and thread name, if available.</p>
<p>If a filename and line number can be determined for the top of the thread&#8217;s callstack, the source code is displayed, highlighting the relevant line.</p>
<p><img loading="lazy" decoding="async" class="alignnone size-full wp-image-12949" src="https://www.softwareverify.com/wp-content/uploads/2026/04/MinidumpBrowserCrashedThread.png" alt="Minidump Browser Crashed Thread" width="1144" height="630" srcset="https://www.softwareverify.com/wp-content/uploads/2026/04/MinidumpBrowserCrashedThread.png 1144w, https://www.softwareverify.com/wp-content/uploads/2026/04/MinidumpBrowserCrashedThread-300x165.png 300w, https://www.softwareverify.com/wp-content/uploads/2026/04/MinidumpBrowserCrashedThread-1024x564.png 1024w, https://www.softwareverify.com/wp-content/uploads/2026/04/MinidumpBrowserCrashedThread-768x423.png 768w" sizes="auto, (max-width: 1144px) 100vw, 1144px" /></p>
<h3>4. Examine the call stack</h3>
<p>Work through the stack frames from top to bottom. The top frame shows where the crash occurred; the frames below show how execution got there. Look for the transition from your code into library or OS code—that boundary is often where the bug lives.</p>
<p>If frames show only addresses without function names, you&#8217;re <a href="https://www.softwareverify.com/blog/dbghelp-search-path/">missing symbols</a> for that module. Check your symbol path configuration.</p>
<h4>WinDbg</h4>
<p>Use the command <strong>k</strong></p>
<p><img loading="lazy" decoding="async" class="alignnone size-full wp-image-12950" src="https://www.softwareverify.com/wp-content/uploads/2026/04/WinDbgCrashingCallstack.png" alt="WinDbg Crashing Callstack" width="1303" height="133" srcset="https://www.softwareverify.com/wp-content/uploads/2026/04/WinDbgCrashingCallstack.png 1303w, https://www.softwareverify.com/wp-content/uploads/2026/04/WinDbgCrashingCallstack-300x31.png 300w, https://www.softwareverify.com/wp-content/uploads/2026/04/WinDbgCrashingCallstack-1024x105.png 1024w, https://www.softwareverify.com/wp-content/uploads/2026/04/WinDbgCrashingCallstack-768x78.png 768w" sizes="auto, (max-width: 1303px) 100vw, 1303px" /></p>
<h4>Visual Studio</h4>
<p>The <strong>Debug &gt; Call Stack</strong> view displays the crashed thread&#8217;s callstack.</p>
<p><img loading="lazy" decoding="async" class="alignnone size-full wp-image-12951" src="https://www.softwareverify.com/wp-content/uploads/2026/04/VisualStudioCrashingCallstack.png" alt="Visual Studio Crashing Callstack" width="947" height="294" srcset="https://www.softwareverify.com/wp-content/uploads/2026/04/VisualStudioCrashingCallstack.png 947w, https://www.softwareverify.com/wp-content/uploads/2026/04/VisualStudioCrashingCallstack-300x93.png 300w, https://www.softwareverify.com/wp-content/uploads/2026/04/VisualStudioCrashingCallstack-768x238.png 768w" sizes="auto, (max-width: 947px) 100vw, 947px" /></p>
<h4>Minidump Browser</h4>
<p>If a loaded minidump contains an exception, the <strong>Exception</strong> display is shown automatically. The <strong>Callstack</strong> part of the Exception display shows the crashing callstack.</p>
<p><img loading="lazy" decoding="async" class="alignnone size-full wp-image-12952" src="https://www.softwareverify.com/wp-content/uploads/2026/04/MinidumpBrowserCrashingCallstack.png" alt="Minidump Browser Crashing Callstack" width="875" height="517" srcset="https://www.softwareverify.com/wp-content/uploads/2026/04/MinidumpBrowserCrashingCallstack.png 875w, https://www.softwareverify.com/wp-content/uploads/2026/04/MinidumpBrowserCrashingCallstack-300x177.png 300w, https://www.softwareverify.com/wp-content/uploads/2026/04/MinidumpBrowserCrashingCallstack-768x454.png 768w" sizes="auto, (max-width: 875px) 100vw, 875px" /></p>
<h3>5. Inspect local variables and registers</h3>
<p>Once you&#8217;ve found the faulting location, examine the state at that point. Was a pointer null? Did an index exceed array bounds? Was a handle invalid? The answers are usually visible in local variables and CPU registers.</p>
<p>This step often reveals the immediate cause. The root cause—why that variable had a bad value—might require tracing back through earlier code or examining other threads.</p>
<h4>WinDbg</h4>
<p>Use the command <strong>dv</strong> to display local variables.</p>
<p><img loading="lazy" decoding="async" class="alignnone size-full wp-image-12955" src="https://www.softwareverify.com/wp-content/uploads/2026/04/WinDbg_dv.png" alt="WinDbg command dv" width="330" height="28" srcset="https://www.softwareverify.com/wp-content/uploads/2026/04/WinDbg_dv.png 330w, https://www.softwareverify.com/wp-content/uploads/2026/04/WinDbg_dv-300x25.png 300w" sizes="auto, (max-width: 330px) 100vw, 330px" /></p>
<p>Use the command <strong>dv</strong> to display local variables. Advanced usage <strong>dv /i /t /V</strong>.<strong> /i </strong>indicates local or parameter.<strong> /t </strong>indicates type.<strong> /V </strong>indicates memory address.</p>
<p><img loading="lazy" decoding="async" class="alignnone size-full wp-image-12956" src="https://www.softwareverify.com/wp-content/uploads/2026/04/WinDbg_dv_itV.png" alt="WinDbg command /i /t /V" width="650" height="30" srcset="https://www.softwareverify.com/wp-content/uploads/2026/04/WinDbg_dv_itV.png 650w, https://www.softwareverify.com/wp-content/uploads/2026/04/WinDbg_dv_itV-300x14.png 300w" sizes="auto, (max-width: 650px) 100vw, 650px" /></p>
<p>Use the command <strong>kP</strong> to display the callstack and parameters passed. This displays results one parameter per line.</p>
<p><img loading="lazy" decoding="async" class="alignnone size-full wp-image-12957" src="https://www.softwareverify.com/wp-content/uploads/2026/04/WinDbg_k_P.png" alt="WinDbg command kP" width="1349" height="157" srcset="https://www.softwareverify.com/wp-content/uploads/2026/04/WinDbg_k_P.png 1349w, https://www.softwareverify.com/wp-content/uploads/2026/04/WinDbg_k_P-300x35.png 300w, https://www.softwareverify.com/wp-content/uploads/2026/04/WinDbg_k_P-1024x119.png 1024w, https://www.softwareverify.com/wp-content/uploads/2026/04/WinDbg_k_P-768x89.png 768w" sizes="auto, (max-width: 1349px) 100vw, 1349px" /></p>
<p>Use the command <strong>kp</strong> to display the callstack and parameters passed. This displays results with all parameters per line.</p>
<p><img loading="lazy" decoding="async" class="alignnone size-full wp-image-12958" src="https://www.softwareverify.com/wp-content/uploads/2026/04/WinDbg_kP.png" alt="WinDbg command kp" width="1697" height="129" srcset="https://www.softwareverify.com/wp-content/uploads/2026/04/WinDbg_kP.png 1697w, https://www.softwareverify.com/wp-content/uploads/2026/04/WinDbg_kP-300x23.png 300w, https://www.softwareverify.com/wp-content/uploads/2026/04/WinDbg_kP-1024x78.png 1024w, https://www.softwareverify.com/wp-content/uploads/2026/04/WinDbg_kP-768x58.png 768w, https://www.softwareverify.com/wp-content/uploads/2026/04/WinDbg_kP-1536x117.png 1536w" sizes="auto, (max-width: 1697px) 100vw, 1697px" /></p>
<p>Use the command <strong>kv</strong> to display the callstack and the raw values of parameters passed.</p>
<p><img loading="lazy" decoding="async" class="alignnone size-full wp-image-12959" src="https://www.softwareverify.com/wp-content/uploads/2026/04/WinDbg_kv.png" alt="WinDbg command kv" width="1900" height="129" srcset="https://www.softwareverify.com/wp-content/uploads/2026/04/WinDbg_kv.png 1900w, https://www.softwareverify.com/wp-content/uploads/2026/04/WinDbg_kv-300x20.png 300w, https://www.softwareverify.com/wp-content/uploads/2026/04/WinDbg_kv-1024x70.png 1024w, https://www.softwareverify.com/wp-content/uploads/2026/04/WinDbg_kv-768x52.png 768w, https://www.softwareverify.com/wp-content/uploads/2026/04/WinDbg_kv-1536x104.png 1536w" sizes="auto, (max-width: 1900px) 100vw, 1900px" /></p>
<h4>Visual Studio</h4>
<p>The <strong>Debug &gt; Autos</strong> view shows you the value of any variables that are in scope.</p>
<p><img loading="lazy" decoding="async" class="alignnone size-full wp-image-12961" src="https://www.softwareverify.com/wp-content/uploads/2026/04/VisualStudioAutos.png" alt="Visual Studio Autos view" width="942" height="294" srcset="https://www.softwareverify.com/wp-content/uploads/2026/04/VisualStudioAutos.png 942w, https://www.softwareverify.com/wp-content/uploads/2026/04/VisualStudioAutos-300x94.png 300w, https://www.softwareverify.com/wp-content/uploads/2026/04/VisualStudioAutos-768x240.png 768w" sizes="auto, (max-width: 942px) 100vw, 942px" /></p>
<p>The <strong>Debug &gt; Locals</strong> view shows you the value of any local variables and parameters.</p>
<p><img loading="lazy" decoding="async" class="alignnone size-full wp-image-12962" src="https://www.softwareverify.com/wp-content/uploads/2026/04/VisualStudioLocals.png" alt="Visual Studio Locals view" width="940" height="292" srcset="https://www.softwareverify.com/wp-content/uploads/2026/04/VisualStudioLocals.png 940w, https://www.softwareverify.com/wp-content/uploads/2026/04/VisualStudioLocals-300x93.png 300w, https://www.softwareverify.com/wp-content/uploads/2026/04/VisualStudioLocals-768x239.png 768w" sizes="auto, (max-width: 940px) 100vw, 940px" /></p>
<p>The <strong>Debug &gt; Watch (1..4)</strong> views allow you to specify which variables and parameters you wish to inspect.</p>
<p><img loading="lazy" decoding="async" class="alignnone size-full wp-image-12963" src="https://www.softwareverify.com/wp-content/uploads/2026/04/VisualStudioWatch.png" alt="Visual Studio Watch view" width="940" height="295" srcset="https://www.softwareverify.com/wp-content/uploads/2026/04/VisualStudioWatch.png 940w, https://www.softwareverify.com/wp-content/uploads/2026/04/VisualStudioWatch-300x94.png 300w, https://www.softwareverify.com/wp-content/uploads/2026/04/VisualStudioWatch-768x241.png 768w" sizes="auto, (max-width: 940px) 100vw, 940px" /></p>
<h4>Minidump Browser</h4>
<p>The <strong>Exception</strong> view can&#8217;t display local variables or parameters, but all the registers from the exception CONTEXT are displayed on the <strong>Registers</strong> tab.</p>
<p><img loading="lazy" decoding="async" class="alignnone size-full wp-image-12965" src="https://www.softwareverify.com/wp-content/uploads/2026/04/MinidumpBrowserRegisters.png" alt="Minidump Browser Registers" width="871" height="516" srcset="https://www.softwareverify.com/wp-content/uploads/2026/04/MinidumpBrowserRegisters.png 871w, https://www.softwareverify.com/wp-content/uploads/2026/04/MinidumpBrowserRegisters-300x178.png 300w, https://www.softwareverify.com/wp-content/uploads/2026/04/MinidumpBrowserRegisters-768x455.png 768w" sizes="auto, (max-width: 871px) 100vw, 871px" /></p>
<h2>Automating crash analysis in your workflow</h2>
<p>Manual analysis works for occasional crashes. If you&#8217;re running automated tests or collecting crashes from production, you&#8217;ll want to automate the analysis too.</p>
<h3>Running analysis from the command line</h3>
<p>Most crash analysis tools support command-line operation. You can pass a dump file path, specify symbol locations, and request specific output—like extracting just the faulting call stack. This lets you script analysis without opening a GUI.</p>
<p>For example, you might write a script that extracts the top ten stack frames from every dump in a directory and writes them to a summary file.</p>
<h4>WinDbg</h4>
<p>Rather than run <strong>windbg.exe</strong> from the command line, it is better to run <strong>cdb.exe</strong> from the command line. This is the console version of WinDbg.</p>
<p>We capture the output of <strong>cdb.exe</strong> and pipe it to a file.</p>
<p>To run from the command line we use:</p>
<table style="border-collapse: collapse; width: 100%;">
<tbody>
<tr>
<td style="width: 11.3655%;"><strong>-z</strong></td>
<td style="width: 88.6345%;">specify the dmp file</td>
</tr>
<tr>
<td style="width: 11.3655%;"><strong>-y</strong></td>
<td style="width: 88.6345%;">specify where to look for symbols</td>
</tr>
<tr>
<td style="width: 11.3655%;"><strong>-c</strong></td>
<td style="width: 88.6345%;">specify a list of commands to run</td>
</tr>
</tbody>
</table>
<p>This command line loads a minidump <strong>e:\buggyApp.dmp</strong> and exports it to a txt file.</p>
<div>The exported data contains the exception callstack, callstacks for all threads, the loaded modules list and the unloaded modules list.</div>
<pre>    cdb.exe -z E:\buggyApp.dmp -y e:\ -c "$$&lt;exportCommands.txt;Q" &gt; e:\buggyApp.txt</pre>
<p>The file <strong>exportCommands.txt</strong> contains the following commands:</p>
<table style="border-collapse: collapse; width: 99.8309%;">
<tbody>
<tr>
<td style="width: 11.6181%;"><strong>!analyze -v</strong></td>
<td style="width: 158.054%;">the exception callstack </td>
</tr>
<tr>
<td style="width: 11.6181%;"><strong>~*k</strong></td>
<td style="width: 158.054%;">callstacks for all threads </td>
</tr>
<tr>
<td style="width: 11.6181%;"><strong>lm</strong></td>
<td style="width: 158.054%;">the loaded modules list and the unloaded modules list</td>
</tr>
</tbody>
</table>
<p>Example log file output:</p>
<p><img loading="lazy" decoding="async" class="alignnone size-full wp-image-12992" src="https://www.softwareverify.com/wp-content/uploads/2026/04/minidumpExportWinDbg.png" alt="Exported data from the console version of WinDbg, cdb.exe" width="1005" height="990" srcset="https://www.softwareverify.com/wp-content/uploads/2026/04/minidumpExportWinDbg.png 1005w, https://www.softwareverify.com/wp-content/uploads/2026/04/minidumpExportWinDbg-300x296.png 300w, https://www.softwareverify.com/wp-content/uploads/2026/04/minidumpExportWinDbg-768x757.png 768w" sizes="auto, (max-width: 1005px) 100vw, 1005px" /></p>
<p>Here is a full list of WinDbg <a href="https://learn.microsoft.com/en-us/windows-hardware/drivers/debugger/windbg-command-line-options">command line options</a>.</p>
<h4>Minidump Browser</h4>
<p>To run from the command line we use:</p>
<table style="border-collapse: collapse; width: 100%; height: 184px;">
<tbody>
<tr style="height: 23px;">
<td style="width: 23.6053%; height: 23px;"><strong>/minidump</strong></td>
<td style="width: 76.3947%; height: 23px;">Specify the full path to the minidump or kernel dump</td>
</tr>
<tr style="height: 23px;">
<td style="width: 23.6053%; height: 23px;"><strong>/exportFormat</strong></td>
<td style="width: 76.3947%; height: 23px;">Specify <strong>txt</strong> or <strong>html</strong> format</td>
</tr>
<tr style="height: 23px;">
<td style="width: 23.6053%; height: 23px;"><strong>/exportFileName</strong></td>
<td style="width: 76.3947%; height: 23px;">Specify the full path to the exported file</td>
</tr>
<tr style="height: 23px;">
<td style="width: 23.6053%; height: 23px;"><strong>/exportBugCheck</strong></td>
<td style="width: 76.3947%; height: 23px;">Export BugCheck information (kernel dumps only)</td>
</tr>
<tr style="height: 23px;">
<td style="width: 23.6053%; height: 23px;"><strong>/exportExceptionCallstack</strong></td>
<td style="width: 76.3947%; height: 23px;">Export Exception information if present (may not be present in some minidumps)</td>
</tr>
<tr style="height: 23px;">
<td style="width: 23.6053%; height: 23px;"><strong>/exportAllThreadsCallstack</strong></td>
<td style="width: 76.3947%; height: 23px;">Export all thread callstacks (minidumps only)</td>
</tr>
<tr style="height: 23px;">
<td style="width: 23.6053%; height: 23px;"><strong>/exportLoadedModules</strong></td>
<td style="width: 76.3947%; height: 23px;">Export all loaded modules</td>
</tr>
<tr style="height: 23px;">
<td style="width: 23.6053%; height: 23px;"><strong>/exportUnloadedModules</strong></td>
<td style="width: 76.3947%; height: 23px;">Export all unloaded modules</td>
</tr>
<tr style="height: 23px;">
<td style="width: 23.6053%; height: 23px;"><strong>/exportRegisters</strong></td>
<td style="width: 76.3947%; height: 23px;">Exports all the registers in the exception context, if there is an exception</td>
</tr>
<tr style="height: 23px;">
<td style="width: 23.6053%; height: 23px;"><strong>/verbose</strong></td>
<td style="width: 76.3947%; height: 23px;">If running on a command prompt, prints a lot of information related to downloading DLLs/PDBs and finding symbol definitions</td>
</tr>
</tbody>
</table>
<p>This command line loads a minidump <strong>e:\buggyApp.dmp</strong> and exports it to a html file. The export contains the exception callstack, callstacks for all threads, the loaded modules list and the unloadedmodules list.</p>
<pre>    minidumpBrowser_x64.exe /minidump E:\buggyApp.dmp /exportFormat html /exportFileName e\buggyApp.html /exportExceptionCallstack /exportAllThreadsCallstack /exportLoadedModules /exportUnloadedModules</pre>
<p>This command line loads a kernel dump <strong>e:\buggyDriver.dmp</strong> and exports it to a txt file. The export contains bugcheck information, the exception callstack, the loaded modules list and the unloadedmodules list.</p>
<pre>    minidumpBrowser_x64.exe /minidump E:\buggyDriver.dmp /exportFormat txt /exportFileName e\buggyDriver.txt /exportBugCheck /exportExceptionCallstack /exportLoadedModules /exportUnloadedModules</pre>
<p>Example log file output:</p>
<p><img loading="lazy" decoding="async" class="alignnone size-full wp-image-12993" src="https://www.softwareverify.com/wp-content/uploads/2026/04/miniDumpExport.png" alt="Exported data from Minidump Browser" width="1000" height="517" srcset="https://www.softwareverify.com/wp-content/uploads/2026/04/miniDumpExport.png 1000w, https://www.softwareverify.com/wp-content/uploads/2026/04/miniDumpExport-300x155.png 300w, https://www.softwareverify.com/wp-content/uploads/2026/04/miniDumpExport-768x397.png 768w" sizes="auto, (max-width: 1000px) 100vw, 1000px" /></p>
<p>Here is a a full list of Minidump Browser <a href="https://www.softwareverify.com/documentation/html/miniDumpBrowser/command-line.html">command line options</a>.</p>
<h3>Integrating with CI and test suites</h3>
<p>When automated tests crash, you can capture dumps and analyze them as part of the build pipeline. The analysis output becomes part of the test report, so developers see the call stack alongside the test failure.</p>
<p>With Splunk research showing <a href="https://www.techtarget.com/searchcloudcomputing/feature/Cloud-outages-expected-to-be-the-new-normal-in-2026">downtime costing an average of $9,000 per minute</a>, this approach speeds up debugging significantly. Instead of reproducing the crash locally, you can often diagnose it directly from the CI output.</p>
<h3>Generating crash reports automatically</h3>
<p>If you&#8217;re collecting crashes from production or from large test runs, batch processing becomes practical. You can iterate through a <a href="https://www.softwareverify.com/product/minidump-manager/">directory of dump files</a>, extract key information from each, and generate summary reports showing patterns—like the same crash occurring across multiple machines or test configurations.</p>
<blockquote>
<p><strong>Tip:</strong> Software Verify&#8217;s minidump tools support both GUI and command-line operation, so you can investigate interactively or automate analysis in your CI pipeline.</p>
</blockquote>
<h2>How to choose a crash analysis tool</h2>
<p>Different compilers produce different debug information formats. A tool built for MSVC symbols may not handle GCC&#8217;s DWARF format, and vice versa.</p>
<p>Check that your tool supports the compilers you actually use—whether that&#8217;s Visual Studio, C++ Builder, MinGW, Clang, Intel, Delphi, Fortran, or something else.</p>
<p>The following table describes the symbol types supported by each tool.</p>
<table style="border-collapse: collapse; width: 100%;">
<thead>
<tr>
<th style="width: 17.9434%;">Tool</th>
<th style="width: 82.0566%;">Debug Information Types</th>
</tr>
</thead>
<thead>
<tr>
<td style="width: 17.9434%;">WinDbg</td>
<td style="width: 82.0566%;">PDB</td>
</tr>
<tr>
<td style="width: 17.9434%;">Visual Studio</td>
<td style="width: 82.0566%;">PDB</td>
</tr>
<tr>
<td style="width: 17.9434%;">Minidump Browser</td>
<td style="width: 82.0566%;">PDB, TDS, DWARF, STABS, COFF, Metrowerks</td>
</tr>
</thead>
</table>
<p>Minidump Browser is part of a group of related <a href="https://www.softwareverify.com/products/#minidump">minidump tools</a> to allow you to create, find, manage, explore and visualize minidumps.</p>
<table style="border-collapse: collapse; width: 100%; height: 138px;">
<thead>
<tr style="height: 23px;">
<th style="width: 17.9434%; height: 23px;">Tool</th>
<th style="width: 82.0566%; height: 23px;">Task</th>
</tr>
</thead>
<tbody>
<tr style="height: 23px;">
<td style="width: 17.9434%; height: 23px;"><a href="https://www.softwareverify.com/product/exception-tracer/">Exception Tracer</a></td>
<td style="width: 82.0566%; height: 23px;">Create minidumps</td>
</tr>
<tr style="height: 23px;">
<td style="width: 17.9434%; height: 23px;"><a href="https://www.softwareverify.com/product/event-log-crash-browser/">Event Log Crash Browser</a></td>
<td style="width: 82.0566%; height: 23px;">Find minidumps from the Windows event log</td>
</tr>
<tr style="height: 23px;">
<td style="width: 17.9434%; height: 23px;"><a href="https://www.softwareverify.com/product/minidump-manager/">Minidump Manager</a></td>
<td style="width: 82.0566%; height: 23px;">Find minidumps on your computer</td>
</tr>
<tr style="height: 23px;">
<td style="width: 17.9434%; height: 23px;"><a href="https://www.softwareverify.com/product/minidump-browser/">Minidump Browser</a></td>
<td style="width: 82.0566%; height: 23px;">Explore minidumps and view crash information</td>
</tr>
<tr style="height: 23px;">
<td style="width: 17.9434%; height: 23px;"><a href="https://www.softwareverify.com/product/virtual-memory-validator/">VM Validator</a></td>
<td style="width: 82.0566%; height: 23px;">Visualize minidump memory</td>
</tr>
</tbody>
</table>
<h2>FAQs about crash analysis tools</h2>
<h3>What is the difference between a minidump and a full memory dump?</h3>
<p>A minidump contains thread stacks, module lists, and exception data in a compact file.</p>
<p>A full memory dump includes the entire process memory and can be gigabytes in size.</p>
<p>Minidumps are easier to collect and transfer; full dumps let you inspect any heap object.</p>
<h3>Can crash analysis tools work without source code?</h3>
<p>Yes. You can analyze call stacks and memory without source code, but you&#8217;ll want symbol files (PDBs) to see function names instead of raw addresses. Symbols don&#8217;t require source code—they&#8217;re generated during the build process.</p>
<h3>How large are typical crash dump files?</h3>
<p>Minidumps are usually a few hundred kilobytes to a few megabytes.</p>
<p>Full dumps can be gigabytes, depending on how much memory the process was using when it crashed.</p>
<h3>Do crash analysis tools support both 32-bit and 64-bit applications?</h3>
<p>Most modern tools handle both architectures. You&#8217;ll want matching symbol files, and some tools require you to use the correct bitness version of the tool itself.</p>
<h3>Can developers analyze crashes from release builds?</h3>
<p>Yes, if you generate and store PDB files for your release builds.</p>
<p>The common practice is to archive debug information (PDB, TDS, etc) alongside each release so you can analyze crashes from any shipped version.</p>
<p>The post <a href="https://www.softwareverify.com/blog/crash-analysis-tools-complete-guide-for-2026/">Crash Analysis Tools: Complete Guide for 2026</a> appeared first on <a href="https://www.softwareverify.com">Software Verify</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Stop using booleans, they&#8217;re hurting your code</title>
		<link>https://www.softwareverify.com/blog/stop-using-booleans-theyre-hurting-your-code/</link>
		
		<dc:creator><![CDATA[Stephen Kellett]]></dc:creator>
		<pubDate>Fri, 27 Feb 2026 13:10:17 +0000</pubDate>
				<category><![CDATA[Blog]]></category>
		<guid isPermaLink="false">https://www.softwareverify.com/?p=12882</guid>

					<description><![CDATA[<p>At Software Verify we&#8217;ve started to phase out the use of booleans in our code. The use of booleans hinders readability and maintainability of the [&#8230;]</p>
<p>The post <a href="https://www.softwareverify.com/blog/stop-using-booleans-theyre-hurting-your-code/">Stop using booleans, they&#8217;re hurting your code</a> appeared first on <a href="https://www.softwareverify.com">Software Verify</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>At Software Verify we&#8217;ve started to phase out the use of booleans in our code.</p>
<p>The use of booleans hinders readability and maintainability of the code.</p>
<p>The use of booleans also allow potential unwanted parameter reordering mistakes to occur.</p>
<p>Some bold claims. I will explain.</p>
<h2>Problem 1: Readability and maintainability</h2>
<p>If you saw this function call in your code what do you think it would do?</p>
<pre>    ok = attachExceptionTracerToRunningProcess(targetProcessId, TRUE, FALSE, _T("d:\\Exception Tracer"));
</pre>
<p>To find out we&#8217;d need to look at the function prototype, or the documentation. Most likely you&#8217;re is going to right click in Visual Studio and ask to see the function definition, or a tooltip is going to tell you what the argument names are. </p>
<p>Here&#8217;s the function definition:</p>
<pre>    int attachExceptionTracerToRunningProcess(const DWORD  processId,
                                              const bool   processBitDepth,
                                              const bool   singleStep,
                                              const TCHAR* dir);
</pre>
<p>To use this function you need to pass a process id, a directory path and two boolean values.</p>
<p>We can guess that passing <span style="font-family: 'courier new', courier, monospace;">TRUE</span> for <span style="font-family: 'courier new', courier, monospace;">singleStep</span> will start Exception Tracer in single stepping mode. But that&#8217;s implied, it&#8217;s not explicit.</p>
<p>But <span style="font-family: 'courier new', courier, monospace;">processBitDepth</span>, what does that do? You&#8217;ll need to read the documentation for that : <span style="font-family: 'courier new', courier, monospace;">FALSE</span> starts 32 bit Exception Tracer, and <span style="font-family: 'courier new', courier, monospace;">TRUE</span> starts 64 bit Exception Tracer.</p>
<p>Reading documentation is not a problem, but it doesn&#8217;t make your code very readable does it? It slows things down. </p>
<h3>Swap booleans for enumerations</h3>
<p>If we swap the bools for typedef&#8217;d enumerations then we get something more readable for the function definition:</p>
<pre>    typedef enum _processBitDepth
    {
        PROCESS_BIT_DEPTH_32,
        PROCESS_BIT_DEPTH_64,
    } PROCESS_BIT_DEPTH;

    typedef enum _doSingleStep
    {
        DO_SINGLE_STEP_NO,
        DO_SINGLE_STEP_YES,
    } DO_SINGLE_STEP;

    int attachExceptionTracerToRunningProcess(const DWORD             processId,
                                              const PROCESS_BIT_DEPTH processBitDepth,
                                              const DO_SINGLE_STEP    singleStep,
                                              const TCHAR*            dir);
</pre>
<p>Now the function call becomes:</p>
<pre>    ok = attachExceptionTracerToRunningProcess(targetProcessId, PROCESS_BIT_DEPTH_64, DO_SINGLE_STEP_NO, _T("d:\\Exception Tracer"));
</pre>
<p>and the purpose of the function arguments is explicit rather than implied.</p>
<h3>Different styles</h3>
<p>You don&#8217;t need to just use YES and NO, you can use what ever nomenclature feels correct for the situation:</p>
<pre>    typedef enum _doSingleStep
    {
        DO_SINGLE_STEP_NO,
        DO_SINGLE_STEP_YES,
    } DO_SINGLE_STEP;

    typedef enum _doSingleStep
    {
        DO_SINGLE_STEP_OFF,
        DO_SINGLE_STEP_ON,
    } DO_SINGLE_STEP;

    typedef enum _doSingleStep
    {
        DO_SINGLE_STEP_DISABLE,
        DO_SINGLE_STEP_ENABLE,
    } DO_SINGLE_STEP;

    typedef enum _doSingleStep
    {
        DO_SINGLE_STEP_STOP,
        DO_SINGLE_STEP_GO,
    } DO_SINGLE_STEP;
</pre>
<p>If you really feel TRUE/FALSE are appropriate you can do that as well. Which seems a bit odd, until you see Problem 2 and Problem 3.</p>
<pre>    typedef enum _doSingleStep
    {
        DO_SINGLE_STEP_FALSE,
        DO_SINGLE_STEP_TRUE,
    } DO_SINGLE_STEP;
</pre>
<h2>Problem 2: Implicit casting</h2>
<p>If you are using bools, many types (char, int, enumerations, etc) can implicitly convert to them without you needing to use a cast statement. This can be convenient, but it&#8217;s also an avenue for bugs.</p>
<p>If you&#8217;re using typedef&#8217;d enumerations, these implicit type conversions fail to compile.</p>
<p>You really want to be explicit about any type conversions.</p>
<h2>Problem 3: Unwanted parameter reordering</h2>
<p>If you are passing parameters through multiple functions before they finally reach the intended function it&#8217;s possible that a future edit (such as refactoring a function&#8217;s parameters) may reorder some parameters and a mistake is made during the updating of calls to the refactored function which results in parameters passed to the new function definition have been unintentionally reordered.</p>
<p>This happened to us with some boolean parameters in our code instrumentation library. We discovered the mistake when we switched to using enumerations because now each of these parameters has it&#8217;s own type.</p>
<h3>Incorrect, but compiles</h3>
<p>With the old function definition, this example will compile, but the parameters have been incorrectly switched, leading to incorrect behaviour.</p>
<pre>    int attachExceptionTracerToRunningProcess(const DWORD  processId,
                                              const bool   processBitDepth,
                                              const bool   singleStep,
                                              const TCHAR* dir);

    int doStartup(const DWORD  processId,
                  const bool   processBitDepth,
                  const bool   singleStep,
                  const TCHAR* dir)
    {
        int ok;

        ok = attachExceptionTracerToRunningProcess(processId, singleStep, processBitDepth, _T("d:\\Exception Tracer"));
    }
</pre>
<h3>Incorrect, but fails to compile</h3>
<p>With the new function definition, this example will fail to compile.</p>
<pre>    int attachExceptionTracerToRunningProcess(const DWORD             processId,
                                              const PROCESS_BIT_DEPTH processBitDepth,
                                              const DO_SINGLE_STEP    singleStep,
                                              const TCHAR*            dir);

    int doStartup(const DWORD             processId,
                  const PROCESS_BIT_DEPTH processBitDepth,
                  const DO_SINGLE_STEP    singleStep,
                  const TCHAR*            dir)
    {
        int ok;

        ok = attachExceptionTracerToRunningProcess(processId, singleStep, processBitDepth, _T("d:\\Exception Tracer"));
    }
</pre>
<h2>Making the change</h2>
<p>It&#8217;s a bit more work to create the enumeration and use it.</p>
<p>With an existing code base it can be time consuming work depending on the number of occurrences of the new enumerated type in your code base.</p>
<h3>One type at a time</h3>
<p>If you are going to make this change I would recommend changing one parameter type at a time and doing a build after each type change.</p>
<p>This seems more time consuming, but in practice we&#8217;ve found it&#8217;s easier than making multiple new types and then trying to build and dealing with the chaos that results until you&#8217;ve fixed up all the function definitions etc.</p>
<p>If, like us, you&#8217;ve got many solutions and many projects in each solution then the quickest way to do these builds is to load the solutions/projects into <a href="https://www.softwareverify.com/product/visual-studio-project-builder/">Visual Studio Project Builder</a> then build all projects of a specific configuration. This saves a lot of time.</p>
<h3>Should we change our whole codebase?</h3>
<p>There are certainly benefits to doing this. You might find some errors where parameters have been passed in the wrong order.</p>
<p>But for large codebases, changing every boolean use is probably impractical (it will take a long time). The best approach is to change them when you&#8217;re editing some code that is using them.</p>
<h2>Conclusion</h2>
<p>As you can see there are multiple benefits to using enumerations rather than booleans in your code.</p>
<p>You get improved readability and improved type safety.</p>
<p>The post <a href="https://www.softwareverify.com/blog/stop-using-booleans-theyre-hurting-your-code/">Stop using booleans, they&#8217;re hurting your code</a> appeared first on <a href="https://www.softwareverify.com">Software Verify</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Secure Admin Service</title>
		<link>https://www.softwareverify.com/blog/secure-admin-service/</link>
		
		<dc:creator><![CDATA[Stephen Kellett]]></dc:creator>
		<pubDate>Thu, 19 Feb 2026 16:07:53 +0000</pubDate>
				<category><![CDATA[Blog]]></category>
		<guid isPermaLink="false">https://www.softwareverify.com/?p=12851</guid>

					<description><![CDATA[<p>This article explains the recent changes to the SVL Admin Service and to the SVL Build Service to make our tools and our services much [&#8230;]</p>
<p>The post <a href="https://www.softwareverify.com/blog/secure-admin-service/">Secure Admin Service</a> appeared first on <a href="https://www.softwareverify.com">Software Verify</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>This article explains the recent changes to the SVL Admin Service and to the SVL Build Service to make our tools and our services much more secure.</p>
<h2>History</h2>
<h3>April 2002 to May 2014</h3>
<p>All actions required by a Software Verify Tool were performed directly by that tool. </p>
<h3>May 2014</h3>
<p>SVL Admin Service provides functionality for various Software Verify tools that these tools cannot do running as a standard user application. </p>
<p>We wrote about this work as <a href="https://www.softwareverify.com/blog/an-end-to-unwanted-uac-prompts/">&#8220;An end to unwanted UAC prompts&#8221;</a>.</p>
<h3>February 2024</h3>
<p>During February 2024 ago we changed all the access controls on files and pipes that our tools and services use to restrict access to just the users that need to use them.</p>
<h2>The problem we wanted to solve</h2>
<p>We wanted to prevent the SVL Admin Service and the SVL Build Service from being used by bad actors as a means to attack a computer.</p>
<p>To do this we have:</p>
<ul>
<li>Encrypted the communication between any Software Verify tool and the SVL Admin Service.</li>
<li>Encrypted the communication between Visual Studio Project Builder and the SVL Build Service.</li>
<li>We&#8217;ve also replaced any commands that had the potential for abuse with commands dedicated to specific tasks that can&#8217;t be changed to something malicious.</li>
<li>We&#8217;ve also added command verification steps to ensure the appropriate digital signatures are present before we execute them or copy them.</li>
</ul>
<h2>Why we&#8217;ve made this change</h2>
<p>When we implemented the communication scheme between our tools and the SVL Admin Service we didn&#8217;t really think about the security implications as to use these pipes you&#8217;d need to know what data we send down them and have access to them as a user.</p>
<p>However, recent attacks on various computer systems, plus studying what malware authors are doing led us to conclude that we should encrypt our comms to make it very hard to monitor the comms between our tools and the service, and also make it very hard to send malicious commands to the service. The services now verify the calling application and all parameters and reject any command where the input parameters cannot be safely verified.</p>
<h2>Are my computers at risk?</h2>
<p>Software Verify&#8217;s footprint worldwide is quite small. Our tools are used worldwide, but we&#8217;re only used on developer machines and the occasional customer machine. Our tools aren&#8217;t like Notepad++ which is distributed massively around the world. Notepad++ is a great tool and that widespread distribution made it a prime candidate for an attack. This was one of the events which prompted us to improve the security of the SVL Admin Service and SVL Build Service.</p>
<p>Because our tools are not massively distributed, and are more than likely distributed on target machines that are not that valuable to a bad actor (not a C-suite machine), the ROI of attacking our tools now that we&#8217;ve made it much harder probably means it&#8217;s not worth attacking a machine hoping that our tools are installed on that machine. There are easier, more widely available targets for bad actors to go for.</p>
<p>That said, we strongly recommend updating to the most recent version of the tools released after 18/02/2026.</p>
<p><em>Please note: The <a href="https://www.softwareverify.com/products/#pythontools">Python tools</a> are legacy tools and cannot be updated. We&#8217;ll be releasing some Python capable tools to replace these later this year.</em></p>
<h2>When will this change happen?</h2>
<p>The SVL Admin Service will be upgraded when you install any of our tools downloaded from our website after 18/Feb/2026.</p>
<h2>Consequences</h2>
<p>The consequences of securing the comms between our tools and the SVL Admin Service are that once you&#8217;ve upgraded the service any already existing Software Verify tool that needs to use the SVL Admin service will be unable to communicate with the service because it will still be communicating with no encryption.</p>
<p>To fix this you will need to update each tool that uses the SVL Admin Service.</p>
<p>You can do this by:</p>
<ul>
<li>Running the tool and doing <strong>Check for Updates&#8230;</strong> from the <strong>Software Updates</strong> menu</li>
<li>For free tools: Go to the appropriate <a href="https://www.softwareverify.com/products/">software tool page</a> and download the tool again, then install it</li>
<li>For commercial tools: Login to the authorised downloads area and download the tool and install. Check your email for details</li>
</ul>
<h2>What happens if I continue trying to use a tool without updating it?</h2>
<p>The tool you are using may work for many of it&#8217;s actions, but any action that requires communicating with the SVL Admin Service will fail.</p>
<p>Any tool that tries to communicate with the encrypted SVL Admin Service without being updated will be shown this message.</p>
<p><img loading="lazy" decoding="async" class="alignnone size-full wp-image-12858" src="https://www.softwareverify.com/wp-content/uploads/2026/02/InstallSecureServiceWarning.png" alt="Message about failing to communicate with the SVL Admin Service" width="316" height="258" srcset="https://www.softwareverify.com/wp-content/uploads/2026/02/InstallSecureServiceWarning.png 316w, https://www.softwareverify.com/wp-content/uploads/2026/02/InstallSecureServiceWarning-300x245.png 300w" sizes="auto, (max-width: 316px) 100vw, 316px" /></p>
<p>If you see this dialog, choose <strong>No</strong>, then update the tool you are trying to use by downloading a new version from the website.</p>
<h2>How do I know which tools to update?</h2>
<p>All our tool installers ship with a small utility which will check your machine for previous installs of our tools. These will be checked to determine if they can communicate securely with the SVL Admin Service. If they cannot communicate securely the utility will display a dialog box listing the names of the tool you need to update.</p>
<p><img loading="lazy" decoding="async" class="alignnone size-full wp-image-12856" src="https://www.softwareverify.com/wp-content/uploads/2026/02/InstallSecureServiceChecker.png" alt="Install Secure Service Checker" width="850" height="523" srcset="https://www.softwareverify.com/wp-content/uploads/2026/02/InstallSecureServiceChecker.png 850w, https://www.softwareverify.com/wp-content/uploads/2026/02/InstallSecureServiceChecker-300x185.png 300w, https://www.softwareverify.com/wp-content/uploads/2026/02/InstallSecureServiceChecker-768x473.png 768w" sizes="auto, (max-width: 850px) 100vw, 850px" /></p>
<h2>What should I do next?</h2>
<p>Find all Software Verify tools installed on your computers and update all of them to the most recent version.</p>
<p>&nbsp;</p>
<p>The post <a href="https://www.softwareverify.com/blog/secure-admin-service/">Secure Admin Service</a> appeared first on <a href="https://www.softwareverify.com">Software Verify</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Setting up ISAPI (and ASP.Net) on IIS 10</title>
		<link>https://www.softwareverify.com/blog/setting-up-isapi-on-iis-10/</link>
					<comments>https://www.softwareverify.com/blog/setting-up-isapi-on-iis-10/#respond</comments>
		
		<dc:creator><![CDATA[Stephen Kellett]]></dc:creator>
		<pubDate>Thu, 15 May 2025 10:50:01 +0000</pubDate>
				<category><![CDATA[Hints and tips]]></category>
		<category><![CDATA[iis 10]]></category>
		<category><![CDATA[isapi]]></category>
		<category><![CDATA[windows 10]]></category>
		<guid isPermaLink="false">https://blog.softwareverify.com/?p=2457</guid>

					<description><![CDATA[<p>Introduction OK so it&#8217;s 2020 and how many people are developing ISAPI extensions? More than you might imagine. Yeah, Ruby on Rails and Rust are [&#8230;]</p>
<p>The post <a href="https://www.softwareverify.com/blog/setting-up-isapi-on-iis-10/">Setting up ISAPI (and ASP.Net) on IIS 10</a> appeared first on <a href="https://www.softwareverify.com">Software Verify</a>.</p>
]]></description>
										<content:encoded><![CDATA[<h2>Introduction</h2>
<p>OK so it&#8217;s 2020 and how many people are developing ISAPI extensions? More than you might imagine. Yeah, Ruby on Rails and Rust are all the rage these days, but some people still need to work with ISAPI for a bunch of business reasons.</p>
<p>I recently had to setup IIS 10 with ISAPI on Windows 10. I read a lot of articles on how to do it. None of them were complete, resulting in reading several articles to get something working, so I put this together, mainly for my own benefit (because I really don&#8217;t need to spend that much time doing this again!). I&#8217;m sharing it so you don&#8217;t have to go through this. </p>
<p>I was trying to get a simple ISAPI extension to work before trying anything else. My guess is most of you are working on legacy code, but a few of you may have been instructed to write a new ISAPI. Here&#8217;s a good starting point for a simple ISAPI extension if you haven&#8217;t already written one.</p>
<p>Creating an ISAPI extension: <a href="https://www.codeproject.com/Articles/1432/What-is-an-ISAPI-Extension">https://www.codeproject.com/Articles/1432/What-is-an-ISAPI-Extension</a></p>
<h3>ASP.Net</h3>
<p>I&#8217;m also going to very briefly mention installing ASP.Net as well.</p>
<h3>32 bit ISAPI</h3>
<p>There&#8217;s an interesting gotcha if you&#8217;re developing a 32 bit ISAPI extension. Don&#8217;t worry I cover that at the end.</p>
<h3>Windows 10 and Windows 11</h3>
<p>The instructions in this article work for both Windows 10 and Windows 11. The process is identical on both operating systems.</p>
<h2>Installing IIS components</h2>
<p>IIS components are installed via the Windows features dialog.</p>
<p>In the Windows 10 search box type <em>&#8220;Turn Windows features on and off&#8221;</em>, when windows shows you the result that matches press return (or click it).</p>
<p><img loading="lazy" decoding="async" class="alignleft size-full wp-image-2459" src="https://www.softwareverify.com/wp-content/uploads/2020/04/TurnWindowsFeaturesOnAndOff.png" alt="Turn Windows features on and off" width="1152" height="680" /><br />
<br clear="all" />
</p>
<p>The feature selection box is displayed. Select the items highlighted red in the image shown below. Click OK.</p>
<p><img loading="lazy" decoding="async" class="alignnone size-full wp-image-11384" src="https://www.softwareverify.com/wp-content/uploads/2020/04/turn-windows-features-on-or-off.png" alt="Turn Windows features on or off ISAPI and ASP.NET" width="415" height="570" srcset="https://www.softwareverify.com/wp-content/uploads/2020/04/turn-windows-features-on-or-off.png 415w, https://www.softwareverify.com/wp-content/uploads/2020/04/turn-windows-features-on-or-off-218x300.png 218w" sizes="auto, (max-width: 415px) 100vw, 415px" /><br />
<br clear="all" />
</p>
<p>If you&#8217;ve already got partway through configuring IIS Manager and have realised you don&#8217;t have all the required components installed that&#8217;s OK, just install them and then close IIS Manager and reopen it (I found that if I didn&#8217;t do that not all the component parts would show in IIS Manager, making finding (for example) ISAPI and CGI Restrictions impossible.</p>
<h3>ASP.Net</h3>
<p>If you&#8217;re working with ASP.Net, enable the items above that are identified as ASP.NET and the .Net Extensibility options as well.</p>
<h2>Configuring IIS Manager</h2>
<p>Start Internet Information Services Manager.</p>
<p>In the Windows 10 search box type <em>&#8220;Internet Information Services Manager&#8221;</em>, when windows shows you the result that matches press return (or click it).</p>
<p><img loading="lazy" decoding="async" class="alignnone size-full wp-image-11247" src="https://www.softwareverify.com/wp-content/uploads/2020/04/IIS-Start-Menu.png" alt="Start menu Internet Information Services Manager" width="834" height="683" srcset="https://www.softwareverify.com/wp-content/uploads/2020/04/IIS-Start-Menu.png 834w, https://www.softwareverify.com/wp-content/uploads/2020/04/IIS-Start-Menu-300x246.png 300w, https://www.softwareverify.com/wp-content/uploads/2020/04/IIS-Start-Menu-768x629.png 768w" sizes="auto, (max-width: 834px) 100vw, 834px" /></p>
<h3>Website</h3>
<p>First of all we need a website to work with. If you&#8217;ve already got one skip the next few lines.</p>
<ol>
<li>Add a test website. Right click on <em>&#8220;Sites&#8221;</em> in the left hand menu and choose <em>&#8220;Add Website&#8230;&#8221;
<p><img loading="lazy" decoding="async" class="alignnone size-full wp-image-11248" src="https://www.softwareverify.com/wp-content/uploads/2020/04/IIS-Sites-AddWebsite.png" alt="IIS context menu Add Website" width="319" height="184" srcset="https://www.softwareverify.com/wp-content/uploads/2020/04/IIS-Sites-AddWebsite.png 319w, https://www.softwareverify.com/wp-content/uploads/2020/04/IIS-Sites-AddWebsite-300x173.png 300w" sizes="auto, (max-width: 319px) 100vw, 319px" /><br />
</em></li>
<li>The Add Website dialog is displayed.
<p><img loading="lazy" decoding="async" class="alignnone size-full wp-image-11249" src="https://www.softwareverify.com/wp-content/uploads/2020/04/IIS-Sites-AddWebsite-Dialog.png" alt="IIS Add Website dialog" width="585" height="672" srcset="https://www.softwareverify.com/wp-content/uploads/2020/04/IIS-Sites-AddWebsite-Dialog.png 585w, https://www.softwareverify.com/wp-content/uploads/2020/04/IIS-Sites-AddWebsite-Dialog-261x300.png 261w" sizes="auto, (max-width: 585px) 100vw, 585px" /></li>
<li>Choose a website name. For example: <strong>&#8220;test&#8221;</strong>.</li>
<li>Choose a location for the website. For example: <strong>C:\testISAPIWebsite</strong></li>
<li>Change the port number (just for testing) so that it doesn&#8217;t conflict with any other sites you have. For example: <strong>81</strong>.</li>
<li><a href="https://www.softwareverify.com/blog/setting-directory-permissions-for-user-group-iis-iusrs/">Modify the security permissions for the directory</a> you specified in step 4 to allow write and/or execute permissions if you need these permissions. </li>
</ol>
<h3 id="handlerMappings">Handler Mappings</h3>
<ol>
<li>Select the server node on the left hand side and double click click on Handler Mappings on the right hand size.
<p><img loading="lazy" decoding="async" class="alignleft size-full wp-image-2460" src="https://www.softwareverify.com/wp-content/uploads/2020/04/HandlerMappings.png" alt="IIS handler mappings" width="1137" height="457" /></p>
</li>
<li>The handler mappings are displayed.
<p><img loading="lazy" decoding="async" class="alignleft size-full wp-image-2461" src="https://www.softwareverify.com/wp-content/uploads/2020/04/HandlerMappingsValues.png" alt="IIS handler mappings values" width="816" height="319" /><br />
<br clear="all" />
</p>
</li>
<li>Right click in empty space and choose <em>&#8220;Edit Feature Permissions&#8230;&#8221;</em>.
<p><img loading="lazy" decoding="async" class="alignnone size-full wp-image-11254" src="https://www.softwareverify.com/wp-content/uploads/2020/04/IIS-Edit-Feature-Permissions.png" alt="IIS Edit Feature Permissions" width="215" height="191" /></li>
<li>The Edit Feature Permissions dialog is displayed. Enable <strong>Read</strong>, <strong>Script</strong> and <strong>Execute</strong> permissions. When you select the execute check box you&#8217;ll notice the entry for ISAPI dlls is added to the displayed Handler Mappings. Click OK.
<p><img loading="lazy" decoding="async" class="alignleft size-full wp-image-2462" src="https://www.softwareverify.com/wp-content/uploads/2020/04/EditFeaturePermissions.png" alt="Edit feature permissions" width="770" height="471" /><br />
<br clear="all" />
</p>
</li>
</ol>
<h3 id="SoftwareRestrictions">ISAPI and CGI Restrictions</h3>
<ol>
<li>Select the server node on the left hand side and double click click on <em>&#8220;ISAPI and CGI Restrictions&#8221;</em> on the right hand size.
<p><img loading="lazy" decoding="async" class="alignnone size-full wp-image-11250" src="https://www.softwareverify.com/wp-content/uploads/2020/04/IIS-CGI-ISAPI-Restrictions.png" alt="IIS CGI-ISAPI restrictions" width="1424" height="750" srcset="https://www.softwareverify.com/wp-content/uploads/2020/04/IIS-CGI-ISAPI-Restrictions.png 1424w, https://www.softwareverify.com/wp-content/uploads/2020/04/IIS-CGI-ISAPI-Restrictions-300x158.png 300w, https://www.softwareverify.com/wp-content/uploads/2020/04/IIS-CGI-ISAPI-Restrictions-1024x539.png 1024w, https://www.softwareverify.com/wp-content/uploads/2020/04/IIS-CGI-ISAPI-Restrictions-768x404.png 768w" sizes="auto, (max-width: 1424px) 100vw, 1424px" /></li>
<li>Right click in empty space and choose <em>&#8220;Add&#8230;&#8221;</em>.
<p><img loading="lazy" decoding="async" class="alignnone size-full wp-image-11251" src="https://www.softwareverify.com/wp-content/uploads/2020/04/IIS-CGI-ISAPI-Add.png" alt="IIS GCI-ISAPI restrictions Add" width="191" height="81" /></li>
<li>Add the path to your ISAPI dll, a description and select the check box so that it is allowed to execute. Click OK.
<p><img loading="lazy" decoding="async" class="alignleft size-full wp-image-2464" src="https://www.softwareverify.com/wp-content/uploads/2020/04/ISAPIandCGIRestrictionsAdd.png" alt="ISAPI and CGI restrictions" width="583" height="431" /><br />
<br clear="all" />
</p>
</li>
<li>
<p>This will place a web.config in the directory that contains the DLL. It will look something like this:</p>
<pre>&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;configuration&gt;
    &lt;system.webServer&gt;
        &lt;handlers accessPolicy="Read, Execute, Script"&gt;
            &lt;remove name="ISAPI-dll" /&gt;
            &lt;add name="ISAPI-dll" path="*.dll" verb="*" modules="IsapiModule" scriptProcessor="C:\testISAPIWebsite\validate.dll" resourceType="File" requireAccess="Execute" allowPathInfo="true" preCondition="bitness32" /&gt;
        &lt;/handlers&gt;
    &lt;/system.webServer&gt;
&lt;/configuration&gt;
</pre>
</li>
</ol>
<h3 id="32bit">32 bit ISAPI extensions</h3>
<p>If your ISAPI is 32 bit you&#8217;ll need to enable them. Go to application pools (under the server node), select the application pool that your website is in, right click, choose <em>&#8220;Advanced Settings&#8230;&#8221;</em>.</p>
<p><img loading="lazy" decoding="async" class="alignnone size-full wp-image-11645" src="https://www.softwareverify.com/wp-content/uploads/2020/04/IIS-ApplicationPools-AdvancedSettings.png" alt="IIS Application Pools Advanced Settings" width="832" height="660" srcset="https://www.softwareverify.com/wp-content/uploads/2020/04/IIS-ApplicationPools-AdvancedSettings.png 832w, https://www.softwareverify.com/wp-content/uploads/2020/04/IIS-ApplicationPools-AdvancedSettings-300x238.png 300w, https://www.softwareverify.com/wp-content/uploads/2020/04/IIS-ApplicationPools-AdvancedSettings-768x609.png 768w" sizes="auto, (max-width: 832px) 100vw, 832px" /></p>
<p>Change the <em>&#8220;Enable 32-Bit Applications&#8221;</em> setting to <strong>True</strong>.</p>
<p><img loading="lazy" decoding="async" class="alignnone size-full wp-image-11648" src="https://www.softwareverify.com/wp-content/uploads/2020/04/IIS-ISAPI-32bit-Extensions.png" alt="IIS ISAPI 32 bit extensions" width="432" height="541" srcset="https://www.softwareverify.com/wp-content/uploads/2020/04/IIS-ISAPI-32bit-Extensions.png 432w, https://www.softwareverify.com/wp-content/uploads/2020/04/IIS-ISAPI-32bit-Extensions-240x300.png 240w" sizes="auto, (max-width: 432px) 100vw, 432px" /></p>
<h3 id="64bit">64 bit ISAPI extensions</h3>
<p>If your ISAPI is 64 bit you&#8217;ll need to ensure that you haven&#8217;t got 32 bit extensions enabled. Go to application pools (under the server node), select the application pool that your website is in, right click, choose <em>&#8220;Advanced Settings&#8230;&#8221;</em>. Change the <em>&#8220;Enable 32-Bit Applications&#8221;</em> setting to <strong>False</strong>.</p>
<p><img loading="lazy" decoding="async" class="alignnone size-full wp-image-11649" src="https://www.softwareverify.com/wp-content/uploads/2020/04/IIS-ISAPI-64bit-Extensions.png" alt="IIS ISAPI 64 bit extensions" width="434" height="541" srcset="https://www.softwareverify.com/wp-content/uploads/2020/04/IIS-ISAPI-64bit-Extensions.png 434w, https://www.softwareverify.com/wp-content/uploads/2020/04/IIS-ISAPI-64bit-Extensions-241x300.png 241w" sizes="auto, (max-width: 434px) 100vw, 434px" /></p>
<h2>Trying out the website</h2>
<p>If we assume your ISAPI is called <strong>validate.dll</strong> you should be able to test your ISAPI in a browser using <strong>http://localhost:81/validate.dll?12345678</strong></p>
<h3>Authentication problems</h3>
<p>If when trying to view your web pages you get strange error messages, select the server node on the left then go to <em>&#8220;Feature Delegation&#8221;</em> and turn any entries that are <em>&#8220;Read only&#8221;</em> to <em>&#8220;Read/Write&#8221;</em>. Then restart the server (top of the right hand bar).</p>
<p><img loading="lazy" decoding="async" class="alignnone size-full wp-image-11252" src="https://www.softwareverify.com/wp-content/uploads/2020/04/IIS-Feature-Delegation.png" alt="IIS Feature Delegation" width="1424" height="750" srcset="https://www.softwareverify.com/wp-content/uploads/2020/04/IIS-Feature-Delegation.png 1424w, https://www.softwareverify.com/wp-content/uploads/2020/04/IIS-Feature-Delegation-300x158.png 300w, https://www.softwareverify.com/wp-content/uploads/2020/04/IIS-Feature-Delegation-1024x539.png 1024w, https://www.softwareverify.com/wp-content/uploads/2020/04/IIS-Feature-Delegation-768x404.png 768w" sizes="auto, (max-width: 1424px) 100vw, 1424px" /></p>
<p>Note that I&#8217;m assuming you&#8217;re working on a Dev machine. If you&#8217;re working on a production machine you might want to be a bit less cavalier than just turning all settings to Read/Write &#8211; work through them one at a time to find out what you need and change only that.</p>
<h3>Directory Permissions</h3>
<p>If you&#8217;re having problems with directory permissions that aren&#8217;t managed by IIS Manager you should read this article about changing <a href="https://www.softwareverify.com/blog/setting-directory-permissions-for-user-group-iis-iusrs/">directory permissions for IIS_IUSRS</a>.</p>
<h3>Server Errors</h3>
<p>If you&#8217;re getting error pages from the server describing various server errors you should take a look at <a href="https://www.softwareverify.com/blog/common-iis-server-errors/">Common IIS Server Errors</a>.</p>
<p>The post <a href="https://www.softwareverify.com/blog/setting-up-isapi-on-iis-10/">Setting up ISAPI (and ASP.Net) on IIS 10</a> appeared first on <a href="https://www.softwareverify.com">Software Verify</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.softwareverify.com/blog/setting-up-isapi-on-iis-10/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Failing email</title>
		<link>https://www.softwareverify.com/blog/failing-email/</link>
					<comments>https://www.softwareverify.com/blog/failing-email/#respond</comments>
		
		<dc:creator><![CDATA[Stephen Kellett]]></dc:creator>
		<pubDate>Tue, 18 Feb 2025 18:39:32 +0000</pubDate>
				<category><![CDATA[Blog]]></category>
		<guid isPermaLink="false">https://www.softwareverify.com/?p=12684</guid>

					<description><![CDATA[<p>Last week, from Thursday 13th February to the evening of Sunday 16th February our email servers were temporarily unreachable. This was caused by a failure [&#8230;]</p>
<p>The post <a href="https://www.softwareverify.com/blog/failing-email/">Failing email</a> appeared first on <a href="https://www.softwareverify.com">Software Verify</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>Last week, from Thursday 13th February to the evening of Sunday 16th February our email servers were temporarily unreachable.</p>
<p>This was caused by a failure with an upstream DNS provider.</p>
<p>After waiting for them to fix the problem for far too long we changed DNS providers. </p>
<p>We started receiving email again during late Sunday evening / early Monday.</p>
<p>If you tried to contact us and got a bounce message, this is the reason why.</p>
<p>Sorry for any inconvenience.</p>
<p>&nbsp;</p>
<p>The post <a href="https://www.softwareverify.com/blog/failing-email/">Failing email</a> appeared first on <a href="https://www.softwareverify.com">Software Verify</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.softwareverify.com/blog/failing-email/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>How to read embedded data from a resource</title>
		<link>https://www.softwareverify.com/blog/how-to-read-embedded-data-from-a-resource/</link>
		
		<dc:creator><![CDATA[Stephen Kellett]]></dc:creator>
		<pubDate>Wed, 22 Jan 2025 11:58:05 +0000</pubDate>
				<category><![CDATA[Hints and tips]]></category>
		<category><![CDATA[C]]></category>
		<category><![CDATA[embed]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[resource]]></category>
		<guid isPermaLink="false">http://www.softwareverify.com/software-verify-blog/?p=590</guid>

					<description><![CDATA[<p>In the previous article, I showed you how to embed data into a custom resource in your application. In this article, I&#8217;m going to show [&#8230;]</p>
<p>The post <a href="https://www.softwareverify.com/blog/how-to-read-embedded-data-from-a-resource/">How to read embedded data from a resource</a> appeared first on <a href="https://www.softwareverify.com">Software Verify</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">In the previous article, I showed you how to <a href="https://www.softwareverify.com/software-verify-blog/?p=589" target="_blank" rel="noopener noreferrer">embed data into a custom resource</a> in your application.</p>


<p class="wp-block-paragraph">In this article, I&#8217;m going to show you how to extract the same data using the Win32 API for use in your application at runtime.</p>


<p class="wp-block-paragraph">To extract data from a resource in an executable we need some information:</p>


<ul class="wp-block-list">
	<li>
<p>Executable name.</p>
</li>
	<li>
<p>Custom resource name.</p>
</li>
	<li>
<p>Custom resource type name.</p>
</li>
</ul>


<p class="wp-block-paragraph">In our previous example, the executable name was <strong>mvJavaDetective.dll</strong>, the custom resource type name was <span style="background-color: var(--green-10); color: #008000;" data-color="var(--green-10)">&#8220;CLASSFILE&#8221;</span> and the custom resource name was <span style="background-color: var(--green-10); color: #008000;" data-color="var(--green-10)">&#8220;myJavaSpy&#8221;</span>.</p>


<h2 class="wp-block-heading">The API</h2>


<h3 class="wp-block-heading">FindResource</h3>


<pre class="wp-block-code"><code>    HRSRC FindResource(HMODULE hModule,
                       LPCTSTR lpName,
                       LPCTSTR lpType);
</code></pre>


<p class="wp-block-paragraph">Call <strong>FindResource()</strong> to find a resource in an executable and return a resource handle.</p>


<p class="wp-block-paragraph">The executable is specified using a module handle that represents a module loaded in the current program. If the module is currently loaded you can get a handle to it using <strong>GetModuleHandle()</strong>. If the module is not currently loaded you can load it with <strong>LoadLibrary()</strong>.</p>


<p class="wp-block-paragraph">The resource is identified by its custom resource name and custom resource type.</p>


<h3 class="wp-block-heading">LoadResource</h3>


<pre class="wp-block-code"><code>    HGLOBAL LoadResource(HMODULE hModule,
                         HRSRC   hResInfo);
</code></pre>


<p class="wp-block-paragraph">Call <strong>LoadResource()</strong> to load the resource passings the module handle and the resource handle from <strong>FindResource()</strong> as parameters.</p>


<p class="wp-block-paragraph">The returned handle should not be passed to any Global memory function for deallocation.</p>


<h3 class="wp-block-heading">LockResource</h3>


<pre class="wp-block-code"><code>    LPVOID LockResource(HGLOBAL hResData);
</code></pre>


<p class="wp-block-paragraph">Call <strong>LockResource()</strong> to lock the resource in memory. Pass the handle returned by <strong>LoadResource()</strong> as the input parameter.</p>


<p class="wp-block-paragraph">If the call succeeds a pointer to the data represented by the handle is returned.</p>


<h3 class="wp-block-heading">SizeofResource</h3>


<pre class="wp-block-code"><code>    DWORD SizeofResource(HMODULE hModule,
                         HRSRC   hResInfo);
</code></pre>


<p class="wp-block-paragraph">Call <strong>SizeofResource()</strong> to determine the size of a resource. Pass the module handle and the handle returned from <strong>FindResource()</strong> as input parameters.</p>


<p class="wp-block-paragraph">The return value specifies the size of the resource.</p>


<h2 class="wp-block-heading">Putting it together</h2>


<p class="wp-block-paragraph">In the previous example our example DLL myJavaDetective.dll had a class <strong>myJavaSpy.class</strong> embedded into a resource with the type <span style="background-color: var(--green-10); color: #008000;" data-color="var(--green-10)">&#8220;CLASSFILE&#8221;</span> and name <span style="background-color: var(--green-10); color: #008000;" data-color="var(--green-10)">&#8220;myJavaSpy&#8221;</span>. I will now show you how to extract the <strong>myJavaSpy.class</strong> byte codes from the resource.</p>


<p class="wp-block-paragraph">First we need to get the module handle of the executable (<strong>myJavaDetective.dll</strong>) containing the <strong>myJavaSpy.class</strong>. For this example we will assume that <strong>myJavaDetective.dll</strong> is already loaded into memory.</p>


<p class="wp-block-paragraph">Call <strong>GetModuleHandle()</strong> with the name of the DLL holding the resource (<span style="background-color: var(--green-10); color: #008000;" data-color="var(--green-10)">&#8220;myJavaDetective.dll&#8221;</span>). The return value is the module handle.</p>


<pre class="wp-block-code"><code>	HMODULE	hModJavaDetective;

	hModJavaDetective = GetModuleHandle("myJavaDetective.dll");
</code></pre>


<p class="wp-block-paragraph">Once we have the module handle we can attempt to find the resource in the executable. We don&#8217;t need to check for a NULL module handle as <strong>FindResource()</strong> handles that and will return a NULL resource handle (just as it will if the resource is not embedded in the executable).</p>


<pre class="wp-block-code"><code>	jbyte	*classBytes = NULL;
	DWORD	classBytesLength = 0;
	HRSRC	hResource;

	hResource = FindResource(hModJavaDetective,
							 _T("myJavaSpy"),
							 _T("CLASSFILE"));
	if (hResource != NULL)
	{
</code></pre>


<p class="wp-block-paragraph">If <strong>FindResource()</strong> returns a non NULL handle the resource has been found. Now we must load the resource using <strong>LoadResource()</strong>.</p>


<pre class="wp-block-code"><code>		HGLOBAL	hResourceMemory;

		hResourceMemory = LoadResource(hModJavaDetective, hResource);
		if (hResourceMemory != NULL)
		{
</code></pre>


<p class="wp-block-paragraph">If <strong>LoadResource()</strong> returns a non NULL handle the resource has been correctly loaded from the executable. This returns a handle of type HGLOBAL. Caution you must not pass this handle to any HGLOBAL related functions such as <strong>GlobalFree()</strong> or <strong>GlobalRealloc()</strong> as this handle does not represent a memory allocation. This type is used for backward compatibility with earlier versions of the Windows API.</p>


<p class="wp-block-paragraph">Before we can use the data we must convert the returned handle into a pointer to the data by calling <strong>LockResource()</strong>. We also want to know the size of the data in the resource so we call <strong>SizeofResource()</strong> to determine the size. The pointer returned by <strong>LockResource()</strong> must not be passed to any memory deallocation functions &#8211; it does not need to be deallocated or unlocked.</p>


<pre class="wp-block-code"><code>			void	*ptr;
			DWORD	size;

			ptr = LockResource(hResourceMemory);
			size = SizeofResource(hModInjectedJVMTI, hResource);
			if (ptr != NULL)
			{
</code></pre>


<p class="wp-block-paragraph">If <strong>LockResource()</strong> returns a non NULL pointer the pointer represents the data embedded in the executable.</p>


<p class="wp-block-paragraph">Now we have the data we make a copy for our own use and continue as normal. This step is optional, you can use the data directly from the returned pointer if you wish.</p>


<pre class="wp-block-code"><code>				classBytes = new jbyte [size];
				if (classBytes != NULL)
				{
					memcpy(classBytes, ptr, size);
					classBytesLength = size;
				}
			}
		}

		// CAUTION! LoadResource() and LockResource() DO NOT allocate handles or locks, 
		// read the documentation
	}
</code></pre>


<p class="wp-block-paragraph">Now that we have extracted the data from the resource embedded into the executable we can use the data as normal. For this example I will conclude by using the extracted Java class bytescodes to define a Java class in a Java Virtual Machine.</p>


<pre class="wp-block-code"><code>	if (classBytes != NULL)
	{
		// define our class, must have same name as class file bytes
		// pass NULL for the class loader - use default class loader

		jclass		klass = 0;

		klass = jniEnv-&gt;DefineClass(SVL_COVERAGE_CLASS, NULL, classBytes, classBytesLength);
		if (klass != 0)
		{
                    // class defined correctly
		}

		// tidy up

		delete [] classBytes;
	}
</code></pre>


<h2 class="wp-block-heading">Wrap up</h2>


<p class="wp-block-paragraph">Now you know how to embed data in an executable at runtime (and after the fact with the utility presented in the previous article) and how to extract data from an executable at runtime. The techniques are quite straightforward to master and allow you to easily embed data for you to use at runtime without worrying about distributing and locating extra data files with your application.</p>

<p>&nbsp;</p><p>The post <a href="https://www.softwareverify.com/blog/how-to-read-embedded-data-from-a-resource/">How to read embedded data from a resource</a> appeared first on <a href="https://www.softwareverify.com">Software Verify</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Debugging a crash with single stepping</title>
		<link>https://www.softwareverify.com/blog/debugging-a-crash-with-single-stepping/</link>
					<comments>https://www.softwareverify.com/blog/debugging-a-crash-with-single-stepping/#respond</comments>
		
		<dc:creator><![CDATA[Stephen Kellett]]></dc:creator>
		<pubDate>Tue, 21 Jan 2025 15:37:43 +0000</pubDate>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Debugging]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[Flow Tracing]]></category>
		<category><![CDATA[execution tracing]]></category>
		<category><![CDATA[single step]]></category>
		<guid isPermaLink="false">https://www.softwareverify.com/?p=12635</guid>

					<description><![CDATA[<p>If you&#8217;ve ever used a debugger you&#8217;re probably familiar with the concept of single stepping through code &#8211; executing one instruction at a time until [&#8230;]</p>
<p>The post <a href="https://www.softwareverify.com/blog/debugging-a-crash-with-single-stepping/">Debugging a crash with single stepping</a> appeared first on <a href="https://www.softwareverify.com">Software Verify</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>If you&#8217;ve ever used a debugger you&#8217;re probably familiar with the concept of single stepping through code &#8211; executing one instruction at a time until you find the particular instruction that causes the crash.</p>
<h2>The Problem &#8211; Inaccessible Locations</h2>
<p>But what if the crash happens in somewhere that&#8217;s hard for you to debug, for example deep inside ExitProcess() or millions of instructions after the last location that you know about that is in your code?</p>
<h2>The Solution &#8211; Automation</h2>
<p>The solution to this problem is a dedicated tool that will single step through your code automatically without requiring you to tell the debugger to single step the next instruction. </p>
<p>Exception Tracer has a dedicated single-step mode that you can use for this.</p>
<p><img loading="lazy" decoding="async" class="alignnone size-full wp-image-12640" src="https://www.softwareverify.com/wp-content/uploads/2025/01/exceptionTracerGUISingleStep.png" alt="Exception Tracer user interface single step" width="691" height="81" srcset="https://www.softwareverify.com/wp-content/uploads/2025/01/exceptionTracerGUISingleStep.png 691w, https://www.softwareverify.com/wp-content/uploads/2025/01/exceptionTracerGUISingleStep-300x35.png 300w" sizes="auto, (max-width: 691px) 100vw, 691px" /></p>
<p>However, using Exception Tracer from it&#8217;s user interface you can attach to your program, but that doesn&#8217;t guarantee single stepping will happen in the right place for you. You could end up single stepping through tens of thousands of lines of code (millions of instructions) that you don&#8217;t need to before you get to the part of the program that you know is interesting. You could spend hours waiting for the trace to get to the part of the code that you think is going to be interesting for the purposes of understanding the bug. I know, I&#8217;ve waited overnight for single stepping results.</p>
<p>What if you could be more specific about when you choose to attach Exception Tracer you could save hours of time, increasing your productivity?</p>
<p>The solution is to add a single call to your application to launch exception tracer from within your program so that Exception Tracer starts single stepping your application from that exact location.</p>
<pre>attachExceptionTracerX64(GetCurrentProcessId());</pre>
<p>The function looks like this:</p>
<pre> 
static const TCHAR *ET_X86_PATH = _T("C:\\Program Files (x86)\\Software Verify\\ExceptionTracer\\exceptionTracer.exe");
static const TCHAR *ET_X64_PATH = _T("C:\\Program Files (x86)\\Software Verify\\ExceptionTracer\\exceptionTracer_x64.exe");

void attachExceptionTracer_internal(const TCHAR*    pathToExceptionTracer,
                                    DWORD           processId)
{
    int                    b;
    DWORD                  dwCreateFlags;
    STARTUPINFO            startupInfo;    // put info about startup here for CreateProcess()
    PROCESS_INFORMATION    procInfo;        // info about the process is placed here
    CString                theCmdLine;

    theCmdLine.Format(_T("%s /process %d /singleStepRequired:On"), pathToExceptionTracer, processId);

    startupInfo.cb = sizeof(STARTUPINFO);
    startupInfo.lpReserved = NULL;
    startupInfo.lpDesktop = NULL;
    startupInfo.lpTitle = NULL;
    startupInfo.dwX = 0;
    startupInfo.dwY = 0;
    startupInfo.dwXSize = 400;
    startupInfo.dwYSize = 400;
    startupInfo.dwXCountChars = 40;
    startupInfo.dwYCountChars = 25;
    startupInfo.dwFillAttribute = 0;
    startupInfo.dwFlags = STARTF_USESHOWWINDOW;
    startupInfo.wShowWindow = SW_SHOW;
    startupInfo.cbReserved2 = 0;
    startupInfo.lpReserved2 = NULL;
    startupInfo.hStdInput = NULL;
    startupInfo.hStdOutput = NULL;
    startupInfo.hStdError = NULL;

    procInfo.hProcess = NULL;
    procInfo.hThread = NULL;
    procInfo.dwProcessId = NULL;
    procInfo.dwThreadId = NULL;

    dwCreateFlags = NORMAL_PRIORITY_CLASS;

    b = CreateProcess(NULL,                                  // program
                      (TCHAR *)(const TCHAR *)theCmdLine,    // command line
                      NULL,                                  // process attributes (use default)
                      NULL,                                  // thread attributes (use default)
                      FALSE,                                 // inheritance (don't)
                      dwCreateFlags,                         // how to create the process
                      NULL,                                  // environment (use parent's, ie this)
                      NULL,                                  // current directory (same as this process if NULL)
                      &amp;startupInfo,                          // startup info
                      &amp;procInfo);                            // process info (return value)
    if (b)
    {
        WaitForInputIdle(procInfo.hProcess, INFINITE);

        CloseHandle(procInfo.hProcess);
        CloseHandle(procInfo.hThread);
    }
}

void attachExceptionTracerX86(DWORD	processId)
{
    attachExceptionTracer_internal(ET_X86_PATH, processId);
}

void attachExceptionTracerX64(DWORD	processId)
{
    attachExceptionTracer_internal(ET_X64_PATH, processId);
}
</pre>
<p>There&#8217;s also some helper functions to calculate the path to Exception Tracer based on values stored in the registry. All you need to do is:</p>
<ol>
<li><strong>#include attachExceptionTracer.inl</strong> into the source file where you want to start Exception Tracer</li>
<li>call <strong>attachExceptionTracerX86 </strong>or <strong>attachExceptionTracerX64</strong> as appropriate to start Exception Tracer</li>
</ol>
<p>Exception Tracer will attach to the application with single stepping enabled and run until the program exits. After the program exits the trace will be processed and then displayed for you to analyse.</p>
<p>The trace shown below shows single stepping into a buffer overrun crash being detected.</p>
<p><img loading="lazy" decoding="async" class="alignnone size-full wp-image-12643" src="https://www.softwareverify.com/wp-content/uploads/2025/01/exceptionTracerGUISingleStepTrace.png" alt="Exception Tracer showing a trace full of single step entries that are part of a buffer overrun crash" width="1183" height="679" srcset="https://www.softwareverify.com/wp-content/uploads/2025/01/exceptionTracerGUISingleStepTrace.png 1183w, https://www.softwareverify.com/wp-content/uploads/2025/01/exceptionTracerGUISingleStepTrace-300x172.png 300w, https://www.softwareverify.com/wp-content/uploads/2025/01/exceptionTracerGUISingleStepTrace-1024x588.png 1024w, https://www.softwareverify.com/wp-content/uploads/2025/01/exceptionTracerGUISingleStepTrace-768x441.png 768w" sizes="auto, (max-width: 1183px) 100vw, 1183px" /></p>
<p>The post <a href="https://www.softwareverify.com/blog/debugging-a-crash-with-single-stepping/">Debugging a crash with single stepping</a> appeared first on <a href="https://www.softwareverify.com">Software Verify</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.softwareverify.com/blog/debugging-a-crash-with-single-stepping/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
