EurekaLog
Menu

The EurekaLog Developer Guide

4. From an incoming report to a useful investigation

The first job is not to fix the line at the top of the stack. It is to establish what arrived, which build produced it, and which parts of the report are evidence rather than guesses. Only then should you group it with other reports or start changing code.

This chapter takes a received file through EurekaLog Viewer and into an investigation. Chapter 20 explains the technical interpretation of call stacks, CPU state, memory errors, hangs, and leaks. Chapter 5 diagnoses EurekaLog itself when report generation or internal processing goes wrong.

4.1 Preserve the incoming evidence before importing it

Keep the original report package in access-controlled storage with its receipt time, product, reported version, and related issue or support conversation. Work from a copy when converting or editing it. Do not replace the original with pasted email text: the package may contain several reports, screenshots, and files that the message body omits.

The formats you are likely to receive are:

File What it contains
.el EurekaLog 7 text report; one file may hold more than one report.
.elx XML report; not an executable or a memory dump.
.elp A ZIP package containing a report and associated files; it may be password-protected.
.elf, .zip, .xml Older report/packaging extensions supported by Viewer.
.dat A file-based Viewer report database, using the report-file format rather than a distinct crash-dump format.

Treat files attached to a report as untrusted inputs. Read logs and images with suitable tools; do not run an attached EXE, installer, script, or macro because it came through a reporting channel. Review private data before forwarding reports outside the investigation group. The reporter's ability to upload evidence is not permission to publish it.

A message that says “sent” may not include the full package. If the ticket exists but the expected .elp is missing, first check the delivery and workflow distinctions in sections 3.6 and 3.8. Do not immediately ask for a new crash reproduction when the evidence may already exist in the application's local storage or on the intake server.

4.2 Open first; import only when you want aggregation

Launch Tools / EurekaLog / Viewer in the IDE, or use the installed Viewer shortcut. For a known file, the most explicit command is:

Viewer.exe /View "C:\Reports\incoming.elp"

Run this with the installed Viewer executable on your path, or use its full path. /View forces viewing rather than database import. The title should show [View mode]. Open another file with the toolbar's Open command; the report list is replaced by the contents of that file. It can be hidden automatically when the file contains only one report.

Double-clicking an associated report file also works, but its action is configurable. To avoid ambiguity, use the explicit command or the file's viewing action. In Configure / Settings / Actions, choose the default behavior you want for file opening. If a needed button is absent, right-click the toolbar, choose Customize, and restore the relevant command; toolbar configuration can hide controls without removing the feature.

Why import is a different operation

In database mode, Viewer merges imported reports by BugID. The documented behavior keeps the first report for a BugID, increases its Count for later matching reports, and discards those later report records from the database. It does not delete the original files from disk. View mode, by contrast, displays the reports in the file without that merge.

This is a major investigation boundary. A later report can contain a different operating system, a different build, a more useful stack, or different attachments even when its BugID matches. Preserve originals before import so that database aggregation does not become evidence loss.

To configure persistent aggregation:

  1. Open Configure / Settings / Database.
  2. Select a storage mode and its destination.
  3. Use Test connection where available, then save the settings.
  4. Import through Import, the Explorer context command Import report, or the explicit command below.
Viewer.exe /Import "C:\Reports\first.elp" "C:\Reports\second.elp"

Check the title's [DB mode: ...] indication and destination. /Import forces database mode, but it does not create a persistent database configuration for you.

Database choice Consequence
No database storage Reports are held in memory and lost from that database when Viewer exits. This is also the fallback when import is forced without a configured database.
File-based database Stores reports in a normal report-format file, usually .dat. Use a backed-up, access-controlled location.
FireBird database, local file Uses the embedded FireBird server. The documented embedded mode does not provide the FireBird security-database boundary; a local login dialog must not be mistaken for filesystem protection.
FireBird database, server Specify the server name and database plus the database credentials. These are distinct from Viewer user accounts. A shared deployment also needs a properly administered FireBird service.

