<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Recent changes to Crash Reporting</title><link>https://sourceforge.net/p/sucrose/wiki/Crash%2520Reporting/</link><description>Recent changes to Crash Reporting</description><atom:link href="https://sourceforge.net/p/sucrose/wiki/Crash%20Reporting/feed" rel="self"/><language>en</language><lastBuildDate>Sat, 04 Jul 2026 04:15:46 -0000</lastBuildDate><atom:link href="https://sourceforge.net/p/sucrose/wiki/Crash%20Reporting/feed" rel="self" type="application/rss+xml"/><item><title>Crash Reporting modified by Bayram Emekli</title><link>https://sourceforge.net/p/sucrose/wiki/Crash%2520Reporting/</link><description>&lt;div class="markdown_content"&gt;&lt;pre&gt;--- v2
+++ v3
@@ -27,11 +27,11 @@

 ## The five global exception handlers

-Every Sucrose app (Launcher, Portal, Watchdog, Property, and the rest) wires the same set of handlers during startup (`OnStartup` → `Configure`). Each is implemented in `Sucrose.Shared.Watchdog.Extension.Watch`:
+Every Sucrose app (Launcher, Portal, Watchdog, Property, and the rest) wires the same set of handlers in the application constructor (`App()`). Each is implemented in `Sucrose.Shared.Watchdog.Extension.Watch`:

 | Handler | Source event |
 |---|---|
-| `Watch_CatchException` | catch-all helper invoked by the others |
+| `Watch_CatchException` | not invoked by the other handlers; called from manual try/catch sites across the codebase (logs the `CATCH` block) |
 | `Watch_ThreadException` | `Application.ThreadException` |
 | `Watch_FirstChanceException` | `AppDomain.FirstChanceException` — **intentionally a no-op** (`return;`) to avoid log spam |
 | `Watch_UnobservedTaskException` | `TaskScheduler.UnobservedTaskException` |
@@ -123,7 +123,7 @@

 ## Consent and privacy

-Crash reporting is **opt-in** and controlled by two independent switches on the [Settings → Other](Settings-Other) page:
+Crash reporting is **enabled by default (opt-out)** and controlled by two independent switches on the [Settings → Other](Settings-Other) page:


 - `ExceptionData` — enables crash-report uploads (the Throw stream).
 - `TelemetryData` — enables analytics and the online heartbeat.
&lt;/pre&gt;
&lt;/div&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Bayram Emekli</dc:creator><pubDate>Sat, 04 Jul 2026 04:15:46 -0000</pubDate><guid>https://sourceforge.net9e19b4befeda13c2c54b9e5577ab8dd8d6393111</guid></item><item><title>Crash Reporting modified by Bayram Emekli</title><link>https://sourceforge.net/p/sucrose/wiki/Crash%2520Reporting/</link><description>&lt;div class="markdown_content"&gt;&lt;pre&gt;--- v1
+++ v2
@@ -64,7 +64,19 @@

 The `✔` (U+2714) start marker and `✖` (U+2716) separator are the standard command-bus wire format (see [IPC](IPC) and [Command Reference](Command-Reference)).

-&amp;gt; 🖼️ **Diagram needed:** crash flow — any process throws → Watch.* logs locally → Watchdog.Start builds Base64(app✖exception✖show✖log) → Commandog spawns Watchdog.exe → Report/&amp;lt;guid&amp;gt;.json written + faulting process killed + optional dialog → Reportdog uploads later.

+    :::mermaid
+    flowchart LR
+        Throw["Any process throws"] --&amp;gt; Log["Watch.* handler&lt;br/&gt;logs 5-line block locally"]
+        Log --&amp;gt; Start["Watchdog.Start(app, ex, show, log)"]
+        Start --&amp;gt; Payload["build payload&lt;br/&gt;app✖exception✖show✖log&lt;br/&gt;then Base64-encode"]
+        Payload --&amp;gt; Cmd["Commandog&lt;br/&gt;✔Watchdog✖&amp;lt;exe&amp;gt;✖&amp;lt;Base64&amp;gt;"]
+        Cmd --&amp;gt; WD["Sucrose.Watchdog.exe"]
+        WD --&amp;gt; Report["write Cache/Report/&amp;lt;guid&amp;gt;.json"]
+        WD --&amp;gt; Kill["kill faulting process&lt;br/&gt;unless it is Watchdog"]
+        WD --&amp;gt; Dialog{"show == true?"}
+        Dialog --&amp;gt;|yes| Box["Dark / Light error dialog"]
+        Dialog --&amp;gt;|no| SilentNode["silent"]
+        Report -. later .-&amp;gt; RD["Reportdog uploads to Soferity v8&lt;br/&gt;if ExceptionData is on"]

 ## What the Watchdog writes

