Python Crash Dump Analysis Case Study

When working on Region Profile memory analysis pattern, we decided to combine two separate Pandas profiling scripts into one:

import pandas as pd
import pandas_profiling

df = pd.read_csv("stack.csv")
html_file = open("stack.html", "w")
html_file.write (pandas_profiling.ProfileReport(df).to_html())
html_file.close()

df = pd.read_csv("stack4columns.csv")
html_file = open("stack4columns.html", "w")
html_file.write (pandas_profiling.ProfileReport(df).to_html())
html_file.close()

Unfortunately, python.exe crashed. Since we always configure LocalDumps to catch interesting crashes we got python.exe.2140.dmp. We promptly loaded it into Microsoft WinDbg Debugger (or WinDbg Preview, see quick download links) and saw Self-Diagnosis from Top Module in Exception Stack Trace (if we ignore exception processing function calls):

0:020> k
# Child-SP RetAddr Call Site
00 00000064`007bbb08 00007ffd`3cac7ff7 ntdll!NtWaitForMultipleObjects+0x14
01 00000064`007bbb10 00007ffd`3cac7ede KERNELBASE!WaitForMultipleObjectsEx+0x107
02 00000064`007bbe10 00007ffd`3f6871fb KERNELBASE!WaitForMultipleObjects+0xe
03 00000064`007bbe50 00007ffd`3f686ca8 kernel32!WerpReportFaultInternal+0x51b
04 00000064`007bbf70 00007ffd`3cb6f848 kernel32!WerpReportFault+0xac
05 00000064`007bbfb0 00007ffd`3f7c4af2 KERNELBASE!UnhandledExceptionFilter+0x3b8
06 00000064`007bc0d0 00007ffd`3f7ac6e6 ntdll!RtlUserThreadStart$filt$0+0xa2
07 00000064`007bc110 00007ffd`3f7c120f ntdll!_C_specific_handler+0x96
08 00000064`007bc180 00007ffd`3f78a299 ntdll!RtlpExecuteHandlerForException+0xf
09 00000064`007bc1b0 00007ffd`3f7bfe7e ntdll!RtlDispatchException+0x219
0a 00000064`007bc8c0 00007ffd`01f5735d ntdll!KiUserExceptionDispatch+0x2e
0b 00000064`007bd070 00007ffd`01f57392 tcl86t!Tcl_PanicVA+0x13d
0c 00000064`007bd0f0 00007ffd`01e83884 tcl86t!Tcl_Panic+0x22