For one investigator, a file-based database is sufficient to organize reports; a remote database is not a prerequisite for this chapter. Back up the database and originals according to your own retention policy. Do not make it broadly readable merely because it contains “only bug reports”.

If you open another Viewer instance with /New, local database files may already be in use. For a separate comparison window, use:

Viewer.exe /New /View "C:\Reports\comparison.elp"

A Test connection failure against a database already open in Viewer may likewise be a file-access conflict rather than an invalid password.

The IDE's local-report shortcut is not the inbox

Tools / EurekaLog / View exception log opens the locally saved report for the current project. It does not retrieve the last tracker upload, screenshot, or outgoing package. Nothing useful can open if local report saving was disabled or the configured file does not exist; dynamic filenames can also prevent the shortcut from locating it. If you know the actual filename, open it explicitly in Viewer.

4.3 Decrypt the right layer and inspect all files

There are two distinct passwords in this workflow:

  • the .elp ZIP/package password from Pack with password;
  • the Debug information encryption password, which protects names in debug information and their readable representation in diagnostic output—not the whole report or its attachments.

When Viewer prompts for an encrypted package, provide its package password. For encrypted diagnostic names, enter the debug-information password in the Password edit and click Apply. A correct package password does not necessarily decrypt the names inside it, and protecting those names does not make unrelated report fields confidential.

Viewer can remember passwords on the investigator's machine. The documented cache includes HKEY_CURRENT_USER\Software\EurekaLab\Viewer\7.0\Passwords and ...\Hashes, identified by project. Protect that user profile and do not assume closing Viewer erases secrets. An investigator opening a file on a second machine may need the password even when the first machine never prompts.

The command-line switches /ELPPassword=password and /DebugPassword=password select the corresponding layers, but putting secrets on a command line can expose them in process information, command history, scripts, or logs. Prefer the interactive entry for sensitive reports.

For a normal .elp, Open/View reads the package. For a legacy ZIP, use Open or Import and choose the appropriate file filter; Viewer attempts to locate the main report and treats other archive entries as associated files. Check that it selected the intended report, especially in an archive assembled manually.

In the report view, select Files to inspect the associated files. Its context menu is available by right-clicking a file or the empty area and provides file-management actions. Avoid removing attachments from your only copy. A screenshot is evidence about visible state, not proof of what the program was doing internally; overlapping windows, private desktop content, or a screenshot taken after the fault can mislead.

Files added through OnZippedFilesRequest are inside the package. Files added through OnAttachedFilesRequest can be separate transport attachments. A complete investigation bundle therefore includes both the .elp and any sibling attachments from the email or tracker. If the supplied .el has no Files section, there may simply be no associated files in that text file; it does not prove none were captured elsewhere.

Convert without overwriting the original

Viewer provides a noninteractive conversion command:

Viewer.exe "/Convert=C:\Reports\incoming.elp" "/Output=C:\Reports\working-copy.el"

The output extension selects the requested report-file form. Use /Output explicitly: without it, the documented behavior overwrites the source file. Conversion exits Viewer rather than opening a normal viewing session and is not combined with /View, /Import, or /New. A text conversion is not a substitute for retaining the original package and attachments.

4.4 Identify the build before trusting a source line

Record the application's version, faulting module, platform/bitness, exception type/message, report time, and BugID. In a DLL report, distinguish the host application's version from the DLL's version. Match these to the release archive from chapter 2: the actual shipped binaries, their debug information, and the corresponding source revision.

Do not rebuild the same source today and assume its addresses match yesterday's executable. Compiler/IDE version, build configuration, conditional defines, packages, third-party libraries, and post-processing can change the binary. A current source file with the same name is not enough.

Keep these questions separate:

  1. What location did the report capture? A resolved line, a routine, a module-relative offset, or only a raw address?
  2. How was it resolved? Exact debug information, export-name approximation, or a raw/heuristic stack item?
  3. Which build do I have? Does the binary and its symbol data actually match the reported module?

A plausible line in the wrong source revision is more dangerous than an honestly unresolved address. If you cannot recover the exact revision, label the mapping as provisional instead of “correcting” the report to fit the current code.