&amp;lt;/guid&amp;gt;&lt;/pre&gt;
&lt;/div&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Bayram Emekli</dc:creator><pubDate>Sat, 04 Jul 2026 04:15:43 -0000</pubDate><guid>https://sourceforge.net7de0e5d5d3399b48113f864528cf2145163d91b5</guid></item><item><title>Crash Reporting modified by Bayram Emekli</title><link>https://sourceforge.net/p/sucrose/wiki/Crash%2520Reporting/</link><description>&lt;div class="markdown_content"&gt;&lt;h1 id="h-crash-reporting"&gt;Crash Reporting&lt;/h1&gt;
&lt;p&gt;Sucrose's multi-process design means a crash in one component should never take down the wallpaper or the tray. To make that work, &lt;strong&gt;every&lt;/strong&gt; Sucrose executable installs a full set of global exception handlers, and when one fires the failure is routed to a dedicated crash handler process (&lt;code&gt;Sucrose.Watchdog.exe&lt;/code&gt;) that writes a structured report, kills the faulting process, and optionally shows a themed error dialog. A separate uploader (&lt;code&gt;Sucrose.Reportdog.exe&lt;/code&gt;) later sends those reports to the backend — but only if you have opted in. This page explains the whole crash-reporting pipeline, from the handlers compiled into each app to the on-disk report queue and the upload step. It is written for developers and administrators.&lt;/p&gt;
&lt;h2 id="h-contents"&gt;Contents&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="#two-things-called-watchdog"&gt;Two things called "watchdog"&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#the-five-global-exception-handlers"&gt;The five global exception handlers&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#how-a-crash-reaches-the-watchdog"&gt;How a crash reaches the Watchdog&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#what-the-watchdog-writes"&gt;What the Watchdog writes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#the-error-dialog"&gt;The error dialog&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#reportdog-uploading-reports"&gt;Reportdog: uploading reports&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#consent-and-privacy"&gt;Consent and privacy&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#native-fallback"&gt;Native fallback&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#see-also"&gt;See also&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="h-two-things-called-watchdog"&gt;Two things called "watchdog"&lt;/h2&gt;
&lt;p&gt;There are two distinct components that share the "watchdog" name — keep them separate:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Name&lt;/th&gt;
&lt;th&gt;What it is&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Sucrose.Shared.Watchdog.Extension.Watch&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;A &lt;strong&gt;logger&lt;/strong&gt; compiled into every executable. Its methods receive each unhandled exception and append a structured block to that process's log file.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Sucrose.Watchdog.exe&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;A &lt;strong&gt;WPF process&lt;/strong&gt; that receives a Base64 exception payload, writes the structured report JSON, kills the faulting process, and (optionally) shows a crash dialog.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;The logger always runs locally and in-process; the Watchdog UI process is spawned only on demand through &lt;a href="./Commandog-Dispatcher"&gt;Commandog&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id="h-the-five-global-exception-handlers"&gt;The five global exception handlers&lt;/h2&gt;
&lt;p&gt;Every Sucrose app (Launcher, Portal, Watchdog, Property, and the rest) wires the same set of handlers during startup (&lt;code&gt;OnStartup&lt;/code&gt; → &lt;code&gt;Configure&lt;/code&gt;). Each is implemented in &lt;code&gt;Sucrose.Shared.Watchdog.Extension.Watch&lt;/code&gt;:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Handler&lt;/th&gt;
&lt;th&gt;Source event&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Watch_CatchException&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;catch-all helper invoked by the others&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Watch_ThreadException&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Application.ThreadException&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Watch_FirstChanceException&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;AppDomain.FirstChanceException&lt;/code&gt; — &lt;strong&gt;intentionally a no-op&lt;/strong&gt; (&lt;code&gt;return;&lt;/code&gt;) to avoid log spam&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Watch_UnobservedTaskException&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;TaskScheduler.UnobservedTaskException&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Watch_GlobalUnhandledException&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;AppDomain.UnhandledException&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Watch_DispatcherUnhandledException&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Application.DispatcherUnhandledException&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Each handler writes a 5-line block to the per-app log manager:&lt;/p&gt;
&lt;div class="codehilite"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&amp;lt;TYPE&amp;gt; EXCEPTION START
&amp;lt;message&amp;gt;
&amp;lt;inner exception&amp;gt;
&amp;lt;stack trace&amp;gt;
&amp;lt;TYPE&amp;gt; EXCEPTION FINISH
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The log manager is selected at compile time by the app's preprocessor symbol (&lt;code&gt;#if UNDO / PORTAL / UPDATE / LAUNCHER / PROPERTY / WATCHDOG / COMMANDOG / REPORTDOG / LIVE_* / BACKGROUNDOG …&lt;/code&gt;), so each process logs to its own file. See &lt;a href="./Preprocessor-Symbols"&gt;Preprocessor Symbols&lt;/a&gt; and &lt;a href="./Logs-Diagnostics"&gt;Logs &amp;amp; Diagnostics&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Extra context can be attached before a crash via &lt;code&gt;Sucrose.Shared.Watchdog.Helper.Dataset&lt;/code&gt;, a static &lt;code&gt;Hashtable&lt;/code&gt;. Its known fields (&lt;code&gt;Memory/Readonly/Watch.cs&lt;/code&gt;) are &lt;code&gt;Text&lt;/code&gt; and &lt;code&gt;Source&lt;/code&gt; — help/source strings merged into &lt;code&gt;Exception.Data&lt;/code&gt; when the crash is reported.&lt;/p&gt;
&lt;h2 id="h-how-a-crash-reaches-the-watchdog"&gt;How a crash reaches the Watchdog&lt;/h2&gt;
&lt;p&gt;After logging, the handler calls &lt;code&gt;Sucrose.Shared.Space.Helper.Watchdog.Start(appName, exception, show, logPath)&lt;/code&gt;. That helper:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Runs only if &lt;strong&gt;both&lt;/strong&gt; &lt;code&gt;Sucrose.Commandog.exe&lt;/code&gt; and &lt;code&gt;Sucrose.Watchdog.exe&lt;/code&gt; exist (&lt;code&gt;Check()&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;Merges any ambient &lt;code&gt;Dataset&lt;/code&gt; entries into &lt;code&gt;Exception.Data&lt;/code&gt;, then clears the dataset.&lt;/li&gt;
&lt;li&gt;Builds the payload string &lt;code&gt;"&amp;lt;Application&amp;gt;✖&amp;lt;SerializedException&amp;gt;✖&amp;lt;Show&amp;gt;✖&amp;lt;LogPath&amp;gt;"&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Base64-encodes&lt;/strong&gt; the whole payload (&lt;code&gt;CryptologyExtension.TextToBase&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Spawns the Watchdog through Commandog:&lt;/p&gt;
&lt;p&gt;✔Watchdog✖&amp;lt;path-to-sucrose.watchdog.exe&amp;gt;✖&amp;lt;base64 payload=""&amp;gt;&amp;lt;/base64&amp;gt;&amp;lt;/path-to-sucrose.watchdog.exe&amp;gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The &lt;code&gt;✔&lt;/code&gt; (U+2714) start marker and &lt;code&gt;✖&lt;/code&gt; (U+2716) separator are the standard command-bus wire format (see &lt;a href="./IPC"&gt;IPC&lt;/a&gt; and &lt;a href="./Command-Reference"&gt;Command Reference&lt;/a&gt;).&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;🖼️ &lt;strong&gt;Diagram needed:&lt;/strong&gt; crash flow — any process throws → Watch.* logs locally → Watchdog.Start builds Base64(app✖exception✖show✖log) → Commandog spawns Watchdog.exe → Report/&amp;lt;guid&amp;gt;.json written + faulting process killed + optional dialog → Reportdog uploads later.&amp;lt;/guid&amp;gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="h-what-the-watchdog-writes"&gt;What the Watchdog writes&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;Sucrose.Watchdog.App.Configure(args)&lt;/code&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Decodes the Base64 argument, splits on &lt;code&gt;✖&lt;/code&gt;, and requires &lt;strong&gt;exactly 4&lt;/strong&gt; parts: &lt;code&gt;Application&lt;/code&gt;, &lt;code&gt;RawException&lt;/code&gt; (JSON), &lt;code&gt;Show&lt;/code&gt; (bool), &lt;code&gt;Log&lt;/code&gt; (path).&lt;/li&gt;
&lt;li&gt;Builds a &lt;code&gt;ThrowExceptionData&lt;/code&gt; record (&lt;code&gt;Sucrose.Shared.Space.Model.ThrowExceptionData&lt;/code&gt;) with:&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Id&lt;/code&gt; (Guid), &lt;code&gt;AppId&lt;/code&gt; (deterministic from app name), &lt;code&gt;Sid&lt;/code&gt; (hash of user + model + manufacturer).&lt;/li&gt;
&lt;li&gt;&lt;code&gt;UserName, DeviceModel, ManufacturerBrand&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;AppName, AppVersion, AppFramework, AppArchitecture, ProcessArchitecture, ProcessorArchitecture&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;CultureName, CultureDisplay, CultureCode&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;OperatingSystem, OperatingSystemBuild, OperatingSystemArchitecture, IsServer, IsWorkstation&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Exception&lt;/code&gt; (the exception as a JObject).&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Writes the record to:&lt;/p&gt;
&lt;p&gt;%AppData%\Sucrose\Cache\Report\&amp;lt;guid&amp;gt;.json&amp;lt;/guid&amp;gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;This is the queue that &lt;a href="#reportdog-uploading-reports"&gt;Reportdog&lt;/a&gt; later drains. See &lt;a href="./Data-Locations"&gt;Data Locations&lt;/a&gt; for the full folder map.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;If &lt;code&gt;Application != Watchdog&lt;/code&gt;, &lt;strong&gt;kills the crashing process&lt;/strong&gt; (the Watchdog never kills itself).&lt;/li&gt;
&lt;li&gt;Always exits at the end (&lt;code&gt;Close()&lt;/code&gt; / &lt;code&gt;Environment.Exit&lt;/code&gt;).&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="h-the-error-dialog"&gt;The error dialog&lt;/h2&gt;
&lt;p&gt;If &lt;code&gt;Show == true&lt;/code&gt;, the Watchdog presents a crash dialog. It picks &lt;strong&gt;Dark&lt;/strong&gt; or &lt;strong&gt;Light&lt;/strong&gt; (&lt;code&gt;DarkErrorMessageBox&lt;/code&gt; / &lt;code&gt;LightErrorMessageBox&lt;/code&gt;) based on the current theme, showing the exception message plus the log/source/text/help fields. If WPF-UI initialization fails, it falls back to a native Windows &lt;code&gt;MessageBox&lt;/code&gt; titled &lt;strong&gt;"Sucrose Watchdog - Critical Error"&lt;/strong&gt; that hints at a missing &lt;strong&gt;Visual C++ Redistributable&lt;/strong&gt; or &lt;strong&gt;.NET Desktop Runtime&lt;/strong&gt; (see &lt;a href="#native-fallback"&gt;Native fallback&lt;/a&gt;).&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;📷 &lt;strong&gt;Screenshot needed:&lt;/strong&gt; Watchdog crash dialog (dark theme) showing the exception message and the log/source/help fields.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Silent (&lt;code&gt;Show == false&lt;/code&gt;) crashes still write the report JSON and kill the process — they just do not interrupt the user.&lt;/p&gt;
&lt;h2 id="h-reportdog-uploading-reports"&gt;Reportdog: uploading reports&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;Sucrose.Reportdog.exe&lt;/code&gt; is a headless uploader with a long-running loop (&lt;code&gt;do { Attempt.Start(); Initialize.Dispose(); delay AppTime = 1000 } while (Exit)&lt;/code&gt;). It is launched on Launcher start and from the tray, but only runs when single-instance &lt;strong&gt;and&lt;/strong&gt; at least one consent flag (&lt;code&gt;ExceptionData&lt;/code&gt; or &lt;code&gt;TelemetryData&lt;/code&gt;) is enabled.&lt;/p&gt;
&lt;p&gt;All uploads go to the &lt;strong&gt;Soferity&lt;/strong&gt; backend (base &lt;code&gt;Url.Soferity&lt;/code&gt;, API version &lt;code&gt;Soferity.Version = "v8"&lt;/code&gt;). There are three upload streams:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Stream&lt;/th&gt;
&lt;th&gt;Trigger&lt;/th&gt;
&lt;th&gt;Endpoint&lt;/th&gt;
&lt;th&gt;Consent&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Throw (crash) reports&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;FileSystemWatcher&lt;/code&gt; on &lt;code&gt;%AppData%\Sucrose\Cache\Report&lt;/code&gt;; drains existing files on startup, uploads on each &lt;code&gt;Created&lt;/code&gt; event, deletes the file on success&lt;/td&gt;
&lt;td&gt;&lt;code&gt;…/v8/Exception/Throw/&amp;lt;UserGuid&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ExceptionData&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Analytic telemetry&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;AnalyticTimer&lt;/code&gt; every &lt;strong&gt;10 minutes&lt;/strong&gt; (&lt;code&gt;AnalyticTime = TimeSpan.FromMinutes(10)&lt;/code&gt;); the timer is disposed after the &lt;strong&gt;first&lt;/strong&gt; successful POST (one-shot per run)&lt;/td&gt;
&lt;td&gt;&lt;code&gt;…/v8/Telemetry/Analytic/&amp;lt;UserGuid&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;TelemetryData&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Online heartbeat&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;OnlineTimer&lt;/code&gt; every &lt;strong&gt;~2–2.5 minutes&lt;/strong&gt; (&lt;code&gt;OnlineTime = Random.Next(120, 150)&lt;/code&gt; seconds); body &lt;code&gt;{ AppVersion, Time }&lt;/code&gt; (Time = 1 on the first ping, else the interval in seconds)&lt;/td&gt;
&lt;td&gt;&lt;code&gt;…/v8/Telemetry/Online/&amp;lt;UserGuid&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;TelemetryData&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;The analytic payload (&lt;code&gt;AnalyticTelemetryData&lt;/code&gt;) is a large snapshot of nearly every user setting (app exit/visible/startup state, all per-type engine choices, all &lt;code&gt;*Performance&lt;/code&gt; modes, library/store/cycling settings) plus hardware facts (total memory, cores, processors, GPU/network/CPU lists, OS/arch/culture). The relevant Soferity path tokens (&lt;code&gt;Memory/Readonly/Soferity.cs&lt;/code&gt;) include &lt;code&gt;Version="v8"&lt;/code&gt;, &lt;code&gt;Telemetry&lt;/code&gt;, &lt;code&gt;Analytic&lt;/code&gt;, &lt;code&gt;Online&lt;/code&gt;, &lt;code&gt;Exception&lt;/code&gt;, &lt;code&gt;Throw&lt;/code&gt;, &lt;code&gt;Encoding=UTF8&lt;/code&gt;, and &lt;code&gt;ApplicationJson="application/json"&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id="h-consent-and-privacy"&gt;Consent and privacy&lt;/h2&gt;
&lt;p&gt;Crash reporting is &lt;strong&gt;opt-in&lt;/strong&gt; and controlled by two independent switches on the &lt;a href="./Settings-Other"&gt;Settings → Other&lt;/a&gt; page:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;ExceptionData&lt;/code&gt; — enables crash-report uploads (the Throw stream).&lt;/li&gt;
&lt;li&gt;&lt;code&gt;TelemetryData&lt;/code&gt; — enables analytics and the online heartbeat.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If both are off, Reportdog does not run, and the &lt;code&gt;Report/&amp;lt;guid&amp;gt;.json&lt;/code&gt; files simply remain on disk (the local crash logging in each process's log file is unaffected). For the full breakdown of what is collected and how to disable it, see &lt;a href="./Privacy-Telemetry"&gt;Privacy &amp;amp; Telemetry&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id="h-native-fallback"&gt;Native fallback&lt;/h2&gt;
&lt;p&gt;The native-&lt;code&gt;MessageBox&lt;/code&gt; fallback in the Watchdog dialog is a deliberate diagnostic: if the WPF-UI crash dialog itself cannot start, the most common root cause is a missing &lt;strong&gt;Visual C++ Redistributable&lt;/strong&gt; or &lt;strong&gt;.NET Desktop Runtime&lt;/strong&gt; on the machine. The fallback message names these explicitly so users know what to install. See &lt;a href="./Runtime-Dependencies"&gt;Runtime Dependencies&lt;/a&gt; and &lt;a href="./Troubleshooting-Settings-Startup-GPU"&gt;Troubleshooting: Settings, Startup &amp;amp; GPU&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id="h-see-also"&gt;See also&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="./Logs-Diagnostics"&gt;Logs &amp;amp; Diagnostics&lt;/a&gt; — where each process logs and how to gather logs for a bug report.&lt;/li&gt;
&lt;li&gt;&lt;a href="./Privacy-Telemetry"&gt;Privacy &amp;amp; Telemetry&lt;/a&gt; — the consent switches and exactly what is sent to Soferity.&lt;/li&gt;
&lt;li&gt;&lt;a href="./Commandog-Dispatcher"&gt;Commandog Dispatcher&lt;/a&gt; — how the &lt;code&gt;✔Watchdog✖…✖…&lt;/code&gt; command spawns the crash handler.&lt;/li&gt;
&lt;li&gt;&lt;a href="./Data-Locations"&gt;Data Locations&lt;/a&gt; — the &lt;code&gt;Cache\Report&lt;/code&gt; queue and other on-disk paths.&lt;/li&gt;
&lt;li&gt;&lt;a href="./Architecture-Overview"&gt;Architecture Overview&lt;/a&gt; — the Watchdog/Reportdog roles in the process roster.&lt;/li&gt;
&lt;/ul&gt;&lt;/div&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Bayram Emekli</dc:creator><pubDate>Sat, 04 Jul 2026 04:15:21 -0000</pubDate><guid>https://sourceforge.nete9607327b71ba190835ebc7016b66f3314c7e8b3</guid></item></channel></rss>