Forráskód Böngészése

Merge branch 'feature/monitor_coredump_decode' into 'master'

tools/idf_monitor: automatically decode UART core dumps

See merge request espressif/esp-idf!7520
Ivan Grokhotkov 6 éve
szülő
commit
d4ec1842f0

+ 14 - 4
components/espcoredump/Kconfig

@@ -28,10 +28,8 @@ menu "Core dump"
             Select the data format for core dump.
         config ESP32_COREDUMP_DATA_FORMAT_BIN
             bool "Binary format"
-            select ESP32_ENABLE_COREDUMP
         config ESP32_COREDUMP_DATA_FORMAT_ELF
             bool "ELF format"
-            select ESP32_ENABLE_COREDUMP
     endchoice
 
     choice ESP32_COREDUMP_CHECKSUM
@@ -42,10 +40,8 @@ menu "Core dump"
             Select the integrity check for the core dump.
         config ESP32_COREDUMP_CHECKSUM_CRC32
             bool "Use CRC32 for integrity verification"
-            select ESP32_ENABLE_COREDUMP
         config ESP32_COREDUMP_CHECKSUM_SHA256
             bool "Use SHA256 for integrity verification"
-            select ESP32_ENABLE_COREDUMP
             depends on ESP32_COREDUMP_DATA_FORMAT_ELF
     endchoice
 
@@ -80,5 +76,19 @@ menu "Core dump"
             To ensure that core dump itself will not overflow task/ISR stack set this to the value above 800.
             NOTE: It eats DRAM.
 
+    choice ESP32_CORE_DUMP_DECODE
+        prompt "Handling of UART core dumps in IDF Monitor"
+        depends on ESP32_ENABLE_COREDUMP_TO_UART
+        config ESP32_CORE_DUMP_DECODE_INFO
+            bool "Decode and show summary (info_corefile)"
+        config ESP32_CORE_DUMP_DECODE_DISABLE
+            bool "Don't decode"
+    endchoice
+
+    config ESP32_CORE_DUMP_DECODE
+        string
+        default "disable" if ESP32_CORE_DUMP_DECODE_DISABLE
+        default "info" if ESP32_CORE_DUMP_DECODE_INFO
+
 endmenu
 

+ 6 - 1
components/esptool_py/Makefile.projbuild

@@ -134,7 +134,12 @@ simple_monitor: $(call prereq_if_explicit,%flash) | check_python_dependencies
 
 PRINT_FILTER ?=
 
-MONITOR_OPTS := --baud $(MONITORBAUD) --port $(ESPPORT) --toolchain-prefix $(CONFIG_SDK_TOOLPREFIX) --make "$(MAKE)" --print_filter "$(PRINT_FILTER)"
+MONITOR_CORE_DUMP_DECODE ?=
+ifdef CONFIG_ESP32_CORE_DUMP_DECODE
+MONITOR_CORE_DUMP_DECODE = --decode-coredumps $(CONFIG_ESP32_CORE_DUMP_DECODE)
+endif
+
+MONITOR_OPTS := --baud $(MONITORBAUD) --port $(ESPPORT) --toolchain-prefix $(CONFIG_SDK_TOOLPREFIX) --make "$(MAKE)" --print_filter "$(PRINT_FILTER)" $(MONITOR_CORE_DUMP_DECODE)
 
 monitor: $(call prereq_if_explicit,%flash) | check_python_dependencies
 	$(summary) MONITOR

+ 116 - 8
tools/idf_monitor.py

@@ -6,6 +6,8 @@
 # - Run flash build target to rebuild and flash entire project (Ctrl-T Ctrl-F)
 # - Run app-flash build target to rebuild and flash app only (Ctrl-T Ctrl-A)
 # - If gdbstub output is detected, gdb is automatically loaded
+# - If core dump output is detected, it is converted to a human-readable report
+#   by espcoredump.py.
 #
 # Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
 #
@@ -54,6 +56,7 @@ import types
 from distutils.version import StrictVersion
 from io import open
 import textwrap
+import tempfile
 
 key_description = miniterm.key_description
 
@@ -85,17 +88,17 @@ ANSI_YELLOW = '\033[0;33m'
 ANSI_NORMAL = '\033[0m'
 
 
-def color_print(message, color):
+def color_print(message, color, newline='\n'):
     """ Print a message to stderr with colored highlighting """
-    sys.stderr.write("%s%s%s\n" % (color, message,  ANSI_NORMAL))
+    sys.stderr.write("%s%s%s%s" % (color, message,  ANSI_NORMAL, newline))
 
 
-def yellow_print(message):
-    color_print(message, ANSI_YELLOW)
+def yellow_print(message, newline='\n'):
+    color_print(message, ANSI_YELLOW, newline)
 
 
-def red_print(message):
-    color_print(message, ANSI_RED)
+def red_print(message, newline='\n'):
+    color_print(message, ANSI_RED, newline)
 
 
 __version__ = "1.1"
@@ -113,6 +116,20 @@ DEFAULT_TOOLCHAIN_PREFIX = "xtensa-esp32-elf-"
 
 DEFAULT_PRINT_FILTER = ""
 