Move from the call stack into the IDE

When the stack has source locations:

  1. Launch the IDE and open the matching project/source revision. Open the target unit explicitly if several copies of that unit exist.
  2. Run Viewer and the IDE as the same user and at the same UAC elevation level. Cross-boundary navigation is not the documented integration path.
  3. Double-click the call-stack row in Viewer or the EurekaLog detailed error dialog to navigate to its source location.
  4. If navigation does not work, open the unit manually and use Search / Go to line number. Check that the surrounding code is the routine named in the report.

EurekaLog can use an IDE __history folder in some cases, but version control or the archived source revision is the more explicit way to select the source. A line offset within a routine can help when preceding code moved; it is still only an approximation if the routine itself changed. With a routine name but no line, inspect that routine's calls and state transitions. Do not claim a unique source statement when several calls could produce the same stack.

Resolve an address without inventing its base

Use Tools / EurekaLog / Address lookup to inspect debug information for a compiled module and resolve an address against the matching executable. The tool is also useful for checking whether the required symbol source exists at all. Supply the module/build that produced the address, not whichever executable is currently in the output directory. No universal command-line syntax is specified for this tool; use its installed UI rather than guessing switches.

For IDE debugging, the documented fallback is to run the matching project, pause it with Run / Pause, and use Search / Go to address. Hexadecimal addresses require the $ prefix. If the report supplies a module-relative offset rather than an absolute address, open View / Debug windows / Modules, find the module's current base, and translate the offset into the current process address.

This translation depends on what “offset” means. An image-relative address is added to the image base. A code-section-relative offset also needs that section's offset from the image base. $1000 applies to some layouts; do not add $1000 blindly to every value. Chapter 20 explains the report's address and offset fields. ASLR or a different module load address invalidates a raw absolute address copied from another process, even when the module binary matches.

If no matching debug information exists, Address Lookup or the IDE cannot manufacture a line number. Preserve the unresolved location and seek a reproduction or a better-instrumented build; do not present an export-name guess as exact source evidence.

4.5 Use the tool that answers the question

Viewer organizes evidence already captured. The other utilities answer different questions and may need a binary or a running process. They are not interchangeable kinds of “report viewer”. Menu placement can vary with the IDE's installed experts.

Question Tool and entry point What it gives you
What did this report contain? Tools / EurekaLog / Viewer Report sections, associated files, and optional report database.
Which routine/line corresponds to an address in this binary? Tools / EurekaLog / Address lookup Address/debug-information lookup against a compiled module.
What does this numerical error mean? Tools / EurekaLog / Error lookup Error-code lookup; not a root-cause analysis of the application.
What is in the executable file? Tools / EurekaLog / PE Analyzer; the tools overview also calls this Module informer/PE Informer Compiled-module information for diagnosis.
What are the live threads waiting on now? Tools / EurekaLog / Threads snapshot A file containing thread information, stacks, and wait chains for the selected process.
Where should Microsoft symbols be found? Tools / EurekaLog / IDE options, or Bin\SetDebugSymbolsPath.exe DbgHelp library path, writable symbol cache, and symbol sources.
How do I edit EurekaLog settings without the IDE integration? External settings editor Loads/saves .eof settings and supported IDE project formats; it does not analyze a crash.

Investigating a live hang

If the application is still hung, launch Threads snapshot, select the correct process, and save the snapshot before terminating the application. Record its process identity, bitness/build, time, and what the user expected it to do. If practical, capture another snapshot while the same hang persists: unchanged wait chains and changing stacks answer different questions. Keep the output with the incident, not in place of its exception report.

A snapshot shows the state at collection time. It does not retroactively recover the exception state of a process that has already exited, prove that a wait is a deadlock, or explain why a lock was acquired. Compare the relevant threads and ownership/waiting relationships using chapter 20 and the hang discussion in chapter 14. When privileges or process access prevent capture, preserve that failure rather than substituting a snapshot of the wrong process.

