This is an automated email from the ASF dual-hosted git repository. jerpelea pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git
The following commit(s) were added to refs/heads/master by this push: new 2c8aa86 tools: Add nuttx-gdbinit for nuttx thread debugging 2c8aa86 is described below commit 2c8aa8629e251593c64739c7dd6a475e57073d36 Author: Masayuki Ishikawa <masayuki.ishik...@gmail.com> AuthorDate: Thu Jul 2 17:46:10 2020 +0900 tools: Add nuttx-gdbinit for nuttx thread debugging Summary: - This commit enables nuttx thread debugging without openocd-nuttx - To use this script, gdb must support python - To show all thread, use 'info_nxthreads' - To switch thread, use 'nxthread pid' - To continue, use 'nxcontinue' Impact: - No impact Testing: - Tested with spresense (Cortex-M4F), sim (x86_64), lm3s6965-ek (Cortex-M3) - Tested with GNU Tools for Arm Embedded Processors 9-2019-q4-major - Tested with GNU gdb (Ubuntu 8.1-0ubuntu3.2) 8.1.0.20180409-git Signed-off-by: Masayuki Ishikawa <masayuki.ishik...@jp.sony.com> --- tools/nuttx-gdbinit | 352 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 352 insertions(+) diff --git a/tools/nuttx-gdbinit b/tools/nuttx-gdbinit new file mode 100644 index 0000000..8927215 --- /dev/null +++ b/tools/nuttx-gdbinit @@ -0,0 +1,352 @@ +############################################################################ +# tools/nuttx-gdbinit +# +# 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. +# +############################################################################ + +# NOTE: you need to use gdb configured '--with-python' +# usage: gdb -ix=./tools/nuttx-gdbinit nuttx +# new commands: info_nxthreads, nxthread pid, nxcontinue, nxthread_all_bt + +set $_current_tcb = 0x0 +set $_target_examined = 0x0 + +define _examine_arch + python _target_frame = gdb.selected_frame() + python _target_arch = _target_frame.architecture() + + python if (_target_arch.name() == 'armv7e-m') : \ + gdb.execute("set $_target_arch = \"armv7e-m\"") + + # TODO: qemu (need to distinguish cortex-m and cortex-a) + python if (_target_arch.name() == 'armv7') : \ + gdb.execute("set $_target_arch = \"armv7e-m\"") + + python if (_target_arch.name() == 'i386:x86-64') : \ + gdb.execute("set $_target_arch = \"i386:x86-64\"") + + # NOTE: we assume that sim has sim_bringup function + python if (type(gdb.lookup_global_symbol("sim_bringup")) is gdb.Symbol) : \ + gdb.execute("set $_target_arch=\"sim:x86-64\"") +end + +define _examine_target + if ($_target_examined == 0x0) + _examine_arch + + python gdb.execute("set $_target_has_fpu = 0") + python if (type(gdb.lookup_global_symbol("fpuconfig")) is gdb.Symbol) : \ + gdb.execute("set $_target_has_fpu = 1") + + python gdb.execute("set $_target_has_smp = 0") + python if (type(gdb.lookup_global_symbol("g_assignedtasks")) is gdb.Symbol) : \ + gdb.execute("set $_target_has_smp = 1") + + set $_target_max_tasks = sizeof(g_pidhash) / sizeof(struct pidhash_s) + + printf "target examined \n" + python print("_target_arch.name=" + _target_arch.name()) + + # NOTE: i386:x86-64 (qemu) does not work + #printf "$_target_arch : %s \n", $_target_arch + + printf "$_target_has_fpu : %d \n", $_target_has_fpu + printf "$_target_has_smp : %d \n", $_target_has_smp + set $_target_examined = 1 + end +end + +define _print_thread + set $tcb = (struct tcb_s *)$arg0 + + if ($tcb == $_current_tcb) + printf "* " + else + printf " " + end + + printf "%d Thread 0x%x (Name: %s, State: %s, Priority: %d) 0x%x in ", \ + $tcb->pid, $tcb, $tcb->name, g_statenames[$tcb->task_state], $tcb->sched_priority, \ + $tcb->xcp.regs[$_pc_reg_idx] + python _symbol = gdb.execute("info symbol $tcb->xcp.regs[$_pc_reg_idx]", to_string=True); \ + print(_symbol.split()[0] + "()") +end + +define _save_tcb + _examine_target + + set $tcb = $arg0 + if ($_streq($_target_arch, "armv7e-m") == 1) + if ($_target_has_fpu == 0) + _save_tcb_armv7e-m $tcb + else + _save_tcb_armv7e-mf $tcb + end + end + if ($_streq($_target_arch, "i386:x86-64") == 1) + _save_tcb_i386x86-64 $tcb + end + if ($_streq($_target_arch, "sim:x86-64") == 1) + _save_tcb_simx86-64 $tcb + end +end + +define _save_current_tcb + _examine_target + + if ($_current_tcb == 0) + if ($_target_has_smp == 0) + set $tcb = (struct tcb_s *)g_readytorun->head + _save_tcb $tcb + else + set $cpu = up_cpu_index() + set $tcb = (struct tcb_s *)g_assignedtasks[$cpu]->head + _save_tcb $tcb + end + printf "saved current_tcb (pid=%d) \n", $tcb->pid + set $_current_tcb = $tcb + end +end + +define _switch_tcb + _examine_target + _save_current_tcb + + # set the current frame to the newest before switching + python if (gdb.selected_frame() != gdb.newest_frame()) : \ + gdb.newest_frame().select() + + set $tcb = $arg0 + if ($_streq($_target_arch, "armv7e-m") == 1) + if ($_target_has_fpu == 0) + _switch_tcb_armv7e-m $tcb + else + _switch_tcb_armv7e-mf $tcb + end + end + if ($_streq($_target_arch, "i386:x86-64") == 1) + _switch_tcb_i386x86-64 $tcb + end + if ($_streq($_target_arch, "sim:x86-64") == 1) + _switch_tcb_simx86-64 $tcb + end + + # update _current_tcb + set $_current_tcb = $tcb +end + +# see nuttx/arch/arm/include/armv7-m/irq_cmnvector.h +define _save_tcb_armv7e-m + set $tcb = (struct tcb_s *)$arg0 + set $tcb.xcp.regs[0] = $sp + # TODO: basepri/primask + set $tcb.xcp.regs[2] = $r4 + set $tcb.xcp.regs[3] = $r5 + set $tcb.xcp.regs[4] = $r6 + set $tcb.xcp.regs[5] = $r7 + set $tcb.xcp.regs[6] = $r8 + set $tcb.xcp.regs[7] = $r9 + set $tcb.xcp.regs[8] = $r10 + set $tcb.xcp.regs[9] = $r11 + # TODO: EXC_RETURN (protected) + set $tcb.xcp.regs[10] = $r0 + set $tcb.xcp.regs[11] = $r1 + set $tcb.xcp.regs[12] = $r2 + set $tcb.xcp.regs[13] = $r3 + set $tcb.xcp.regs[14] = $r12 + set $tcb.xcp.regs[15] = $lr + set $tcb.xcp.regs[16] = $pc + # TODO: xPSR + + set $_pc_reg_idx = 16 +end + +define _switch_tcb_armv7e-m + set $tcb = (struct tcb_s *)$arg0 + set $sp = $tcb.xcp.regs[0] + # TODO: basepri/primask + set $r4 = $tcb.xcp.regs[2] + set $r5 = $tcb.xcp.regs[3] + set $r6 = $tcb.xcp.regs[4] + set $r7 = $tcb.xcp.regs[5] + set $r8 = $tcb.xcp.regs[6] + set $r9 = $tcb.xcp.regs[7] + set $r10 = $tcb.xcp.regs[8] + set $r11 = $tcb.xcp.regs[9] + # TODO: EXC_RETURN (protected) + set $r0 = $tcb.xcp.regs[10] + set $r1 = $tcb.xcp.regs[11] + set $r2 = $tcb.xcp.regs[12] + set $r3 = $tcb.xcp.regs[13] + set $r12 = $tcb.xcp.regs[14] + set $lr = $tcb.xcp.regs[15] + set $pc = $tcb.xcp.regs[16] + # TODO: xPSR +end + +# see nuttx/arch/arm/include/armv7-m/irq_cmnvector.h +define _save_tcb_armv7e-mf + set $tcb = (struct tcb_s *)$arg0 + set $tcb.xcp.regs[0] = $sp + # TODO: basepri/primask + set $tcb.xcp.regs[2] = $r4 + set $tcb.xcp.regs[3] = $r5 + set $tcb.xcp.regs[4] = $r6 + set $tcb.xcp.regs[5] = $r7 + set $tcb.xcp.regs[6] = $r8 + set $tcb.xcp.regs[7] = $r9 + set $tcb.xcp.regs[8] = $r10 + set $tcb.xcp.regs[9] = $r11 + # TODO: EXC_RETURN (protected) + # TODO: FPU + set $tcb.xcp.regs[27] = $r0 + set $tcb.xcp.regs[28] = $r1 + set $tcb.xcp.regs[29] = $r2 + set $tcb.xcp.regs[30] = $r3 + set $tcb.xcp.regs[31] = $r12 + set $tcb.xcp.regs[32] = $lr + set $tcb.xcp.regs[33] = $pc + # TODO: xPSR + + set $_pc_reg_idx = 33 +end + +define _switch_tcb_armv7e-mf + set $tcb = (struct tcb_s *)$arg0 + set $sp = $tcb.xcp.regs[0] + # TODO: basepri/primask + set $r4 = $tcb.xcp.regs[2] + set $r5 = $tcb.xcp.regs[3] + set $r6 = $tcb.xcp.regs[4] + set $r7 = $tcb.xcp.regs[5] + set $r8 = $tcb.xcp.regs[6] + set $r9 = $tcb.xcp.regs[7] + set $r10 = $tcb.xcp.regs[8] + set $r11 = $tcb.xcp.regs[9] + # TODO: EXC_RETURN (protected) + # TODO: FPU + set $r0 = $tcb.xcp.regs[27] + set $r1 = $tcb.xcp.regs[28] + set $r2 = $tcb.xcp.regs[29] + set $r3 = $tcb.xcp.regs[30] + set $r12 = $tcb.xcp.regs[31] + set $lr = $tcb.xcp.regs[32] + set $pc = $tcb.xcp.regs[33] + # TODO: xPSR +end + +# see nuttx/arch/x86_64/include/intel64/irq.h +define _save_tcb_i386x86-64 + set $tcb = (struct tcb_s *)$arg0 + set $tcb.xcp.regs[6 + 64] = $rbx + set $tcb.xcp.regs[7 + 64] = $rbp + set $tcb.xcp.regs[10 + 64] = $r12 + set $tcb.xcp.regs[11 + 64] = $r13 + set $tcb.xcp.regs[12 + 64] = $r14 + set $tcb.xcp.regs[13 + 64] = $r15 + set $tcb.xcp.regs[21 + 64] = $rip + set $tcb.xcp.regs[24 + 64] = $rsp + + set $_pc_reg_idx = (21 + 64) +end + +define _switch_tcb_i386x86-64 + set $tcb = (struct tcb_s *)$arg0 + set $rbx = $tcb.xcp.regs[6 + 64] + set $rbp = $tcb.xcp.regs[7 + 64] + set $r12 = $tcb.xcp.regs[10 + 64] + set $r13 = $tcb.xcp.regs[11 + 64] + set $r14 = $tcb.xcp.regs[12 + 64] + set $r15 = $tcb.xcp.regs[13 + 64] + set $rip = $tcb.xcp.regs[21 + 64] + set $rsp = $tcb.xcp.regs[24 + 64] +end + +# see nuttx/arch/sim/src/sim/up_internal.h +define _save_tcb_simx86-64 + set $tcb = (struct tcb_s *)$arg0 + set $tcb.xcp.regs[0] = $rbx + set $tcb.xcp.regs[1] = $rsp + set $tcb.xcp.regs[2] = $rbp + set $tcb.xcp.regs[3] = $r12 + set $tcb.xcp.regs[4] = $r13 + set $tcb.xcp.regs[5] = $r14 + set $tcb.xcp.regs[6] = $r15 + set $tcb.xcp.regs[7] = $rip + + set $_pc_reg_idx = 7 +end + +define _switch_tcb_simx86-64 + set $tcb = (struct tcb_s *)$arg0 + set $rbx = $tcb.xcp.regs[0] + set $rsp = $tcb.xcp.regs[1] + set $rbp = $tcb.xcp.regs[2] + set $r12 = $tcb.xcp.regs[3] + set $r13 = $tcb.xcp.regs[4] + set $r14 = $tcb.xcp.regs[5] + set $r15 = $tcb.xcp.regs[6] + set $rip = $tcb.xcp.regs[7] +end + +define nxthread + _examine_target + _save_current_tcb + set $hash = ($arg0 & ($_target_max_tasks - 1)) + set $tcb = g_pidhash[$hash].tcb + if ($tcb != 0x0) + _print_thread $tcb + if ($argc == 1) + _switch_tcb $tcb + end + if ($argc == 2) + if ($arg1 == 1) + _switch_tcb $tcb + where + end + end + end +end + +define nxthread_all_bt + _save_current_tcb + set $i = 0 + while ($i < $_target_max_tasks) + # 1: backtrace + nxthread $i 1 + set $i = $i + 1 + end +end + +define info_nxthreads + _save_current_tcb + set $i = 0 + while ($i < $_target_max_tasks) + # dummy : 0 0 + nxthread $i 0 0 + set $i = $i + 1 + end +end + +define nxcontinue + printf "nxcontinue \n" + # TODO: SMP + set $tcb = g_readytorun->head + _switch_tcb $tcb + set $_current_tcb = 0x0 + continue +end