+# coredump related messages
+COREDUMP_UART_START = b"================= CORE DUMP START ================="
+COREDUMP_UART_END = b"================= CORE DUMP END ================="
+COREDUMP_UART_PROMPT = b"Press Enter to print core dump to UART..."
+
+# coredump states
+COREDUMP_IDLE = 0
+COREDUMP_READING = 1
+COREDUMP_DONE = 2
+
+# coredump decoding options
+COREDUMP_DECODE_DISABLE = "disable"
+COREDUMP_DECODE_INFO = "info"
+
 
 class StoppableThread(object):
     """
@@ -442,7 +459,8 @@ class Monitor(object):
 
     Main difference is that all event processing happens in the main thread, not the worker threads.
     """
-    def __init__(self, serial_instance, elf_file, print_filter, make="make", toolchain_prefix=DEFAULT_TOOLCHAIN_PREFIX, eol="CRLF"):
+    def __init__(self, serial_instance, elf_file, print_filter, make="make", toolchain_prefix=DEFAULT_TOOLCHAIN_PREFIX, eol="CRLF",
+                 decode_coredumps=COREDUMP_DECODE_INFO):
         super(Monitor, self).__init__()
         self.event_queue = queue.Queue()
         self.cmd_queue = queue.Queue()
@@ -484,6 +502,9 @@ class Monitor(object):
         self._output_enabled = True
         self._serial_check_exit = socket_mode
         self._log_file = None
+        self._decode_coredumps = decode_coredumps
+        self._reading_coredump = COREDUMP_IDLE
+        self._coredump_buffer = b""
 
     def invoke_processing_last_line(self):
         self.event_queue.put((TAG_SERIAL_FLUSH, b''), False)
@@ -553,9 +574,11 @@ class Monitor(object):
             if line != b"":
                 if self._serial_check_exit and line == self.console_parser.exit_key.encode('latin-1'):
                     raise SerialStopException()
+                self.check_coredump_trigger_before_print(line)
                 if self._force_line_print or self._line_matcher.match(line.decode(errors="ignore")):
                     self._print(line + b'\n')
                     self.handle_possible_pc_address_in_line(line)
+                self.check_coredump_trigger_after_print(line)
                 self.check_gdbstub_trigger(line)
                 self._force_line_print = False
         # Now we have the last part (incomplete line) in _last_line_part. By
@@ -659,6 +682,83 @@ class Monitor(object):
             else:
                 red_print("Malformed gdb message... calculated checksum %02x received %02x" % (chsum, calc_chsum))
 
+    def check_coredump_trigger_before_print(self, line):
+        if self._decode_coredumps == COREDUMP_DECODE_DISABLE:
+            return
+
+        if COREDUMP_UART_PROMPT in line:
+            yellow_print("Initiating core dump!")
+            self.event_queue.put((TAG_KEY, '\n'))
+            return
+
+        if COREDUMP_UART_START in line:
+            yellow_print("Core dump started (further output muted)")
+            self._reading_coredump = COREDUMP_READING
+            self._coredump_buffer = b""
+            self._output_enabled = False
+            return
+
+        if COREDUMP_UART_END in line:
+            self._reading_coredump = COREDUMP_DONE
+            yellow_print("\nCore dump finished!")
+            self.process_coredump()
+            return
+
+        if self._reading_coredump == COREDUMP_READING:
+            kb = 1024
+            buffer_len_kb = len(self._coredump_buffer) // kb
+            self._coredump_buffer += line.replace(b'\r', b'') + b'\n'
+            new_buffer_len_kb = len(self._coredump_buffer) // kb
+            if new_buffer_len_kb > buffer_len_kb:
+                yellow_print("Received %3d kB..." % (new_buffer_len_kb), newline='\r')
+
+    def check_coredump_trigger_after_print(self, line):
+        if self._decode_coredumps == COREDUMP_DECODE_DISABLE:
+            return
+
+        # Re-enable output after the last line of core dump has been consumed
+        if not self._output_enabled and self._reading_coredump == COREDUMP_DONE:
+            self._reading_coredump = COREDUMP_IDLE
+            self._output_enabled = True
+            self._coredump_buffer = b""
+
+    def process_coredump(self):
+        if self._decode_coredumps != COREDUMP_DECODE_INFO:
+            raise NotImplementedError("process_coredump: %s not implemented" % self._decode_coredumps)
+
+        coredump_script = os.path.join(os.path.dirname(__file__), "..", "components", "espcoredump", "espcoredump.py")
+        coredump_file = None
+        try:
+            # On Windows, the temporary file can't be read unless it is closed.
+            # Set delete=False and delete the file manually later.
+            with tempfile.NamedTemporaryFile(mode="wb", delete=False) as coredump_file:
+                coredump_file.write(self._coredump_buffer)
+                coredump_file.flush()
+
+            cmd = [sys.executable,
+                   coredump_script,
+                   "info_corefile",
+                   "--core", coredump_file.name,
+                   "--core-format", "b64",
+                   self.elf_file
+                   ]
+            output = subprocess.check_output(cmd, stderr=subprocess.STDOUT)
+            self._output_enabled = True
+            self._print(output)
+            self._output_enabled = False  # Will be reenabled in check_coredump_trigger_after_print
+        except subprocess.CalledProcessError as e:
+            yellow_print("Failed to run espcoredump script: {}\n\n".format(e))
+            self._output_enabled = True
+            self._print(COREDUMP_UART_START + b'\n')
+            self._print(self._coredump_buffer)
+            # end line will be printed in handle_serial_input
+        finally:
+            if coredump_file is not None:
+                try:
+                    os.unlink(coredump_file.name)
+                except OSError as e:
+                    yellow_print("Couldn't remote temporary core dump file ({})".format(e))
+
     def run_gdb(self):
         with self:  # disable console control
             sys.stderr.write(ANSI_NORMAL)