No complete operational contract is specified here for minidumps or Windows Error Reporting. Do not assume those workflows are interchangeable with the report, Viewer, address/debug-information tools, or thread snapshots used in this chapter.

Set up Microsoft symbols on an investigator's machine

System DLLs usually do not carry their full debug information. Export names alone can produce a plausible but inaccurate “possible” match. Microsoft symbol files can improve that information, but must match the particular module version.

For controlled diagnostic work:

  1. Obtain the appropriate-bitness DbgHelp.dll from the EurekaLog installation's Bin/Bin64 directory or Microsoft Debugging Tools. The provider requires a suitable debugging-tools version, not simply whichever DLL Windows loads from a system directory. Do not replace the system DLL.
  2. Open Tools / EurekaLog / IDE options. Set DbgHelp.dll path to the selected library.
  3. Set Cache to a writable directory with room for the symbol set. The old documentation's roughly 500 MiB planning figure is not a storage ceiling; allow for the modules and versions you actually investigate.
  4. Add Debug symbol sources: a local folder, an authorized network share, or the symbol server used by your investigation environment. The documented Use defaults action fills in a cache and Microsoft's symbol source; inspect the resulting settings, including its URL, rather than assuming the historical default expresses your transport policy.
  5. For an application that should resolve Microsoft symbols while capturing a new report, enable Microsoft DBG/PDB in the project's debug-information provider configuration. This is distinct from configuring the machine's search paths.

On a machine without the IDE, Bin\SetDebugSymbolsPath.exe exposes the library, cache, and source settings. Fill those values and click Set for EurekaLog. Remove all symbol sources and apply again to disable that symbol-source configuration. Set for Process Explorer tool configures Process Explorer; Set other is a separate action that requires administrator rights.

Downloading symbols can be slow, especially with an empty cache. Use this deliberately on a diagnostic machine; do not silently enable network symbol downloads throughout your user base. Disable hang detection during this diagnostic setup to avoid classifying slow symbol retrieval as a new application hang. A later symbol setup also does not guarantee that Viewer will reconstruct information absent from an already captured text report; use address lookup or a controlled new capture for the question at hand.

4.6 Build a triage view that does not hide the next clue

After preserving originals, a Viewer database can provide a useful worklist.

  1. Select Configure / Configure columns. Add the fields useful to your queue, including Status, Note, Count, and the application/date/type fields available in your report set. Move columns by dragging their headers.
  2. Click a header to sort; click again to reverse the order. Hold Shift while clicking other headers for multi-column sorting. Ctrl-click a header to remove its sort.
  3. Use the right edge of a column header to filter values. For example, filter Status to New. Choose (All) to clear that column's filter, or the X at the lower-left conditions bar to clear filtering.
  4. Drag a column header into the grouping area above the report list to group by that value. Drag it back to undo grouping. Grouping the display is not the same as merging reports during import.
  5. For repeated investigation views, choose (Custom...) in a filter, then Customize... on the conditions bar for compound conditions. Save as... and Open... save/load the filter as an .flt file.

The Status column allows New, Fixed, Postponed, or Rejected. The Note column accepts investigation notes, such as the reproduction, issue reference, or reason for postponement. These are Viewer database-management actions; they are not automatically commands to change a remote tracker issue or deployed application's behavior.

Before declaring reports missing, remove filters and check the current file/database mode. A hidden row, an in-memory database closed yesterday, and an import merged by BugID are three different explanations for an apparently empty queue.

Prioritize using both impact and frequency. A frequent harmless validation failure does not outrank a rare data-corruption incident merely because its Count is larger. Counts also depend on local deduplication, sender fallback, tracker workflow, and Viewer import rules; they are not a count of unique affected users.

4.7 Turn a group of reports into a tested explanation

Start a short investigation record that separates observation from hypothesis:

Observed: exact build/platform, exception kind and message,
          reported location, relevant thread, available attachments.
Reproduction: action/input/environment; reproduced or not reproduced.
Hypothesis: proposed state/ownership/timing failure, not yet established.
Evidence: matching source/binary, stack confidence, relevant logs,
          comparison with other preserved occurrences.
