2008-04-17 08:35:00 +04:00
/*
* Stack trace utility
*
* Copyright 2008 Christoph Hellwig , IBM Corp .
*
*
* This program is free software ; you can redistribute it and / or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation ; either version
* 2 of the License , or ( at your option ) any later version .
*/
2011-07-23 02:24:23 +04:00
# include <linux/export.h>
2008-04-17 08:35:00 +04:00
# include <linux/sched.h>
# include <linux/stacktrace.h>
# include <asm/ptrace.h>
2008-07-10 18:08:18 +04:00
# include <asm/processor.h>
2008-04-17 08:35:00 +04:00
/*
* Save stack - backtrace addresses into a stack_trace buffer .
*/
2008-07-10 18:08:18 +04:00
static void save_context_stack ( struct stack_trace * trace , unsigned long sp ,
struct task_struct * tsk , int savesched )
2008-04-17 08:35:00 +04:00
{
for ( ; ; ) {
unsigned long * stack = ( unsigned long * ) sp ;
unsigned long newsp , ip ;
2008-07-10 18:08:18 +04:00
if ( ! validate_sp ( sp , tsk , STACK_FRAME_OVERHEAD ) )
2008-04-17 08:35:00 +04:00
return ;
newsp = stack [ 0 ] ;
ip = stack [ STACK_FRAME_LR_SAVE ] ;
2008-07-10 18:08:18 +04:00
if ( savesched | | ! in_sched_functions ( ip ) ) {
if ( ! trace - > skip )
trace - > entries [ trace - > nr_entries + + ] = ip ;
else
trace - > skip - - ;
}
2008-04-17 08:35:00 +04:00
if ( trace - > nr_entries > = trace - > max_entries )
return ;
sp = newsp ;
}
}
2008-07-10 18:08:18 +04:00
void save_stack_trace ( struct stack_trace * trace )
{
unsigned long sp ;
2014-10-13 12:41:39 +04:00
sp = current_stack_pointer ( ) ;
2008-07-10 18:08:18 +04:00
save_context_stack ( trace , sp , current , 1 ) ;
}
EXPORT_SYMBOL_GPL ( save_stack_trace ) ;
void save_stack_trace_tsk ( struct task_struct * tsk , struct stack_trace * trace )
{
2008-07-17 02:12:25 +04:00
save_context_stack ( trace , tsk - > thread . ksp , tsk , 0 ) ;
2008-07-10 18:08:18 +04:00
}
EXPORT_SYMBOL_GPL ( save_stack_trace_tsk ) ;