@@ -822,6 +922,13 @@ def main():
         help="Filtering string",
         default=DEFAULT_PRINT_FILTER)
 
+    parser.add_argument(
+        '--decode-coredumps',
+        choices=[COREDUMP_DECODE_INFO, COREDUMP_DECODE_DISABLE],
+        default=COREDUMP_DECODE_INFO,
+        help="Handling of core dumps found in serial output"
+    )
+
     args = parser.parse_args()
 
     if args.port.startswith("/dev/tty."):
@@ -847,7 +954,8 @@ def main():
     except KeyError:
         pass  # not running a make jobserver
 
-    monitor = Monitor(serial_instance, args.elf_file.name, args.print_filter, args.make, args.toolchain_prefix, args.eol)
+    monitor = Monitor(serial_instance, args.elf_file.name, args.print_filter, args.make, args.toolchain_prefix, args.eol,
+                      args.decode_coredumps)
 
     yellow_print('--- idf_monitor on {p.name} {p.baudrate} ---'.format(
         p=serial_instance))

+ 5 - 1
tools/idf_py_actions/serial_ext.py

@@ -6,7 +6,7 @@ import click
 
 from idf_py_actions.errors import FatalError
 from idf_py_actions.global_options import global_options
-from idf_py_actions.tools import ensure_build_directory, run_tool, run_target
+from idf_py_actions.tools import ensure_build_directory, run_tool, run_target, get_sdkconfig_value
 
 PYTHON = sys.executable
 
@@ -95,6 +95,10 @@ def action_extensions(base_actions, project_path):
         monitor_args += ["-b", monitor_baud]
         monitor_args += ["--toolchain-prefix", project_desc["monitor_toolprefix"]]
 
+        coredump_decode = get_sdkconfig_value(project_desc["config_file"], "CONFIG_ESP32_CORE_DUMP_DECODE")
+        if coredump_decode is not None:
+            monitor_args += ["--decode-coredumps", coredump_decode]
+
         if print_filter is not None:
             monitor_args += ["--print_filter", print_filter]
         monitor_args += [elf_file]

+ 1 - 0
tools/test_idf_monitor/run_test_idf_monitor.py

@@ -38,6 +38,7 @@ test_list = (
     ('in1.txt',             '*:N',                                                      'in1f3.txt',                60),
     ('in2.txt',             'boot mdf_device_handle:I mesh:E vfs:I',                    'in2f1.txt',               420),
     ('in2.txt',             'vfs',                                                      'in2f2.txt',               420),
+    ('core1.txt',           '',                                                         'core1_out.txt',            60),
 )
 
 IN_DIR = 'tests/'       # tests are in this directory

+ 344 - 0
tools/test_idf_monitor/tests/core1.txt

