############################################################################ # 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 # Do not stop with SIGUSR1 which is used for the NuttX sim SMP handle SIGUSR1 "nostop" "pass" "noprint" 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\"") python if (_target_arch.name() == 'armv7') : \ gdb.execute("set $_target_arch = \"armv7e-m\"") # TODO: need more smart way to detect armv7-a python if (type(gdb.lookup_global_symbol("arm_gic_initialize")) is gdb.Symbol) : \ gdb.execute("set $_target_arch = \"armv7-a\"") 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_static_symbol("sim_start")) is gdb.Symbol \ and _target_arch.name() == 'i386') : \ gdb.execute("set $_target_arch=\"sim:x86\"") python if (type(gdb.lookup_static_symbol("sim_start")) is gdb.Symbol \ and _target_arch.name() == 'i386:x86-64') : \ gdb.execute("set $_target_arch=\"sim:x86-64\"") end define _examine_target if ($_target_examined == 0x0) _examine_arch set $_tcb0 = g_pidhash[0] set $_xcp_nregs = sizeof($_tcb0->xcp.regs) / sizeof($_tcb0->xcp.regs[0]) set $_target_has_fpu = 0 if ($_streq($_target_arch, "armv7e-m") == 1) if ($_xcp_nregs != 19) set $_target_has_fpu = 1 end end if ($_streq($_target_arch, "armv7-a") == 1) if ($_xcp_nregs != 17) set $_target_has_fpu = 1 end end 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 = g_npidhash python if (type(gdb.lookup_global_symbol("up_check_tcbstack")) is gdb.Symbol) : \ gdb.execute("set $_target_has_stack_coloration = 1") 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 if ($_target_has_stack_coloration) set $stack_used = up_check_tcbstack($tcb) else set $stack_used = 0 end printf "%d Thread 0x%x (Name: %s, State: %s, Priority: %d, Stack: %d/%d) PC: 0x%x in ", \ $tcb->pid, $tcb, $tcb->name, g_statenames[$tcb->task_state], $tcb->sched_priority, \ $stack_used, $tcb->adj_stack_size, $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, "armv7-a") == 1) _save_tcb_armv7-a $tcb end 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 if ($_streq($_target_arch, "sim:x86") == 1) _save_tcb_simx86 $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, "armv7-a") == 1) _switch_tcb_armv7-a $tcb end 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 if ($_streq($_target_arch, "sim:x86") == 1) _switch_tcb_simx86 $tcb end # update _current_tcb set $_current_tcb = $tcb end # see nuttx/arch/arm/include/armv7-a/irq.h define _save_tcb_armv7-a set $tcb = (struct tcb_s *)$arg0 set $tcb.xcp.regs[0] = $r0 set $tcb.xcp.regs[1] = $r1 set $tcb.xcp.regs[2] = $r2 set $tcb.xcp.regs[3] = $r3 set $tcb.xcp.regs[4] = $r4 set $tcb.xcp.regs[5] = $r5 set $tcb.xcp.regs[6] = $r6 set $tcb.xcp.regs[7] = $r7 set $tcb.xcp.regs[8] = $r8 set $tcb.xcp.regs[9] = $r9 set $tcb.xcp.regs[10] = $r10 set $tcb.xcp.regs[11] = $r11 set $tcb.xcp.regs[12] = $r12 set $tcb.xcp.regs[13] = $r13 set $tcb.xcp.regs[14] = $r14 set $tcb.xcp.regs[15] = $r15 # TODO: xPSR set $_pc_reg_idx = 15 end define _switch_tcb_armv7-a set $tcb = (struct tcb_s *)$arg0 set $r0 = $tcb.xcp.regs[0] set $r1 = $tcb.xcp.regs[1] set $r2 = $tcb.xcp.regs[2] set $r3 = $tcb.xcp.regs[3] set $r4 = $tcb.xcp.regs[4] set $r5 = $tcb.xcp.regs[5] set $r6 = $tcb.xcp.regs[6] set $r7 = $tcb.xcp.regs[7] set $r8 = $tcb.xcp.regs[8] set $r9 = $tcb.xcp.regs[9] set $r10 = $tcb.xcp.regs[10] set $r11 = $tcb.xcp.regs[11] set $r12 = $tcb.xcp.regs[12] set $r13 = $tcb.xcp.regs[13] set $r14 = $tcb.xcp.regs[14] set $r15 = $tcb.xcp.regs[15] # TODO: xPSR 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[11] = $r0 set $tcb.xcp.regs[12] = $r1 set $tcb.xcp.regs[13] = $r2 set $tcb.xcp.regs[14] = $r3 set $tcb.xcp.regs[15] = $r12 set $tcb.xcp.regs[16] = $lr set $tcb.xcp.regs[17] = $pc # TODO: xPSR set $_pc_reg_idx = 17 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[11] set $r1 = $tcb.xcp.regs[12] set $r2 = $tcb.xcp.regs[13] set $r3 = $tcb.xcp.regs[14] set $r12 = $tcb.xcp.regs[15] set $lr = $tcb.xcp.regs[16] set $pc = $tcb.xcp.regs[17] # 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 # see nuttx/arch/sim/src/sim/up_internal.h define _save_tcb_simx86 set $tcb = (struct tcb_s *)$arg0 set $tcb.xcp.regs[0] = $ebx set $tcb.xcp.regs[1] = $esi set $tcb.xcp.regs[2] = $edi set $tcb.xcp.regs[3] = $ebp set $tcb.xcp.regs[4] = $sp set $tcb.xcp.regs[5] = $pc set $_pc_reg_idx = 5 end define _switch_tcb_simx86 set $tcb = (struct tcb_s *)$arg0 set $ebx = $tcb.xcp.regs[0] set $esi = $tcb.xcp.regs[1] set $edi = $tcb.xcp.regs[2] set $ebp = $tcb.xcp.regs[3] set $sp = $tcb.xcp.regs[4] set $pc = $tcb.xcp.regs[5] end define _restore_current_tcb # TODO: SMP set $tcb = g_readytorun->head _switch_tcb $tcb set $_current_tcb = 0x0 end define nxthread _examine_target _save_current_tcb set $hash = ($arg0 & ($_target_max_tasks - 1)) set $tcb = g_pidhash[$hash] 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 _restore_current_tcb 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 _restore_current_tcb 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 _restore_current_tcb end define nxcontinue printf "nxcontinue\n" _restore_current_tcb continue end