Skip to content

Commit 8515f83

Browse files
committed
Crash reports keep the start of a long dump (the crashing thread) as well as its end
1 parent e748d1f commit 8515f83

3 files changed

Lines changed: 24 additions & 2 deletions

File tree

‎launcher/Launch.cs‎

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -297,7 +297,11 @@ static string CrashLogSinceSent(string dir)
297297
try { offset = long.Parse(File.ReadAllText(Path.Combine(dir, "lapsecoin-crash.sent")).Trim()); } catch (Exception) { }
298298
if (offset < 0 || offset > text.Length) offset = 0;
299299
string tail = text.Substring((int)offset);
300-
return tail.Length > MaxTrace ? tail.Substring(tail.Length - MaxTrace) : tail;
300+
if (tail.Length <= MaxTrace) return tail;
301+
// A native crash dump starts with the thread that crashed, so keep the start too.
302+
const string gap = "\n[...]\n";
303+
int head = MaxTrace / 2;
304+
return tail.Substring(0, head) + gap + tail.Substring(tail.Length - (MaxTrace - head - gap.Length));
301305
}
302306
catch (Exception) { return ""; }
303307
}

‎src/crashlog.py‎

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,16 @@ def _start_log_tail(lines=15):
210210
return ""
211211

212212

213+
def _head_and_tail(text, limit):
214+
"""A native crash dump starts with the thread that crashed and a Python
215+
traceback ends with the error, so a long text keeps both ends."""
216+
if len(text) <= limit:
217+
return text
218+
gap = "\n[...]\n"
219+
head = limit // 2
220+
return text[:head] + gap + text[-(limit - head - len(gap)):]
221+
222+
213223
def build_payload(kind, where, trace, sig):
214224
"""What is sent: nothing beyond this."""
215225
import platform
@@ -221,7 +231,7 @@ def build_payload(kind, where, trace, sig):
221231
return {"v": 1, "kind": kind, "where": where, "sig": sig,
222232
"app": version, "windows": platform.version(), "arch": platform.machine(),
223233
"python": platform.python_version(), "packaged": _packaged(),
224-
"trace": sanitize(trace)[-MAX_TRACE:],
234+
"trace": _head_and_tail(sanitize(trace), MAX_TRACE),
225235
"steps": sanitize(_start_log_tail())[-MAX_STEPS:]}
226236

227237

‎tests/test_crashlog.py‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -276,6 +276,14 @@ def test_a_log_with_nothing_critical_sends_nothing(self, reporting, monkeypatch)
276276
assert gh.requests == []
277277

278278

279+
class TestLongDumps:
280+
def test_a_long_dump_keeps_the_crashing_thread_and_the_end(self):
281+
dump = "Windows fatal exception: access violation\n" + "x" * 9000 + "\nTHE END"
282+
kept = crashlog._head_and_tail(dump, crashlog.MAX_TRACE)
283+
assert kept.startswith("Windows fatal exception") and kept.endswith("THE END")
284+
assert len(kept) == crashlog.MAX_TRACE
285+
286+
279287
class TestWhatIsSent:
280288
def test_the_account_name_paths_and_addresses_are_taken_out(self, reporting, monkeypatch):
281289
monkeypatch.setenv("USERNAME", "Vic")

0 commit comments

Comments
 (0)