From 5eebdd1de2a0b2b66e498014875a1786fb14a39e Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Fri, 2 Oct 2020 16:33:27 +0200 Subject: [PATCH] espcoredump: fix exception when -thread-info fails GDB "-thread-info N" command (for a specific thread N) may fail if GDB can not perform a backtrace. At the same time, "-thread-info" command succeeds in this situation, returning information for all threads. Replace repeated calls to "-thread-info N" with a single call to "-thread-info", also reducing the total execution time. --- components/espcoredump/espcoredump.py | 28 ++++++++++----------------- 1 file changed, 10 insertions(+), 18 deletions(-) diff --git a/components/espcoredump/espcoredump.py b/components/espcoredump/espcoredump.py index 78021e3a50..e3daad179f 100755 --- a/components/espcoredump/espcoredump.py +++ b/components/espcoredump/espcoredump.py @@ -1281,12 +1281,12 @@ def gdbmi_cmd_exec_console(p, gdb_cmd): # type: (GdbController, str) -> str .replace('\\n', '\n').replace('\\t', '\t').rstrip("\n") -def gdbmi_get_thread_ids(p): # type: (GdbController) -> (str, typing.List[str]) - """ Get the current thread ID and the list of all thread IDs known to GDB, as strings """ - result = gdbmi_run_cmd_get_one_response(p, "-thread-list-ids", "done", "result")["payload"] +def gdbmi_get_threads(p): # type: (GdbController) -> (typing.List[dict], str) + """ Get information about all threads known to GDB, and the current thread ID """ + result = gdbmi_run_cmd_get_one_response(p, "-thread-info", "done", "result")["payload"] current_thread_id = result["current-thread-id"] - thread_ids = result["thread-ids"]["thread-id"] - return current_thread_id, thread_ids + threads = result["threads"] + return threads, current_thread_id def gdbmi_switch_thread(p, thr_id): # type: (GdbController, str) -> None @@ -1294,11 +1294,6 @@ def gdbmi_switch_thread(p, thr_id): # type: (GdbController, str) -> None gdbmi_run_cmd_get_one_response(p, "-thread-select %s" % thr_id, "done", "result") -def gdbmi_get_thread_info(p, thr_id=None): # type: (GdbController, typing.Optional[str]) -> dict - """ Get thread info dictionary for the given thread ID """ - return gdbmi_run_cmd_get_one_response(p, "-thread-info" + (" %s" % thr_id) if thr_id else "", "done", "result")["payload"]["threads"][0] - - def gdbmi_data_evaluate_expression(p, expr): # type: (GdbController, str) -> str """ Get the value of an expression, similar to the 'print' command """ return gdbmi_run_cmd_get_one_response(p, "-data-evaluate-expression \"%s\"" % expr, "done", "result")["payload"]["value"] @@ -1435,16 +1430,13 @@ def info_corefile(args): print("\n======================== THREADS INFO =========================") print(gdbmi_cmd_exec_console(p, "info threads")) # THREADS STACKS - cur_thread, threads = gdbmi_get_thread_ids(p) - for thr_id in threads: + threads, _ = gdbmi_get_threads(p) + for thr in threads: + thr_id = int(thr["id"]) + tcb_addr = gdb2freertos_thread_id(thr["target-id"]) task_index = int(thr_id) - 1 - gdbmi_switch_thread(p, thr_id) - thr_info_res = gdbmi_get_thread_info(p, thr_id) - if not thr_info_res["target-id"]: - print("WARNING: Unable to switch to thread %s\n" % thr_id) - continue - tcb_addr = gdb2freertos_thread_id(thr_info_res["target-id"]) task_name = gdbmi_freertos_get_task_name(p, tcb_addr) + gdbmi_switch_thread(p, thr_id) print("\n==================== THREAD %s (TCB: 0x%x, name: '%s') =====================" % (thr_id, tcb_addr, task_name)) print(gdbmi_cmd_exec_console(p, "bt")) if task_info and task_info[task_index].task_flags != EspCoreDumpTaskStatus.TASK_STATUS_CORRECT: