@@ -140,20 +140,44 @@ struct stack_frame {
140140#endif
141141};
142142
143- #define MAX_STACK_FRAMES CONFIG_EXCEPTION_STACK_TRACE_MAX_FRAMES
143+ static bool print_trace_address (void * arg , unsigned long addr )
144+ {
145+ ARG_UNUSED (arg );
144146
145- __pinned_func
146- static void unwind_stack (uintptr_t base_ptr , uint16_t cs )
147+ #ifdef CONFIG_X86_64
148+ LOG_ERR (" 0x%016lx" , addr );
149+ #else
150+ LOG_ERR (" 0x%08lx" , addr );
151+ #endif
152+
153+ return true;
154+ }
155+
156+ __pinned_func static void walk_stackframe (stack_trace_callback_fn cb , void * cookie ,
157+ const struct arch_esf * esf , int max_frames )
147158{
159+ uintptr_t base_ptr ;
160+ uint16_t cs ;
148161 struct stack_frame * frame ;
149162 int i ;
150163
164+ if (esf != NULL ) {
165+ #ifdef CONFIG_X86_64
166+ base_ptr = esf -> rbp ;
167+ #else /* x86 32-bit */
168+ base_ptr = esf -> ebp ;
169+ #endif /* CONFIG_X86_64 */
170+ cs = esf -> cs ;
171+ } else {
172+ return ;
173+ }
174+
151175 if (base_ptr == 0U ) {
152176 LOG_ERR ("NULL base ptr" );
153177 return ;
154178 }
155179
156- for (i = 0 ; i < MAX_STACK_FRAMES ; i ++ ) {
180+ for (i = 0 ; i < max_frames ; i ++ ) {
157181 if (base_ptr % sizeof (base_ptr ) != 0U ) {
158182 LOG_ERR ("unaligned frame ptr" );
159183 return ;
@@ -178,16 +202,40 @@ static void unwind_stack(uintptr_t base_ptr, uint16_t cs)
178202 if (frame -> ret_addr == 0U ) {
179203 break ;
180204 }
181- #ifdef CONFIG_X86_64
182- LOG_ERR ( " 0x%016lx" , frame -> ret_addr );
183- #else
184- LOG_ERR ( " 0x%08lx (0x%lx)" , frame -> ret_addr , frame -> args );
185- #endif
205+
206+ if (! cb ( cookie , frame -> ret_addr )) {
207+ break ;
208+ }
209+
186210 base_ptr = frame -> next ;
187211 }
188212}
213+
214+ __pinned_func
215+ static void unwind_stack (const struct arch_esf * esf )
216+ {
217+ walk_stackframe (print_trace_address , NULL , esf ,
218+ CONFIG_EXCEPTION_STACK_TRACE_MAX_FRAMES );
219+ }
189220#endif /* CONFIG_EXCEPTION_STACK_TRACE */
190221
222+ void arch_stack_walk (stack_trace_callback_fn callback_fn , void * cookie ,
223+ const struct k_thread * thread , const struct arch_esf * esf )
224+ {
225+ #ifdef CONFIG_EXCEPTION_STACK_TRACE
226+ ARG_UNUSED (thread );
227+
228+ walk_stackframe (callback_fn , cookie , esf , CONFIG_ARCH_STACKWALK_MAX_FRAMES );
229+ #else
230+ ARG_UNUSED (callback_fn );
231+ ARG_UNUSED (cookie );
232+ ARG_UNUSED (thread );
233+ ARG_UNUSED (esf );
234+
235+ LOG_DBG ("Enable CONFIG_EXCEPTION_STACK_TRACE for %s()" , __func__ );
236+ #endif /* CONFIG_EXCEPTION_STACK_TRACE */
237+ }
238+
191239static inline uintptr_t get_cr3 (const struct arch_esf * esf )
192240{
193241#if defined(CONFIG_USERSPACE ) && defined(CONFIG_X86_KPTI )
@@ -231,7 +279,7 @@ static void dump_regs(const struct arch_esf *esf)
231279#endif
232280 LOG_ERR ("RIP: 0x%016lx" , esf -> rip );
233281#ifdef CONFIG_EXCEPTION_STACK_TRACE
234- unwind_stack (esf -> rbp , esf -> cs );
282+ unwind_stack (esf );
235283#endif
236284}
237285#else /* 32-bit */
@@ -250,7 +298,7 @@ static void dump_regs(const struct arch_esf *esf)
250298#endif
251299 LOG_ERR ("EIP: 0x%08x" , esf -> eip );
252300#ifdef CONFIG_EXCEPTION_STACK_TRACE
253- unwind_stack (esf -> ebp , esf -> cs );
301+ unwind_stack (esf );
254302#endif
255303}
256304#endif /* CONFIG_X86_64 */
0 commit comments