0d 00000064`007bd120 00007ffd`01e86393 tcl86t!Tcl_AsyncDelete+0x114
0e 00000064`007bd150 00007ffd`234c414c tcl86t!Tcl_DeleteInterp+0xf3
0f 00000064`007bd1a0 00007ffc`ef4f728d _tkinter!PyInit__tkinter+0x14bc
10 00000064`007bd1d0 00007ffc`ef4f5706 python37!PyObject_Hash+0x349
11 00000064`007bd210 00007ffc`ef4f71ed python37!PyDict_GetItem+0x4a6
12 00000064`007bd260 00007ffc`ef53c803 python37!PyObject_Hash+0x2a9
13 00000064`007bd2a0 00007ffc`ef4e0673 python37!PyErr_NoMemory+0xe49f
14 00000064`007bd2d0 00007ffc`ef514ee4 python37!PyCFunction_NewEx+0x137
15 00000064`007bd300 00007ffc`ef514b20 python37!PyMethod_ClearFreeList+0x568
16 00000064`007bd3a0 00007ffc`ef514add python37!PyMethod_ClearFreeList+0x1a4
17 00000064`007bd3d0 00007ffc`ef538500 python37!PyMethod_ClearFreeList+0x161
18 00000064`007bd400 00007ffc`ef4da197 python37!PyErr_NoMemory+0xa19c
19 00000064`007bd430 00007ffc`ef50e77d python37!PyObject_GetIter+0x1f
1a 00000064`007bd460 00007ffc`ef50b146 python37!PyEval_EvalFrameDefault+0xa4d
1b 00000064`007bd5a0 00007ffc`ef50dbcc python37!PyEval_EvalCodeWithName+0x1a6
1c 00000064`007bd640 00007ffc`ef50e1df python37!PyMethodDef_RawFastCallKeywords+0xccc
1d 00000064`007bd700 00007ffc`ef50b146 python37!PyEval_EvalFrameDefault+0x4af
1e 00000064`007bd840 00007ffc`ef4d358b python37!PyEval_EvalCodeWithName+0x1a6
*** WARNING: Unable to verify checksum for lib.cp37-win_amd64.pyd
1f 00000064`007bd8e0 00007ffd`02bb9163 python37!PyEval_EvalCodeEx+0x9b
20 00000064`007bd970 00007ffd`02bb8c82 lib_cp37_win_amd64+0x9163
21 00000064`007bd9f0 00007ffd`02bda552 lib_cp37_win_amd64+0x8c82
22 00000064`007bda20 00007ffd`02bdaeed lib_cp37_win_amd64!PyInit_lib+0x1c542
23 00000064`007bdb50 00007ffc`ef50d255 lib_cp37_win_amd64!PyInit_lib+0x1cedd
24 00000064`007bdbe0 00007ffc`ef50db17 python37!PyMethodDef_RawFastCallKeywords+0x355
25 00000064`007bdc60 00007ffc`ef50ed2a python37!PyMethodDef_RawFastCallKeywords+0xc17
26 00000064`007bdd20 00007ffc`ef50b146 python37!PyEval_EvalFrameDefault+0xffa
27 00000064`007bde60 00007ffc`ef50dbcc python37!PyEval_EvalCodeWithName+0x1a6
28 00000064`007bdf00 00007ffc`ef50e5e2 python37!PyMethodDef_RawFastCallKeywords+0xccc
29 00000064`007bdfc0 00007ffc`ef50dab3 python37!PyEval_EvalFrameDefault+0x8b2
2a 00000064`007be100 00007ffc`ef50e1df python37!PyMethodDef_RawFastCallKeywords+0xbb3
2b 00000064`007be1c0 00007ffc`ef50dab3 python37!PyEval_EvalFrameDefault+0x4af
2c 00000064`007be300 00007ffc`ef50e5e2 python37!PyMethodDef_RawFastCallKeywords+0xbb3
2d 00000064`007be3c0 00007ffc`ef50dab3 python37!PyEval_EvalFrameDefault+0x8b2
2e 00000064`007be500 00007ffc`ef50e1df python37!PyMethodDef_RawFastCallKeywords+0xbb3
2f 00000064`007be5c0 00007ffc`ef50a3bd python37!PyEval_EvalFrameDefault+0x4af
30 00000064`007be700 00007ffc`ef4dc53b python37!PyFunction_FastCallDict+0xdd
31 00000064`007be7d0 00007ffc`ef5be47b python37!PyObject_Call+0xd3
32 00000064`007be800 00007ffc`ef5029cd python37!Py_hashtable_size+0x3e63
33 00000064`007be830 00007ffc`ef520b7b python37!PyList_Extend+0x1f1
34 00000064`007be870 00007ffc`ef520b3f python37!PyBuiltin_Init+0x587
35 00000064`007be8a0 00007ffc`ef4f78a7 python37!PyBuiltin_Init+0x54b
36 00000064`007be8e0 00007ffc`ef4f763a python37!PyObject_FastCallKeywords+0x3e7
37 00000064`007be910 00007ffc`ef50dbfe python37!PyObject_FastCallKeywords+0x17a
38 00000064`007be970 00007ffc`ef50e1df python37!PyMethodDef_RawFastCallKeywords+0xcfe
39 00000064`007bea30 00007ffc`ef50a3bd python37!PyEval_EvalFrameDefault+0x4af
3a 00000064`007beb70 00007ffc`ef4de47d python37!PyFunction_FastCallDict+0xdd
3b 00000064`007bec40 00007ffc`ef50eea5 python37!PyObject_IsAbstract+0x1b1
3c 00000064`007bec80 00007ffc`ef50b146 python37!PyEval_EvalFrameDefault+0x1175
3d 00000064`007bedc0 00007ffc`ef50a49a python37!PyEval_EvalCodeWithName+0x1a6
3e 00000064`007bee60 00007ffc`ef4de47d python37!PyFunction_FastCallDict+0x1ba
3f 00000064`007bef30 00007ffc`ef50eea5 python37!PyObject_IsAbstract+0x1b1
40 00000064`007bef70 00007ffc`ef50dab3 python37!PyEval_EvalFrameDefault+0x1175
41 00000064`007bf0b0 00007ffc`ef50e133 python37!PyMethodDef_RawFastCallKeywords+0xbb3
42 00000064`007bf170 00007ffc`ef50dab3 python37!PyEval_EvalFrameDefault+0x403
43 00000064`007bf2b0 00007ffc`ef50e133 python37!PyMethodDef_RawFastCallKeywords+0xbb3
44 00000064`007bf370 00007ffc`ef50a3bd python37!PyEval_EvalFrameDefault+0x403
45 00000064`007bf4b0 00007ffc`ef50a1de python37!PyFunction_FastCallDict+0xdd
46 00000064`007bf580 00007ffc`ef4de3f4 python37!PyMember_GetOne+0x732
47 00000064`007bf610 00007ffc`ef50eea5 python37!PyObject_IsAbstract+0x128
48 00000064`007bf650 00007ffc`ef50a3bd python37!PyEval_EvalFrameDefault+0x1175
49 00000064`007bf790 00007ffc`ef51e834 python37!PyFunction_FastCallDict+0xdd
4a 00000064`007bf860 00007ffc`ef51e7a1 python37!PyObject_Call_Prepend+0x6c
4b 00000064`007bf8f0 00007ffc`ef4dc4dd python37!PyDict_Contains+0x6d5
4c 00000064`007bf920 00007ffc`ef5d7a4e python37!PyObject_Call+0x75
4d 00000064`007bf950 00007ffc`ef67894a python37!PySignal_AfterFork+0x157a
4e 00000064`007bf980 00007ffd`3cd6d9f2 python37!PyThread_tss_is_created+0xde
4f 00000064`007bf9b0 00007ffd`3f637bd4 ucrtbase!thread_start<unsigned int (__cdecl*)(void *),1>+0x42
50 00000064`007bf9e0 00007ffd`3f78cee1 kernel32!BaseThreadInitThunk+0x14
51 00000064`007bfa10 00000000`00000000 ntdll!RtlUserThreadStart+0x21