Next check: the smallest experiment that distinguishes the hypotheses.
Resolution: changed behavior and the build/retest that demonstrates it.

Use chapter 20 to interpret the report. For an ordinary exception, inspect the exception's location and relevant call stack before roaming through every system-information section. For a leak, allocation/ownership evidence may matter more than the dummy exception fields. For a hang, compare thread stacks and waits rather than treating the active thread as a crashed thread. A detection location may be where corrupted state was finally noticed, not where it was created.

Classify the incident into a useful next action:

  • Application defect: reproduce the state transition and fix its cause, then repeat the original scenario on the candidate build.
  • Expected/domain failure handled badly: establish whether the application should recover, show validation feedback, or report an unexpected condition. Do not suppress every exception of a broad class to hide one noisy path.
  • Environment or deployment problem: identify the missing permission, dependency, configuration, or unsupported combination and verify the corrected deployment. Preserve the evidence rather than labeling it “user error”.
  • Incomplete evidence: identify exactly what is missing—matching build, reliable stack, attachment, reproduction input, or live hang snapshot—and request only that information through an appropriate channel.
  • Reporting/integration failure: if EurekaLog itself is implicated, retain internal diagnostic output and use chapter 5. A report about a reporting failure is not automatically an application root cause.

BugID is a grouping key, not a verdict

BugID is derived from configured exception/location information. Equal BugIDs tell you that the configured grouping rule matched. They do not prove identical root causes, identical runtime state, or equivalent reports. Different BugIDs can also arise from one underlying defect through different detection paths or build changes.

Before merging engineering issues, compare the exact builds, exception kinds/messages, relevant stacks, and reproductions. Keep separate evidence for contradictory occurrences. If a grouping rule persistently joins unrelated failures, review BugID configuration and the explicit CustomID mechanism described in chapter 8 rather than teaching investigators to ignore the contradiction.

A useful deduplication workflow therefore has two layers: automatic grouping for intake volume, and human-confirmed issue relationships for root-cause work. Preserve report originals so you can split a mistaken group later.

4.8 Close an issue without shutting off useful evidence too early

Tracker status affects what the application will do on the next report. In the documented default workflow:

Sender's interpretation Subsequent matching reports
NEW The issue is open; occurrence updates and configured report uploads can continue.
IN PROGRESS The count can continue to update, but additional report files are rejected by that workflow. Use it only when you intentionally no longer need new files.
CLOSED Normal collection/counting stops and the sender can report that the bug is fixed/closed. Closing does not prove the client runs a fixed build.

The exact status names and mappings depend on the sender options and tracker configuration. Duplicate-file options can suppress additional files even before a status transition; a missing second attachment is not necessarily a transport failure. Email senders cannot perform the same closed-issue check, and plain HTTP needs an implemented receiver/feedback protocol to do it.

Before marking a defect fixed:

  1. Reproduce the original behavior where possible, retaining the inputs and environment needed for the check.
  2. Verify the candidate fix with that scenario and the relevant boundary conditions. Record which build and configuration were exercised; “new version offered” is not a successful retest.
  3. Make the corrected version available through your release process. Record the fixed-in version in the tracker if your sender uses it.
  4. Then close the issue with a clear resolution. A rejected or environmental issue needs an accurate explanation, not a misleading generic “fixed in an update”. Configure closed-issue feedback accordingly.
  5. Watch reports from the fixed build separately from reports from older clients. Investigate contradictions before assuming every occurrence is obsolete.

Automatic reopening is supported only by some tracker/send methods. It requires executable version information, released versions in the tracker, Use versions enabled, and a recorded fixed-in version. The documented rule reopens when a report arrives from version M at or beyond the fixed version N (M >= N). Without those prerequisites, do not expect a closed issue to reopen merely because a user says they installed the update.

A completed investigation ends with an explanation supported by evidence and a verified change or deployment correction—not merely a closed ticket or a matching BugID. Keep enough of the original report/build/retest record to recognize a recurrence.