@@ -0,0 +1,344 @@
+
+I (195) boot: Loaded app from partition at offset 0x10000
+I (195) boot: Disabling RNG early entropy source...
+I (196) cpu_start: Pro cpu up.
+I (200) cpu_start: Application information:
+I (205) cpu_start: Project name:     hello-world
+I (210) cpu_start: App version:      v4.2-dev-172-gc9cc694dbb-dirty
+I (217) cpu_start: Compile time:     Feb  6 2020 17:57:45
+I (223) cpu_start: ELF file SHA256:  83cfeb53c9c00c61...
+I (229) cpu_start: ESP-IDF:          v4.2-dev-172-gc9cc694dbb-dirty
+I (236) cpu_start: Starting app cpu, entry point is 0x40081010
+I (0) cpu_start: App cpu up.
+I (246) heap_init: Initializing. RAM available for dynamic allocation:
+I (253) heap_init: At 3FFAE6E0 len 00001920 (6 KiB): DRAM
+I (259) heap_init: At 3FFB3F58 len 0002C0A8 (176 KiB): DRAM
+I (265) heap_init: At 3FFE0440 len 00003AE0 (14 KiB): D/IRAM
+I (272) heap_init: At 3FFE4350 len 0001BCB0 (111 KiB): D/IRAM
+I (278) heap_init: At 40089AC8 len 00016538 (89 KiB): IRAM
+I (284) cpu_start: Pro cpu start user code
+I (303) spi_flash: detected chip: generic
+I (303) spi_flash: flash io: dio
+W (303) spi_flash: Detected size(4096k) larger than the size in the binary image header(2048k). Using the size in the binary image header.
+I (314) esp_core_dump_uart: Init core dump to UART
+I (319) cpu_start: Starting scheduler on PRO CPU.
+I (0) cpu_start: Starting scheduler on APP CPU.
+Guru Meditation Error: Core  0 panic'ed (StoreProhibited). Exception was unhandled.
+Core 0 register dump:
+PC      : 0x400e37f7  PS      : 0x00060430  A0      : 0x800d0c31  A1      : 0x3ffb5db0  
+A2      : 0x00000001  A3      : 0x00000001  A4      : 0x00000001  A5      : 0x00060023  
+A6      : 0x00000001  A7      : 0x00060023  A8      : 0x00000001  A9      : 0x00000000  
+A10     : 0x7fffffff  A11     : 0x8001f880  A12     : 0x06ff1ff8  A13     : 0x00000000  
+A14     : 0x3ffb7d80  A15     : 0x00000000  SAR     : 0x00000014  EXCCAUSE: 0x0000001d  
+EXCVADDR: 0x00000001  LBEG    : 0x00000000  LEND    : 0x00000000  LCOUNT  : 0x00000000  
+
+ELF file SHA256: 83cfeb53c9c00c61c4e52674e43654e4b452b7592075920977e491e06a4488d8
+
+Backtrace: 0x400e37f4:0x3ffb5db0 0x400d0c2e:0x3ffb5dd0 0x40087015:0x3ffb5df0
+
+I (401) esp_core_dump_uart: Press Enter to print core dump to UART...
+Core Dump detected!
+I (434) esp_core_dump_uart: Print core dump to uart...
+I (434) esp_core_dump_elf: Found tasks: 8
+================= CORE DUMP START =================
+9C0AAAABAAAIAAAAXAEAAAAAAAA=
+f0VMRgEBAQAAAAAAAAAAAAQAXgABAAAAAAAAADQAAAAAAAAAAAAAADQAIAASACgA
+AAAAAA==
+BAAAAHQCAAAAAAAAAAAAAAATAAAAEwAABgAAAAAAAAA=
+AQAAAHQVAACAXvs/gF77P1wBAABcAQAABgAAAAAAAAA=
+AQAAANAWAADwXPs/8Fz7P4gBAACIAQAABgAAAAAAAAA=
+AQAAAFgYAABIbfs/SG37P1wBAABcAQAABgAAAAAAAAA=
+AQAAALQZAAAgbPs/IGz7PyABAAAgAQAABgAAAAAAAAA=
+AQAAANQaAADkZfs/5GX7P1wBAABcAQAABgAAAAAAAAA=
+AQAAADAcAACwZPs/sGT7PywBAAAsAQAABgAAAAAAAAA=
+AQAAAFwdAACgd/s/oHf7P1wBAABcAQAABgAAAAAAAAA=
+AQAAALgeAADQdfs/0HX7P8gBAADIAQAABgAAAAAAAAA=
+AQAAAIAgAADwS/s/8Ev7P1wBAABcAQAABgAAAAAAAAA=
+AQAAANwhAABASvs/QEr7P6gBAACoAQAABgAAAAAAAAA=
+AQAAAIQjAAC0+vo/tPr6P1wBAABcAQAABgAAAAAAAAA=
+AQAAAOAkAADg+Po/4Pj6P8wBAADMAQAABgAAAAAAAAA=
+AQAAAKwmAAB8R/s/fEf7P1wBAABcAQAABgAAAAAAAAA=
+AQAAAAgoAADQRfs/0EX7P6QBAACkAQAABgAAAAAAAAA=
+AQAAAKwpAACQ/fo/kP36P1wBAABcAQAABgAAAAAAAAA=
+AQAAAAgrAACwQfs/sEH7P8ABAADAAQAABgAAAAAAAAA=
+BAAAAMgsAAAAAAAAAAAAABQBAAAUAQAABgAAAAAAAAA=
+CAAAAEwCAAABAAAA
+Q09SRQAAAAA=
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgF77PwAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA9zcOQCAEBgAAAAAAAAAAAAAAAAAUAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADEMDYCwXfs/
+AQAAAAEAAAABAAAAIwAGAAEAAAAjAAYAAQAAAAAAAAD///9/gPgBgPgf/wYAAAAA
+gH37PwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAA
+CAAAAEwCAAABAAAA
+Q09SRQAAAAA=
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAASG37PwAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEHAIQCAABQAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADgbPs/
+AAAAAAAAAAAAAAAAAAAAAMCCCEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAA
+CAAAAEwCAAABAAAA
+Q09SRQAAAAA=
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA5GX7PwAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEHAIQCAABQAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABwZfs/
+AAAAAAAAAAAAAAAAAAAAAMCCCEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAA
+CAAAAEwCAAABAAAA
+Q09SRQAAAAA=
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAoHf7PwAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAxBIIQCAABgAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAaYCICQdvs/
+AAAAAAAAAADwbvs/AAAAAAEAAAAjDgYAxBIIgHB2+z/cAPA/AQAAAAgA+z9gS/s/
+/AwNQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAA
+CAAAAEwCAAABAAAA
+Q09SRQAAAAA=
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA8Ev7PwAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAxBIIQCAABgAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADuRCIAAS/s/
+AAAAAAEAAACE/fo/AAAAAAEAAAACAAAAxBIIgOBK+z/cAPA/AQAAAAgA+z8jAAYA
+AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAA
+CAAAAEwCAAABAAAA
+Q09SRQAAAAA=
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAtPr6PwAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAxBIIQCAABgAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABB+CICg+fo/
+AAAAAAAAAAAQNfs/vDf7PwIAAADQN/s/xBIIgID5+j/cAPA/AQAAAAgA+z8jAAYA
+AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAA
+CAAAAEwCAAABAAAA
+Q09SRQAAAAA=
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAfEf7PwAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEH4IQCACBgAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACsaCICQRvs/
+mP/6PwAAAADg//o/AAAAAAEAAAABAAAAEH4IgHBG+z8BAAAABAAAABQ1+z8KAAAA
+AACAABwA9D8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAA
+CAAAAEwCAAABAAAA
+Q09SRQAAAAA=
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAkP36PwAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAxBIIQCAOBgAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABB+CIBwQvs/
+AAAAAAAAAAAQNfs/oDr+PwMAAAAjBQYAxBIIgFBC+z/cAPA/AQAAAAgA+z8jAAYA
+AQAAACMFBgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAA
+UF37PxBe+z+Ly+SRODP7Pzgz+z+AXvs/MDP7PxgAAACXBQ54SQvlZoBe+z8AAAAA
+AQAAAHxO+z9tYWluANFl1b9gbhUZORAAAAAAAHhe+z8BAAAAAAAAAAAAAAAAAAAA
+AAAAALjo+j8g6fo/iOn6PwAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAEgdAEAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAk5ND
+776t3vc3DkAwBAYAMQwNgLBd+z8BAAAAAQAAAAEAAAAjAAYAAQAAACMABgABAAAA
+AAAAAP///3+A+AGA+B//BgAAAACAffs/AAAAABQAAAAdAAAAAQAAAAAAAAAAAAAA
+AAAAAPgf/wYAAAAAPB4IQAgL+z8AAAAAAAAAAAAAAAD//z+zAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAABhwCIDQXfs/AAAAAAAAAAAYcAiA0F37PwAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAADwXfs/zAsNQAAAAAAjAAYAODP7P4Be+z8AAAAA
+AAAAABBe+z8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAcXvs/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAA=
+IGz7P+Bs+z8qbFI9JDP7P+xl+z9Ibfs/HDP7PxkAAACM49VXeSoll0ht+z8AAAAA
+AAAAAERn+z9JRExFMQCFkbfvDgtV1KkAAQAAAEBt+z8AAAAAAAAAAAAAAAAAAAAA
+AAAAALjo+j8g6fo/iOn6PwAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAEgdAEAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAvl21
+oB4IQBBwCEAwAAUAAAAAAOBs+z8AAAAAAAAAAAAAAAAAAAAAwIIIQAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAADAbPs/wIIIQAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAOBs+z8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAADsbPs/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+sGT7P3Bl+z/HSTugUG37PyQz+z/kZfs/HDP7PxkAAAA1aB3HlRMz9ORl+z8AAAAA
+AAAAAOBf+z9JRExFMAB5I/hhScYuItcAAAAAANxl+z8AAAAAAAAAAAAAAAAAAAAA
+AAAAALjo+j8g6fo/iOn6PwAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAEgdAEAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAADuXO
+oB4IQBBwCEAwAAUAAAAAAHBl+z8AAAAAAAAAAAAAAAAAAAAAwIIIQAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAGgS+z8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAB8Zfs/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAA
+0HX7PzB3+z8AAAAAEDP7PxAz+z+gd/s/CDP7PxgAAADUbvs/1G77P6B3+z/Mbvs/
+AQAAAJxv+z9UbXIgU3ZjAA1db2P9pUIAAAAAAJh3+z8BAAAAAAAAAAAAAAAAAAAA
+AAAAALjo+j8g6fo/iOn6PwAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAEgdAEAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAFysf
+oB4IQMQSCEAwAAYABpgIgJB2+z8AAAAAAAAAAPBu+z8AAAAAAQAAACMOBgDEEgiA
+cHb7P9wA8D8BAAAACAD7P2BL+z/8DA1AAAAAAAAAAAD//wAAAAAAAAAAAAAAAAAA
+AAAAAKQgCEBgS/s/mHIIQCgk+z8AAAAAAAAAAAAAAAD//z+zAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAKAeCEAQcAhAMAAFAAAAAADzmAiAsHb7Pxw1+z8AAAAA
+AAAAAOSYCEAAAAAAAAAAABhwCIDgdvs/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAACMABgABAAAAIwAGAAAAAAAQd/s/5JgIQAAAAAABAAAAAAAAAAAAAAAAAAAA
+IwAGADgz+z+AXvs/AAAAAAAAAAAwd/s/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPHf7PwAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+QEr7P4BL+z9GPj4tuDL7P7gy+z/wS/s/sDL7PxQAAABM4/eNY9P4VPBL+z8AAAAA
+BQAAAOxI+z9kcG9ydADgytnG+juR2iwAAAAAAOhL+z8FAAAAAAAAAAAAAAAAAAAA
+AAAAALjo+j8g6fo/iOn6PwAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAEgdAEAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAGA9Z
+oB4IQMQSCEAwAAYAO5EIgABL+z8AAAAAAQAAAIT9+j8AAAAAAQAAAAIAAADEEgiA
+4Er7P9wA8D8BAAAACAD7PyMABgABAAAAAAAAAAAAAAD//wAAAAAAAAAAAAAAAAAA
+AAAAAKQgCEAjAAYAmHIIQHj4+j8AAAAAAAAAAAAAAAD//z+zAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAD8DA1AAAAAAAAAAABcDQ2AIEv7P/BL+z8AAAAA
+AAAAAAAAAAAAAAAAAAAAABhwCIBAS/s/AQAAAAAAABDwS/s/IwAGAAEAAAAjAAYA
+AAAAAGBL+z/8DA1AAAAAABoAAACIM/s/8Ev7PwAAAAAAAAAAgEv7PwAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIxL+z8AAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==
+4Pj6P0D6+j/c8+jFhEf7P5j9+j+0+vo/mDL7PwMAAACI6vo/iOr6P7T6+j+A6vo/
+FgAAALDq+j9lc3BfdGltZXIAmI0iFV0AAAAAAKz6+j8WAAAAAAAAAAAAAAAAAAAA
+AAAAALjo+j8g6fo/iOn6PwAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAEgdAEAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAOT5O
+oB4IQMQSCEAwAAYAEH4IgKD5+j8AAAAAAAAAABA1+z+8N/s/AgAAANA3+z/EEgiA
+gPn6P9wA8D8BAAAACAD7PyMABgABAAAAAAAAAAAAAAD//wAAAAAAAAAAAAAAAAAA
+AAAAAKQgCEAjAAYAmHIIQDin+j8AAAAAAAAAAAAAAAD//z+zAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAKAeCEAQcAhAMAAFAAAAAABLHw2AwPn6P1zq+j8AAAAA
+AAAAADgfDUAAAAAAAAAAABhwCIAA+vo/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+/////wAAAAAAAAAAAAAAAKTq+j8AAAAAAQAAACMOBgAAAAAAIPr6PzgfDUAAAAAA
+IwAGANw0+z+0+vo/AAAAAAAAAABA+vo/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAATPr6PwAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==
+0EX7PxBH+z8+sA1HoDL7P7z6+j98R/s/mDL7PwEAAADE//o/xP/6P3xH+z+8//o/
+GAAAAHhD+z9pcGMxAHSb12QdtYvfmTkAAQAAAHRH+z8YAAAAAAAAAAAAAAAAAAAA
+AAAAALjo+j8g6fo/iOn6PwAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAEgdAEAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAjAAz
+oB4IQBB+CEAwAgYAKxoIgJBG+z+Y//o/AAAAAOD/+j8AAAAAAQAAAAEAAAAQfgiA
+cEb7PwEAAAAEAAAAFDX7PwoAAAAAAIAAHAD0PwAAAAD//wAAAAAAAAAAAAAAAAAA
+AAAAAKQgCEAKAAAAmHIIQAj0+j8AAAAAAAAAAAAAAAD//z+zAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAD4GQhAAQAAAAAAAAAYcAiA0Eb7PwEAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAP////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAPBG+z/4GQhAAQAAACAHBgAENfs/fEf7PwAAAAAAAAAAEEf7PwAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAFwQCICAff4/KAAAACgAAAAAAAAAAAAAABxH+z8AAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+sEH7PxBD+z8En2QMvPr6P6Ay+z+Q/fo/mDL7PwEAAABo/fo/aP36P5D9+j9g/fo/
+GAAAAHQ/+z9pcGMwAGHBu8ov8v26vbcAAAAAAHBD+z8YAAAAAAAAAAAAAAAAAAAA
+AAAAALjo+j8g6fo/iOn6PwAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAEgdAEAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAsXYs
+oB4IQMQSCEAwDgYAEH4IgHBC+z8AAAAAAAAAABA1+z+gOv4/AwAAACMFBgDEEgiA
+UEL7P9wA8D8BAAAACAD7PyMABgABAAAAIwUGAAAAAAD//wAAAAAAAAAAAAAAAAAA
+AAAAAKQgCEAjAAYAmHIIQAjw+j8AAAAAAAAAAAAAAAD//z+zAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAKAeCEAQcAhAMAAFAAAAAAArGgiAkEL7Pzz9+j8AAAAA
+AAAAAPgZCEAAAAAAAAAAABhwCIDQQvs/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+/////wAAAAAAAAAAAAAAAIT9+j8AAAAAAQAAAAIAAAAAAAAA8EL7P/gZCEAAAAAA
+IwMGAAQ1+z+Q/fo/AQAAAAAAAAAQQ/s/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+2Q8IgGA7/j+AMvs/BQAAAAAAAAAAAAAAHEP7PwAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAA==
+FAAAAEgAAABKIAAA
+RVNQX0NPUkVfRFVNUF9JTkZPAAA=
+AAEAADgzY2ZlYjUzYzljMDBjNjFjNGU1MjY3NGU0MzY1NGU0YjQ1MmI3NTkyMDc1
+OTIwOTc3ZTQ5MWUwNmE0NDg4ZDgAAAAA
+DAAAAJQAAAClAgAA
+RVhUUkFfSU5GTwAA
+gF77P+gAAAAdAAAA7gAAAAEAAADCAAAAAAAAAMMAAAAAAAAAxAAAAAAAAADFAAAA
+AAAAAMYAAAAAAAAAsQAAAL84DkCyAAAAAAAAALMAAAAAAAAAtAAAAAAAAAC1AAAA
+AAAAALYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAA==
+Fj6ctQ==
+================= CORE DUMP END =================
+I (1859) esp_core_dump_uart: Core dump has been written to uart.
+Rebooting...
+ets Jun  8 2016 00:22:57
+
+rst:0xc (SW_CPU_RESET),boot:0x1e (SPI_FAST_FLASH_BOOT)
+configsip: 0, SPIWP:0xee
+clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
+mode:DIO, clock div:2
+load:0x3fff0030,len:4
+load:0x3fff0034,len:7148
+load:0x40078000,len:14220
+ho 0 tail 12 room 4
+load:0x40080400,len:4584
+0x40080400: _init at ??:?

