a150e03e24
This checks if the required function is defined (when stack coloration is enabled) and, if so, calls it to get used stack. Otherwise it just reports zero used stack.
371 lines
9.8 KiB
Plaintext
371 lines
9.8 KiB
Plaintext
############################################################################
|
|
# 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\"")
|
|
|
|
# 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
|
|
|
|
set $_tcb0 = g_pidhash[0].tcb
|
|
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
|
|
|
|
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)
|
|
|
|
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, "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[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
|
|
|
|
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
|