4 export EXECUTION_DIR=$(dirname "$0")
6 exitcode_list[0]="Exited Successfully"
7 exitcode_list[130]="SIGINT Ctrl-C occurred. Likely tests timed out."
8 exitcode_list[131]="SIGQUIT Ctrl-\ occurred. Core dumped."
9 exitcode_list[132]="SIGILL Illegal Instruction. Core dumped. Likely codegen issue."
10 exitcode_list[133]="SIGTRAP Breakpoint hit. Core dumped."
11 exitcode_list[134]="SIGABRT Abort. Managed or native assert, or runtime check such as heap corruption, caused call to abort(). Core dumped."
12 exitcode_list[135]="IGBUS Unaligned memory access. Core dumped."
13 exitcode_list[136]="SIGFPE Bad floating point arguments. Core dumped."
14 exitcode_list[137]="SIGKILL Killed eg by kill"
15 exitcode_list[139]="SIGSEGV Illegal memory access. Deref invalid pointer, overrunning buffer, stack overflow etc. Core dumped."
16 exitcode_list[143]="SIGTERM Terminated. Usually before SIGKILL."
17 exitcode_list[159]="SIGSYS Bad System Call."
19 function print_info_from_core_file_using_lldb {
20 local core_file_name=$1
21 local executable_name=$2
22 local plugin_path_name="$RUNTIME_PATH/shared/Microsoft.NETCore.App/9.9.9/libsosplugin.so"
24 # check for existence of lldb on the path
25 hash lldb 2>/dev/null || { echo >&2 "lldb was not found. Unable to print core file."; return; }
27 # pe and clrstack are defined in libsosplugin.so
28 if [ ! -f $plugin_path_name ]; then
29 echo $plugin_path_name cannot be found.
33 echo ----- start =============== lldb Output =====================================================
34 echo Printing managed exceptions and managed call stack.
35 lldb -O "settings set target.exec-search-paths $RUNTIME_PATH" -o "plugin load $plugin_path_name" -o "clrthreads -managedexception" -o "pe -nested" -o "clrstack -all -a -f" -o "quit" --core $core_file_name $executable_name
36 echo ----- end =============== lldb Output =======================================================
39 function print_info_from_core_file_using_gdb {
40 local core_file_name=$1
41 local executable_name=$2
43 # Check for the existence of GDB on the path
44 hash gdb 2>/dev/null || { echo >&2 "GDB was not found. Unable to print core file."; return; }
46 echo ----- start =============== GDB Output =====================================================
47 # Open the dump in GDB and print the stack from each thread. We can add more
48 # commands here if desired.
49 echo printing native stack.
50 gdb --batch -ex "thread apply all bt full" -ex "quit" $executable_name $core_file_name
51 echo ----- end =============== GDB Output =======================================================
54 function print_info_from_core_file {
55 local core_file_name=$1
56 local executable_name=$RUNTIME_PATH/$2
58 if ! [ -e $executable_name ]; then
59 echo "Unable to find executable $executable_name"
61 elif ! [ -e $core_file_name ]; then
62 echo "Unable to find core file $core_file_name"
65 echo "Printing info from core file $core_file_name"
66 print_info_from_core_file_using_gdb $core_file_name $executable_name
67 print_info_from_core_file_using_lldb $core_file_name $executable_name
70 function copy_core_file_to_temp_location {
71 local core_file_name=$1
73 local storage_location="/tmp/coredumps"
75 # Create the directory (this shouldn't fail even if it already exists).
76 mkdir -p $storage_location
78 local new_location=$storage_location/core.$RANDOM
80 echo "Copying core file $core_file_name to $new_location in case you need it."
81 cp $core_file_name $new_location
84 if [ "$RUNTIME_PATH" == "" ]
86 echo error: RUNTIME_PATH is not defined. Usage: $0 RUNTIME_PATH
90 # ========================= BEGIN Core File Setup ============================
91 if [ "$(uname -s)" == "Darwin" ]; then
92 # On OS X, we will enable core dump generation only if there are no core
93 # files already in /cores/ at this point. This is being done to prevent
94 # inadvertently flooding the CI machines with dumps.
95 if [[ ! -d "/cores" || ! "$(ls -A /cores)" ]]; then
98 elif [ "$(uname -s)" == "Linux" ]; then
99 # On Linux, we'll enable core file generation unconditionally, and if a dump
100 # is generated, we will print some useful information from it and delete the
103 if [ -e /proc/self/coredump_filter ]; then
104 # Include memory in private and shared file-backed mappings in the dump.
105 # This ensures that we can see disassembly from our shared libraries when
106 # inspecting the contents of the dump. See 'man core' for details.
107 echo -n 0x3F > /proc/self/coredump_filter
112 # ========================= END Core File Setup ==============================
114 # ========================= BEGIN Test Execution =============================
115 echo ----- start $(date +"%T") =============== To repro directly: =====================================================
116 echo pushd $EXECUTION_DIR
117 [[TestRunCommandsEcho]]
119 echo ===========================================================================================================
124 echo ----- end $(date +"%T") ----- exit code $test_exitcode ----------------------------------------------------------
126 if [ "${exitcode_list[$test_exitcode]}" != "" ]; then
127 echo exit code $test_exitcode means ${exitcode_list[$test_exitcode]}
129 # ========================= END Test Execution ===============================
131 # ======================= BEGIN Core File Inspection =========================
132 pushd $EXECUTION_DIR >/dev/null
133 if [[ "$(uname -s)" == "Linux" && $test_exitcode -ne 0 ]]; then
134 echo Looking around for any Linux dump...
135 # Depending on distro/configuration, the core files may either be named "core"
136 # or "core.<PID>" by default. We read /proc/sys/kernel/core_uses_pid to
137 # determine which it is.
139 if [ -e /proc/sys/kernel/core_uses_pid ] && [ "1" == $(cat /proc/sys/kernel/core_uses_pid) ]; then
143 if [ $core_name_uses_pid == "1" ]; then
144 # We don't know what the PID of the process was, so let's look at all core
145 # files whose name matches core.NUMBER
146 echo Looking for files matching core.* ...
148 [[ $f =~ core.[0-9]+ ]] && print_info_from_core_file "$f" "dotnet" && copy_core_file_to_temp_location "$f" && rm "$f"
150 elif [ -f core ]; then
151 echo found a dump named core in $EXECUTION_DIR !
152 print_info_from_core_file "core" "dotnet"
153 copy_core_file_to_temp_location "core"
156 echo ... found no dump in $PWD
160 # ======================== END Core File Inspection ==========================