+ 193 - 0
tools/test_idf_monitor/tests/core1_out.txt

@@ -0,0 +1,193 @@
+I (195) boot: Loaded app from partition at offset 0x10000
+I (195) boot: Disabling RNG early entropy source...
+I (196) cpu_start: Pro cpu up.
+I (200) cpu_start: Application information:
+I (205) cpu_start: Project name:     hello-world
+I (210) cpu_start: App version:      v4.2-dev-172-gc9cc694dbb-dirty
+I (217) cpu_start: Compile time:     Feb  6 2020 17:57:45
+I (223) cpu_start: ELF file SHA256:  83cfeb53c9c00c61...
+I (229) cpu_start: ESP-IDF:          v4.2-dev-172-gc9cc694dbb-dirty
+I (236) cpu_start: Starting app cpu, entry point is 0x40081010
+I (0) cpu_start: App cpu up.
+I (246) heap_init: Initializing. RAM available for dynamic allocation:
+I (253) heap_init: At 3FFAE6E0 len 00001920 (6 KiB): DRAM
+I (259) heap_init: At 3FFB3F58 len 0002C0A8 (176 KiB): DRAM
+I (265) heap_init: At 3FFE0440 len 00003AE0 (14 KiB): D/IRAM
+I (272) heap_init: At 3FFE4350 len 0001BCB0 (111 KiB): D/IRAM
+I (278) heap_init: At 40089AC8 len 00016538 (89 KiB): IRAM
+I (284) cpu_start: Pro cpu start user code
+I (303) spi_flash: detected chip: generic
+I (303) spi_flash: flash io: dio
+W (303) spi_flash: Detected size(4096k) larger than the size in the binary image header(2048k). Using the size in the binary image header.
+I (314) esp_core_dump_uart: Init core dump to UART
+I (319) cpu_start: Starting scheduler on PRO CPU.
+I (0) cpu_start: Starting scheduler on APP CPU.
+Guru Meditation Error: Core  0 panic'ed (StoreProhibited). Exception was unhandled.
+Core 0 register dump:
+PC      : 0x400e37f7  PS      : 0x00060430  A0      : 0x800d0c31  A1      : 0x3ffb5db0  
+A2      : 0x00000001  A3      : 0x00000001  A4      : 0x00000001  A5      : 0x00060023  
+A6      : 0x00000001  A7      : 0x00060023  A8      : 0x00000001  A9      : 0x00000000  
+A10     : 0x7fffffff  A11     : 0x8001f880  A12     : 0x06ff1ff8  A13     : 0x00000000  
+A14     : 0x3ffb7d80  A15     : 0x00000000  SAR     : 0x00000014  EXCCAUSE: 0x0000001d  
+EXCVADDR: 0x00000001  LBEG    : 0x00000000  LEND    : 0x00000000  LCOUNT  : 0x00000000  
+ELF file SHA256: 83cfeb53c9c00c61c4e52674e43654e4b452b7592075920977e491e06a4488d8
+Backtrace: 0x400e37f4:0x3ffb5db0 0x400d0c2e:0x3ffb5dd0 0x40087015:0x3ffb5df0
+I (401) esp_core_dump_uart: Press Enter to print core dump to UART...
+Core Dump detected!
+I (434) esp_core_dump_uart: Print core dump to uart...
+I (434) esp_core_dump_elf: Found tasks: 8
+ERROR: GDB/MI command failed (error / msg="No symbol table is loaded.  Use the \"file\" command.")!
+espcoredump.py v0.4-dev
+===============================================================
+==================== ESP32 CORE DUMP START ====================
+
+Crashed task handle: 0x3ffb5e80, name: '', GDB name: 'process 1073438336'
+
+================== CURRENT THREAD REGISTERS ===================
+exccause       0x1d (StoreProhibitedCause)
+excvaddr       0x1
+epc1           0x0
+epc2           0x0
+epc3           0x0
+epc4           0x0
+epc5           0x0
+epc6           0x0
+epc7           0x0
+eps2           0x0
+eps3           0x0
+eps4           0x0
+eps5           0x0
+eps6           0x0
+eps7           0x400e38bf
+pc             0x400e37f7	0x400e37f7
+lbeg           0x0	0
+lend           0x0	0
+lcount         0x0	0
+sar            0x14	20
+ps             0x60420	394272
+threadptr      <unavailable>
+br             <unavailable>
+scompare1      <unavailable>
+acclo          <unavailable>
+acchi          <unavailable>
+m0             <unavailable>
+m1             <unavailable>
+m2             <unavailable>
+m3             <unavailable>
+expstate       <unavailable>
+f64r_lo        <unavailable>
+f64r_hi        <unavailable>
+f64s           <unavailable>
+fcr            <unavailable>
+fsr            <unavailable>
+a0             0x800d0c31	-2146628559
+a1             0x3ffb5db0	1073438128
+a2             0x1	1
+a3             0x1	1
+a4             0x1	1
+a5             0x60023	393251
+a6             0x1	1
+a7             0x60023	393251
+a8             0x1	1
+a9             0x0	0
+a10            0x7fffffff	2147483647
+a11            0x8001f880	-2147354496
+a12            0x6ff1ff8	117383160
+a13            0x0	0
+a14            0x3ffb7d80	1073446272
+a15            0x0	0
+
+==================== CURRENT THREAD STACK =====================
+#0  0x400e37f7 in ?? ()
+#1  0x400d0c31 in ?? ()
+#2  0x40087018 in ?? ()
+
+======================== THREADS INFO =========================
+  Id   Target Id         Frame 
+* 1    process 1073438336 0x400e37f7 in ?? ()
+  2    process 1073442120 0x40087010 in ?? ()
+  3    process 1073440228 0x40087010 in ?? ()
+  4    process 1073444768 0x400812c4 in ?? ()
+  5    process 1073433584 0x400812c4 in ?? ()
+  6    process 1073412788 0x400812c4 in ?? ()
+  7    process 1073432444 0x40087e10 in ?? ()
+  8    process 1073413520 0x400812c4 in ?? ()
+ERROR: GDB/MI command failed (error / msg="No symbol table is loaded.  Use the \"file\" command.")!
+
+==================== THREAD 2 (TCB: 0x3ffb6d48, name: '') =====================
+#0  0x40087010 in ?? ()
+ERROR: GDB/MI command failed (error / msg="No symbol table is loaded.  Use the \"file\" command.")!
+
+==================== THREAD 3 (TCB: 0x3ffb65e4, name: '') =====================
+#0  0x40087010 in ?? ()
+ERROR: GDB/MI command failed (error / msg="No symbol table is loaded.  Use the \"file\" command.")!
+
+==================== THREAD 4 (TCB: 0x3ffb77a0, name: '') =====================
+#0  0x400812c4 in ?? ()
+#1  0x40089806 in ?? ()
+#2  0x400898f3 in ?? ()
+#3  0x40087018 in ?? ()
+ERROR: GDB/MI command failed (error / msg="No symbol table is loaded.  Use the \"file\" command.")!
+
+==================== THREAD 5 (TCB: 0x3ffb4bf0, name: '') =====================
+#0  0x400812c4 in ?? ()
+#1  0x4008913b in ?? ()
+#2  0x400d0d5c in ?? ()
+#3  0x40087018 in ?? ()
+ERROR: GDB/MI command failed (error / msg="No symbol table is loaded.  Use the \"file\" command.")!
+
+==================== THREAD 6 (TCB: 0x3ffafab4, name: '') =====================
+#0  0x400812c4 in ?? ()
+#1  0x40087e10 in ?? ()
+#2  0x400d1f4b in ?? ()
+#3  0x40087018 in ?? ()
+ERROR: GDB/MI command failed (error / msg="No symbol table is loaded.  Use the \"file\" command.")!
+
+==================== THREAD 7 (TCB: 0x3ffb477c, name: '') =====================
+#0  0x40087e10 in ?? ()
+#1  0x40081a2b in ?? ()
+#2  0x40087018 in ?? ()
+ERROR: GDB/MI command failed (error / msg="No symbol table is loaded.  Use the \"file\" command.")!
+
+==================== THREAD 8 (TCB: 0x3ffafd90, name: '') =====================
+#0  0x400812c4 in ?? ()
+#1  0x40087e10 in ?? ()
+#2  0x40081a2b in ?? ()
+#3  0x40087018 in ?? ()
+
+======================= ALL MEMORY REGIONS ========================
+Name   Address   Size   Attrs
+.data 0x400054 0x4 RW A
+.coredump.tasks.data 0x3ffb5e80 0x15c RW 
+.coredump.tasks.data 0x3ffb5cf0 0x188 RW 
+.coredump.tasks.data 0x3ffb6d48 0x15c RW 
+.coredump.tasks.data 0x3ffb6c20 0x120 RW 
+.coredump.tasks.data 0x3ffb65e4 0x15c RW 
+.coredump.tasks.data 0x3ffb64b0 0x12c RW 
+.coredump.tasks.data 0x3ffb77a0 0x15c RW 
+.coredump.tasks.data 0x3ffb75d0 0x1c8 RW 
+.coredump.tasks.data 0x3ffb4bf0 0x15c RW 
+.coredump.tasks.data 0x3ffb4a40 0x1a8 RW 
+.coredump.tasks.data 0x3ffafab4 0x15c RW 
+.coredump.tasks.data 0x3ffaf8e0 0x1cc RW 
+.coredump.tasks.data 0x3ffb477c 0x15c RW 
+.coredump.tasks.data 0x3ffb45d0 0x1a4 RW 
+.coredump.tasks.data 0x3ffafd90 0x15c RW 
+.coredump.tasks.data 0x3ffb41b0 0x1c0 RW 
+
+===================== ESP32 CORE DUMP END =====================
+===============================================================
+Done!
+I (1859) esp_core_dump_uart: Core dump has been written to uart.
+Rebooting...
+ets Jun  8 2016 00:22:57
+rst:0xc (SW_CPU_RESET),boot:0x1e (SPI_FAST_FLASH_BOOT)
+configsip: 0, SPIWP:0xee
+clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
+mode:DIO, clock div:2
+load:0x3fff0030,len:4
+load:0x3fff0034,len:7148
+load:0x40078000,len:14220
+ho 0 tail 12 room 4
+load:0x40080400,len:4584
+0x40080400: _init at ??:?