| ############################################################################ |
| # tools/esp32/backtrace.gdbscript |
| # |
| # SPDX-License-Identifier: Apache-2.0 |
| # |
| # Licensed to the Apache Software Foundation (ASF) under one or more |
| # contributor license agreements. See the NOTICE file distributed with |
| # this work for additional information regarding copyright ownership. The |
| # ASF licenses this file to you under the Apache License, Version 2.0 (the |
| # "License"); you may not use this file except in compliance with the |
| # License. You may obtain a copy of the License at |
| # |
| # http://www.apache.org/licenses/LICENSE-2.0 |
| # |
| # Unless required by applicable law or agreed to in writing, software |
| # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT |
| # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the |
| # License for the specific language governing permissions and limitations |
| # under the License. |
| # |
| ############################################################################ |
| |
| # Usage: |
| # |
| # (gdb) esp32_bt <pc> <return address (a0)> <sp (a1)> |
| # |
| # Example 1: |
| # |
| # ------- |
| # xtensa_btdump: Backtrace0: 400d82a3:3ffdec60 |
| # xtensa_btdump: Backtrace1: 400d82ff:3ffdec80 |
| # ------- |
| # (gdb) esp32_bt 0x400d82ff 0x400d82a3 0x3ffdec60 |
| # ------- |
| # |
| # Example 2: |
| # |
| # ------- |
| # xtensa_registerdump: PC: 400d5775 PS: 00060e33 |
| # xtensa_registerdump: A0: 800d504c A1: 3ffd8080 A2: 3ffdfb28 A3: 00000001 |
| # ------- |
| # (gdb) esp32_bt 0x400d5775 0x800d504c 0x3ffd8080 |
| # ------- |
| # |
| # Caveats: |
| # |
| # This doesn't work if the specified register values are already |
| # inconsistent with the frames on the stack. It's usually the case |
| # when xtensa_registerdump saved the state by itself using |
| # xtensa_context_save. |
| # |
| # References: |
| # |
| # Xtensa(R) Instruction Set Architecture (ISA) Reference Manual |
| # 4.7.1.4 Call, Entry, and Return Mechanism |
| # 4.7.1.5 Windowed Procedure-Call Protocol |
| |
| define esp32_bt |
| set $x_pc = $arg0 |
| set $x_a0 = $arg1 |
| set $x_a1 = $arg2 |
| set $pc_topbits = (int)$x_pc & 0xc0000000 |
| # The return address from xtensa_sig_deliver to _xtensa_sig_trampoline |
| set $sig_tramp_ra = (int)(_xtensa_sig_trampoline + 2 * 3) |
| print/a $x_pc |
| while (1) |
| # Note: "- 3" to workaround the case where "call" is |
| # the last instruction in the calling function. |
| set $next_pc = (($x_a0 & 0x3fffffff) | $pc_topbits) - 3 |
| print/a $next_pc |
| if ($x_a0 == $sig_tramp_ra) |
| # A special logic for xtensa_sig_deliver |
| |
| print "--- SIGNAL ---" |
| |
| # XXX SMP |
| set $tcb = (struct tcb_s *)g_readytorun.head |
| set $next_pc = $tcb.xcp.saved_pc |
| print/a $next_pc |
| |
| # XXX local var offset assumption |
| set $regs = (int *)$x_a1 |
| |
| # Note: REG_A0 == 2 |
| # Note: REG_A1 == 3 |
| set $next_a0 = $regs[2] |
| set $next_a1 = $regs[3] |
| else |
| set $next_bsa = (int *)($x_a1 - 16) |
| set $next_a0 = $next_bsa[0] |
| set $next_a1 = $next_bsa[1] |
| end |
| if ($next_a0 == 0) |
| # Xtensa(R) Instruction Set Architecture (ISA) Reference Manual |
| # 8.1.9 Stack Initialization |
| # "The return address register (a0) for the first procedure |
| # on the stack must be explicitly set to zero." |
| loop_break |
| end |
| if ($next_a1 <= $x_a1) |
| print "stack went backward. corrupted?" |
| loop_break |
| end |
| set $x_a0 = $next_a0 |
| set $x_a1 = $next_a1 |
| end |
| end |
| |
| # Usage: |
| # |
| # (gdb) esp32_bt_pid <pid> |
| |
| define esp32_bt_pid |
| set $_pid = $arg0 |
| set $_tcb = g_pidhash[$_pid] |
| if ($_tcb->pid == $_pid) |
| set $_regs = $_tcb->xcp.regs |
| printf "PID %d NAME %s\n", $_pid, $_tcb.name |
| esp32_bt $_regs[0] $_regs[2] $_regs[3] |
| end |
| end |
| |
| # Usage: |
| # |
| # (gdb) esp32_bt_all |
| |
| define esp32_bt_all |
| set $_max_pid = g_npidhash |
| set $_i = 0 |
| while ($_i < $_max_pid) |
| esp32_bt_pid $_i |
| set $_i = $_i + 1 |
| end |
| end |