To trace back through a thread’s kernel or user stack, you first need to find the stack pointer value. On the ARM, R13 always points to the stack, but there are different R13 registers for each processor mode:
In thread context:
R13usr points to the thread’s user stack,
R13svc points to the thread’s kernel stack.
When handling interrupts, dedicated stacks are used:
R13Fiq points to the stack used when processing fast interrupts (FIQ).
R13Irq points to the stack used when processing general purpose interrupts (IRQ)
To find out which stack to inspect, you need to know what mode the CPU was in when the fault occurred. The processor mode is identified by the five least-significant bits of the CPSR register. To get the value of the CPSR register:
use the f command when the debug monitor is triggered by a hardware exception.
use the r command when the debug monitor is triggered by a panic.
The following examples show how to find the stack(s):
Use the f command.
Fault Category: Exception Fault Reason: 10000000
ExcId 00000001 CodeAddr f816c908 DataAddr 80000001 Extra c0007003
Exc 1 Cpsr=60000010 FAR=80000001 FSR=c0007003
R0=00000000 R1=00000000 R2=30000000 R3=80000001
R4=00000001 R5=00403d88 R6=00002000 R7=f816c768
R8=00000012 R9=00000040 R10=00000000 R11=00403fa4
R12=00403d5c R13=00403d70 R14=f80906f8 R15=f816c908
R13Svc=6571e000 R14Svc=f80074bc SpsrSvc=80000010
In this example:
the kernel stack is the value of R13Svc, i.e. 0x6571e00.
the user stack is the value of R13, i.e. 0x00403d70.
Use the r command.
MODE_USR:
R0=6571de54 R1=0000002a R2=00000002 R3=ffffffff
R4=0000002a R5=f8170414 R6=6571df14 R7=6403cc50
R8=00000001 R9=6403c44c R10=640002f8 R11=6571de70
R12=00000020 R13=00404e00 R14=f80818c0 R15=f800bfa8
CPSR=60000013
MODE_FIQ:
R8=00000000 R9=ffffffff R10=ffffffff R11=00000000
R12=00000000 R13=64000d0c R14=c080079c SPSR=e00000dc
MODE_IRQ:
R13=6400110c R14=00000013 SPSR=20000013
MODE_SVC:
R13=6571de54 R14=f80328bc SPSR=60000010
MODE_ABT:
R13=6400090c R14=ccbfd0e0 SPSR=b00000d9
MODE_UND:
R13=6400090c R14=b5a39950 SPSR=f000009d
In this example:
the kernel stack is the value of R13 under MODE_SVC:, i.e. 0x6571de54.
the user stack is the value of R13 under MODE_USR:, i.e. 0x00404e00.
Use the r command.
MODE_USR:
R0=6571de54 R1=0000002a R2=00000002 R3=ffffffff
R4=0000002a R5=f8170414 R6=6571df14 R7=6403cc50
R8=00000001 R9=6403c44c R10=640002f8 R11=6571de70
R12=00000020 R13=00404e00 R14=f80818c0 R15=f800bfa8
CPSR=60000013
MODE_FIQ:
R8=00000000 R9=ffffffff R10=ffffffff R11=00000000
R12=00000000 R13=64000d0c R14=c080079c SPSR=e00000dc
MODE_IRQ:
R13=6400110c R14=00000013 SPSR=20000013
MODE_SVC:
R13=6571de54 R14=f80328bc SPSR=60000010
MODE_ABT:
R13=6400090c R14=ccbfd0e0 SPSR=b00000d9
MODE_UND:
R13=6400090c R14=b5a39950 SPSR=f000009d
In this example:
the IRQ stack is the value of R13 under MODE_IRQ:, i.e. 0x6400110c.
the FRQ stack is the value of R13 under MODE_FIQ:, i.e. 0x64000d0c.
Use the output of the i, q and c commands.
THREAD at 6403c194 VPTR=f8046c18 AccessCount=5 Owner=6403bb4c
Full name t_dmasim::Main
Thread MState READY
Default priority 12 WaitLink Priority 12
ExitInfo 3,0,
Flags 00000002, Handles 6403b418
Supervisor stack base 6571d000 size 1000
User stack base 00403000 size 2000
Id=25, Alctr=00700000, Created alctr=00700000, Frame=00000000
Trap handler=00000000, ActiveScheduler=007000c8, Exception handler=00000000
TempObj=00000000 TempAlloc=00000000
NThread @ 6403c44c Pri 12 NState READY
Next=6403c44c Prev=6403c44c Att=03 iUserContextType=02
HeldFM=00000000 WaitFM=00000000 AddrSp=6403bb4c
Time=0 Timeslice=20 ReqCount=0
SuspendCount=0 CsCount=1 CsFunction=00000000
SavedSP=6571df98
DACR f800bd2c
R13_USR 0d404c38 R14_USR 00000001 SPSR_SVC 00000000
R4 f8022d84 R5 6571dfd4 R6 6571dfbc R7 f8022db8
R8 f800bddc R9 f800a454 R10 00000000 R11 f801daac
PC 60000010
In this example:
the kernel stack is the value of SavedSP, i.e. 0x6571df98.
the user stack is the value of R13_USR, i.e. 0x0d404c38.