We noticed PyErr_NoMemory function calls, but the offset was too big (0xe49f) that we considered that Incorrect Symbolic Information. Indeed, there were only export symbols available:

0:020> lmv m python37
Browse full module list
start end module name
00007ffc`ef4d0000 00007ffc`ef88f000 python37 (export symbols) python37.dll
Loaded symbol image file: python37.dll
Image path: C:\Program Files (x86)\Microsoft Visual Studio\Shared\Python37_64\python37.dll
Image name: python37.dll
Browse all global symbols functions data
Timestamp: Mon Mar 25 22:22:41 2019 (5C9954B1)
CheckSum: 00396A11
ImageSize: 003BF000
File version: 3.7.3150.1013
Product version: 3.7.3150.1013
File flags: 0 (Mask 3F)
File OS: 4 Unknown Win32
File type: 2.0 Dll
File date: 00000000.00000000
Translations: 0000.04b0
Information from resource tables:
CompanyName: Python Software Foundation
ProductName: Python
InternalName: Python DLL
OriginalFilename: python37.dll
ProductVersion: 3.7.3
FileVersion: 3.7.3
FileDescription: Python Core
LegalCopyright: Copyright © 2001-2016 Python Software Foundation. Copyright © 2000 BeOpen.com. Copyright © 1995-2001 CNRI. Copyright © 1991-1995 SMC.

Fortunately, this Python installation came with PDB files, so we provided a path to them:

0:020> .sympath+ C:\Program Files (x86)\Microsoft Visual Studio\Shared\Python37_64
Symbol search path is: srv*;C:\Program Files (x86)\Microsoft Visual Studio\Shared\Python37_64
Expanded Symbol search path is: cache*;SRV*https://msdl.microsoft.com/download/symbols;
c:\program files (x86)\microsoft visual studio\shared\python37_64

