void save_stack_trace(struct stack_trace *trace)
  {
-       unsigned long sp;
- 
-       sp = current_stack_pointer();
-       dump_trace(save_address, trace, NULL, sp);
+       struct unwind_state state;
+ 
+       unwind_for_each_frame(&state, current, NULL, 0) {
+               if (trace->nr_entries >= trace->max_entries)
+                       break;
+               if (trace->skip > 0)
+                       trace->skip--;
+               else
+                       trace->entries[trace->nr_entries++] = state.ip;
+       }
 -      if (trace->nr_entries < trace->max_entries)
 -              trace->entries[trace->nr_entries++] = ULONG_MAX;
  }
  EXPORT_SYMBOL_GPL(save_stack_trace);
  
  void save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace)
  {
-       unsigned long sp;
- 
-       sp = tsk->thread.ksp;
-       if (tsk == current)
-               sp = current_stack_pointer();
-       dump_trace(save_address_nosched, trace, tsk, sp);
+       struct unwind_state state;
+ 
+       unwind_for_each_frame(&state, tsk, NULL, 0) {
+               if (trace->nr_entries >= trace->max_entries)
+                       break;
+               if (in_sched_functions(state.ip))
+                       continue;
+               if (trace->skip > 0)
+                       trace->skip--;
+               else
+                       trace->entries[trace->nr_entries++] = state.ip;
+       }
 -      if (trace->nr_entries < trace->max_entries)
 -              trace->entries[trace->nr_entries++] = ULONG_MAX;
  }
  EXPORT_SYMBOL_GPL(save_stack_trace_tsk);
  
  void save_stack_trace_regs(struct pt_regs *regs, struct stack_trace *trace)
  {
-       unsigned long sp;
- 
-       sp = kernel_stack_pointer(regs);
-       dump_trace(save_address, trace, NULL, sp);
+       struct unwind_state state;
+ 
+       unwind_for_each_frame(&state, current, regs, 0) {
+               if (trace->nr_entries >= trace->max_entries)
+                       break;
+               if (trace->skip > 0)
+                       trace->skip--;
+               else
+                       trace->entries[trace->nr_entries++] = state.ip;
+       }
 -      if (trace->nr_entries < trace->max_entries)
 -              trace->entries[trace->nr_entries++] = ULONG_MAX;
  }
  EXPORT_SYMBOL_GPL(save_stack_trace_regs);