************* Path validation summary **************
Response Time (ms) Location
Deferred srv*
OK C:\Program Files (x86)\Microsoft Visual Studio\Shared\Python37_64

Then we got the better stack trace:

0:020> .ecxr
rax=0000000000000000 rbx=00007ffd01fd0e60 rcx=0000000000002402
rdx=00007ffd3ce3b770 rsi=00007ffd02000200 rdi=000001b38a51d9c0
rip=00007ffd01f5735d rsp=00000064007bd070 rbp=0000000000000002
r8=00000064007bc828 r9=00000064007bc920 r10=0000000000000000
r11=00000064007bcf70 r12=000001b38a51d9c0 r13=000001b38a51d8c0
r14=000001b38a51d9c0 r15=00007ffd01e86393
iopl=0 nv up ei pl nz na pe nc
cs=0033 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000202
tcl86t!Tcl_PanicVA+0x13d:
00007ffd`01f5735d cc int 3

0:020> kL
*** Stack trace for last set context - .thread/.cxr resets it
# Child-SP RetAddr Call Site
00 00000064`007bd070 00007ffd`01f57392 tcl86t!Tcl_PanicVA+0x13d
01 00000064`007bd0f0 00007ffd`01e83884 tcl86t!Tcl_Panic+0x22
02 00000064`007bd120 00007ffd`01e86393 tcl86t!Tcl_AsyncDelete+0x114
03 00000064`007bd150 00007ffd`234c414c tcl86t!Tcl_DeleteInterp+0xf3
04 00000064`007bd1a0 00007ffc`ef4f728d _tkinter!PyInit__tkinter+0x14bc
05 00000064`007bd1d0 00007ffc`ef4f5706 python37!dict_dealloc+0x22d
06 00000064`007bd210 00007ffc`ef4f71ed python37!subtype_dealloc+0x176
07 (Inline Function) --------`-------- python37!free_keys_object+0xf5
08 00000064`007bd260 00007ffc`ef53c803 python37!dict_dealloc+0x18d
09 00000064`007bd2a0 00007ffc`ef4e0673 python37!subtype_clear+0x5b967
0a 00000064`007bd2d0 00007ffc`ef514ee4 python37!delete_garbage+0x4b
0b 00000064`007bd300 00007ffc`ef514b20 python37!collect+0x184
0c 00000064`007bd3a0 00007ffc`ef514add python37!collect_with_callback+0x34
0d 00000064`007bd3d0 00007ffc`ef538500 python37!collect_generations+0x4d
0e (Inline Function) --------`-------- python37!_PyObject_GC_Alloc+0x5e2ec
0f (Inline Function) --------`-------- python37!_PyObject_GC_Malloc+0x5e2ec
10 (Inline Function) --------`-------- python37!_PyObject_GC_New+0x5e2f3

11 00000064`007bd400 00007ffc`ef4da197 python37!tuple_iter+0x5e310
12 00000064`007bd430 00007ffc`ef50e77d python37!PyObject_GetIter+0x1f
13 00000064`007bd460 00007ffc`ef50b146 python37!_PyEval_EvalFrameDefault+0xa4d
14 (Inline Function) --------`-------- python37!PyEval_EvalFrameEx+0x17
15 00000064`007bd5a0 00007ffc`ef50dbcc python37!_PyEval_EvalCodeWithName+0x1a6
16 (Inline Function) --------`-------- python37!_PyFunction_FastCallKeywords+0x1ca
17 00000064`007bd640 00007ffc`ef50e1df python37!call_function+0x3ac
18 00000064`007bd700 00007ffc`ef50b146 python37!_PyEval_EvalFrameDefault+0x4af
19 (Inline Function) --------`-------- python37!PyEval_EvalFrameEx+0x17
1a 00000064`007bd840 00007ffc`ef4d358b python37!_PyEval_EvalCodeWithName+0x1a6
1b 00000064`007bd8e0 00007ffd`02bb9163 python37!PyEval_EvalCodeEx+0x9b
1c 00000064`007bd970 00007ffd`02bb8c82 lib_cp37_win_amd64+0x9163
1d 00000064`007bd9f0 00007ffd`02bda552 lib_cp37_win_amd64+0x8c82
1e 00000064`007bda20 00007ffd`02bdaeed lib_cp37_win_amd64!PyInit_lib+0x1c542
1f 00000064`007bdb50 00007ffc`ef50d255 lib_cp37_win_amd64!PyInit_lib+0x1cedd
20 00000064`007bdbe0 00007ffc`ef50db17 python37!_PyMethodDef_RawFastCallKeywords+0x355
21 (Inline Function) --------`-------- python37!_PyCFunction_FastCallKeywords+0x22
22 00000064`007bdc60 00007ffc`ef50ed2a python37!call_function+0x2f7
23 00000064`007bdd20 00007ffc`ef50b146 python37!_PyEval_EvalFrameDefault+0xffa
24 (Inline Function) --------`-------- python37!PyEval_EvalFrameEx+0x17
25 00000064`007bde60 00007ffc`ef50dbcc python37!_PyEval_EvalCodeWithName+0x1a6
26 (Inline Function) --------`-------- python37!_PyFunction_FastCallKeywords+0x1ca
27 00000064`007bdf00 00007ffc`ef50e5e2 python37!call_function+0x3ac
28 00000064`007bdfc0 00007ffc`ef50dab3 python37!_PyEval_EvalFrameDefault+0x8b2
29 (Inline Function) --------`-------- python37!PyEval_EvalFrameEx+0x17
2a (Inline Function) --------`-------- python37!function_code_fastcall+0x5e
2b (Inline Function) --------`-------- python37!_PyFunction_FastCallKeywords+0xb1
2c 00000064`007be100 00007ffc`ef50e1df python37!call_function+0x293
2d 00000064`007be1c0 00007ffc`ef50dab3 python37!_PyEval_EvalFrameDefault+0x4af
2e (Inline Function) --------`-------- python37!PyEval_EvalFrameEx+0x17
2f (Inline Function) --------`-------- python37!function_code_fastcall+0x5e
30 (Inline Function) --------`-------- python37!_PyFunction_FastCallKeywords+0xb1
31 00000064`007be300 00007ffc`ef50e5e2 python37!call_function+0x293
32 00000064`007be3c0 00007ffc`ef50dab3 python37!_PyEval_EvalFrameDefault+0x8b2
33 (Inline Function) --------`-------- python37!PyEval_EvalFrameEx+0x17
34 (Inline Function) --------`-------- python37!function_code_fastcall+0x5e
35 (Inline Function) --------`-------- python37!_PyFunction_FastCallKeywords+0xb1
36 00000064`007be500 00007ffc`ef50e1df python37!call_function+0x293
37 00000064`007be5c0 00007ffc`ef50a3bd python37!_PyEval_EvalFrameDefault+0x4af
38 (Inline Function) --------`-------- python37!PyEval_EvalFrameEx+0x17
39 (Inline Function) --------`-------- python37!function_code_fastcall+0x5c
3a 00000064`007be700 00007ffc`ef4dc53b python37!_PyFunction_FastCallDict+0xdd
3b 00000064`007be7d0 00007ffc`ef5be47b python37!PyObject_Call+0xd3
3c 00000064`007be800 00007ffc`ef5029cd python37!starmap_next+0x67
3d 00000064`007be830 00007ffc`ef520b7b python37!list_extend+0x1e9
3e 00000064`007be870 00007ffc`ef520b3f python37!list___init___impl+0x27
3f 00000064`007be8a0 00007ffc`ef4f78a7 python37!list___init__+0x67
40 00000064`007be8e0 00007ffc`ef4f763a python37!type_call+0xa7
41 00000064`007be910 00007ffc`ef50dbfe python37!_PyObject_FastCallKeywords+0x17a
42 00000064`007be970 00007ffc`ef50e1df python37!call_function+0x3de
43 00000064`007bea30 00007ffc`ef50a3bd python37!_PyEval_EvalFrameDefault+0x4af
44 (Inline Function) --------`-------- python37!PyEval_EvalFrameEx+0x17
45 (Inline Function) --------`-------- python37!function_code_fastcall+0x5c
46 00000064`007beb70 00007ffc`ef4de47d python37!_PyFunction_FastCallDict+0xdd
47 (Inline Function) --------`-------- python37!PyObject_Call+0xcf
48 00000064`007bec40 00007ffc`ef50eea5 python37!do_call_core+0x14d
49 00000064`007bec80 00007ffc`ef50b146 python37!_PyEval_EvalFrameDefault+0x1175
4a (Inline Function) --------`-------- python37!PyEval_EvalFrameEx+0x17
4b 00000064`007bedc0 00007ffc`ef50a49a python37!_PyEval_EvalCodeWithName+0x1a6
4c 00000064`007bee60 00007ffc`ef4de47d python37!_PyFunction_FastCallDict+0x1ba
4d (Inline Function) --------`-------- python37!PyObject_Call+0xcf
4e 00000064`007bef30 00007ffc`ef50eea5 python37!do_call_core+0x14d
4f 00000064`007bef70 00007ffc`ef50dab3 python37!_PyEval_EvalFrameDefault+0x1175
50 (Inline Function) --------`-------- python37!PyEval_EvalFrameEx+0x17
51 (Inline Function) --------`-------- python37!function_code_fastcall+0x5e
52 (Inline Function) --------`-------- python37!_PyFunction_FastCallKeywords+0xb1
53 00000064`007bf0b0 00007ffc`ef50e133 python37!call_function+0x293
54 00000064`007bf170 00007ffc`ef50dab3 python37!_PyEval_EvalFrameDefault+0x403
55 (Inline Function) --------`-------- python37!PyEval_EvalFrameEx+0x17
56 (Inline Function) --------`-------- python37!function_code_fastcall+0x5e
57 (Inline Function) --------`-------- python37!_PyFunction_FastCallKeywords+0xb1
58 00000064`007bf2b0 00007ffc`ef50e133 python37!call_function+0x293
59 00000064`007bf370 00007ffc`ef50a3bd python37!_PyEval_EvalFrameDefault+0x403
5a (Inline Function) --------`-------- python37!PyEval_EvalFrameEx+0x17
5b (Inline Function) --------`-------- python37!function_code_fastcall+0x5c
5c 00000064`007bf4b0 00007ffc`ef50a1de python37!_PyFunction_FastCallDict+0xdd
5d (Inline Function) --------`-------- python37!_PyObject_FastCallDict+0x25
5e (Inline Function) --------`-------- python37!_PyObject_Call_Prepend+0x5a
5f 00000064`007bf580 00007ffc`ef4de3f4 python37!method_call+0x92
60 (Inline Function) --------`-------- python37!PyObject_Call+0x46
61 00000064`007bf610 00007ffc`ef50eea5 python37!do_call_core+0xc4
62 00000064`007bf650 00007ffc`ef50a3bd python37!_PyEval_EvalFrameDefault+0x1175
63 (Inline Function) --------`-------- python37!PyEval_EvalFrameEx+0x17
64 (Inline Function) --------`-------- python37!function_code_fastcall+0x5c
65 00000064`007bf790 00007ffc`ef51e834 python37!_PyFunction_FastCallDict+0xdd
66 00000064`007bf860 00007ffc`ef51e7a1 python37!_PyObject_Call_Prepend+0x6c
67 00000064`007bf8f0 00007ffc`ef4dc4dd python37!slot_tp_call+0x51
68 00000064`007bf920 00007ffc`ef5d7a4e python37!PyObject_Call+0x75
69 00000064`007bf950 00007ffc`ef67894a python37!t_bootstrap+0x6a
6a 00000064`007bf980 00007ffd`3cd6d9f2 python37!bootstrap+0x32
6b 00000064`007bf9b0 00007ffd`3f637bd4 ucrtbase!thread_start<unsigned int (__cdecl*)(void *),1>+0x42
6c 00000064`007bf9e0 00007ffd`3f78cee1 kernel32!BaseThreadInitThunk+0x14
6d 00000064`007bfa10 00000000`00000000 ntdll!RtlUserThreadStart+0x21

We noticed that something wasn’t quite right during Python garbage collection processing, so we disabled GC in our script and the problem was gone for the duration of its execution:

import gc

gc.disable()

Of course, we consider this as a temporary workaround and should add it to our Workaround Patterns catalog.