All of lore.kernel.org
 help / color / mirror / Atom feed
* how does linux restores a thread's stack pointer, program counter and return address.
@ 2011-10-04  4:20 Smital Desai
  2011-10-04 12:50 ` Chauhan, Himanshu
  2011-10-04 18:33 ` Dave Hylands
  0 siblings, 2 replies; 3+ messages in thread
From: Smital Desai @ 2011-10-04  4:20 UTC (permalink / raw)
  To: kernelnewbies

Hi.
I am using linux 2.6.39 and MIPS core.
I am keen to find out how does linux restores a thread's stack pointer, program counter and return address.

I have created a binary which spawns four threads. with a ps -eaL , then I kill one of the thread with kill -11 <thread_id>. In the kernel 'do_coredump' handler i can easily find out the stack pointer of the current crashed thread by reading the struct pt_regs->reg29. My concern is to find out the stack pointers of rest of the 3 threads that did not crash. I did it this way:

1. read the reg29 variable of struct thread_struct for each task (By traversing the list of task with list_for_each)
2. Dump the values at address stored in reg29.
3. Look out manually to locate the Stack pointer offset. Tried this by crashing all the threads and found that the stackpointer comes at a fixed offset and assumed that stack pointer to be correct and I went ahead.

so you can say that my Stack pointer is stored at => reg29 + offset;

My question now is how to find this value of 'offset' dynamically. How does the kernel keeps a track of any thread's stack pointer while restoring the context. Since my observation was that the reg29 field of struct thread_struct at a glance seems to be a stack pointer. but it is not. it is just an address where at some offset we can find our stack pointer stored.

Thanks
Smital Desai





________________________________
The contents of this e-mail and any attachment(s) may contain confidential or privileged information for the intended recipient(s). Unintended recipients are prohibited from taking action on the basis of information in this e-mail and using or disseminating the information, and must notify the sender and delete it from their system. L&T Infotech will not accept responsibility or liability for the accuracy or completeness of, or the presence of any virus or disabling code in this e-mail"

______________________________________________________________________
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.kernelnewbies.org/pipermail/kernelnewbies/attachments/20111004/544e5aaf/attachment-0001.html 

^ permalink raw reply	[flat|nested] 3+ messages in thread

* how does linux restores a thread's stack pointer, program counter and return address.
  2011-10-04  4:20 how does linux restores a thread's stack pointer, program counter and return address Smital Desai
@ 2011-10-04 12:50 ` Chauhan, Himanshu
  2011-10-04 18:33 ` Dave Hylands
  1 sibling, 0 replies; 3+ messages in thread
From: Chauhan, Himanshu @ 2011-10-04 12:50 UTC (permalink / raw)
  To: kernelnewbies

Hi Smital,

> I am keen to find out how does linux restores a thread's stack pointer, program counter and return address.

Isn't it that each thread has a different task_struct and at schedule
r29 is reloaded from its own independent task_struct?
Also, while scheduling pc and r31 are stored at the independent stack?

Anyways, I think if you ask this question at Linux MIPS mailing list,
people might shed more light on it.

-Himanshu

^ permalink raw reply	[flat|nested] 3+ messages in thread

* how does linux restores a thread's stack pointer, program counter and return address.
  2011-10-04  4:20 how does linux restores a thread's stack pointer, program counter and return address Smital Desai
  2011-10-04 12:50 ` Chauhan, Himanshu
@ 2011-10-04 18:33 ` Dave Hylands
  1 sibling, 0 replies; 3+ messages in thread
From: Dave Hylands @ 2011-10-04 18:33 UTC (permalink / raw)
  To: kernelnewbies

Hi Smital,

On Mon, Oct 3, 2011 at 9:20 PM, Smital Desai
<Smital.Desai@lntinfotech.com> wrote:
> Hi.
>
> I am using linux 2.6.39 and MIPS core.
>
> I am keen to find out how does linux restores a thread's stack pointer,
> program counter and return address.
>
> I have created a binary which spawns four threads. with a ps -eaL , then I
> kill one of the thread with kill -11 <thread_id>. In the kernel
> 'do_coredump' handler i can easily find out the stack pointer of the current
> crashed thread by reading the struct pt_regs->reg29. My concern is to find
> out the stack pointers of rest of the 3 threads that did not crash. I did it
> this way:
>
> 1. read the reg29 variable of struct thread_struct for each task (By
> traversing the list of task with list_for_each)
> 2. Dump the values at address stored in reg29.
> 3. Look out manually to locate the Stack pointer offset. Tried this by
> crashing all the threads and found that the stackpointer comes at a fixed
> offset and assumed that stack pointer to be correct and I went ahead.
>
> so you can say that my Stack pointer is stored at => reg29 + offset;
>
> My question now is how to find this value of 'offset' dynamically. How does
> the kernel keeps a track of any thread's stack pointer while restoring the
> context. Since my observation was that the reg29 field of struct
> thread_struct at a glance seems to be a stack pointer. but it is not. it is
> just an address where at some offset we can find our stack pointer stored.

Each thread has its own stack, which grows from high memory towards low memory.

At the low memory end of the stack, a thread_info structure contains
thread specific information, including the stack pointer for
non-running threads.

The code which actually performs the context switch starts here:
http://lxr.linux.no/linux+v2.6.39/kernel/sched.c#L2954

and the call to switch_to is where the switch actually takes place
(and will be architecture dependant).

You may be interested in looking at the SysRq-T, which (if enabled)
will dump the context of all threads in the system to the console.

A snippet from my ARM system looks like the following:

*** break sent ***
[45568.530000] SysRq : Show State
[45568.530000]   task                PC stack   pid father
[45568.530000] systemd         S c0397de8     0     1      0 0x00000000
[45568.530000] [<c0397de8>] (schedule+0x588/0x668) from [<c03990bc>]
(schedule_hrtimeout_range_clock+0x44/0x14c)
[45568.530000] [<c03990bc>]
(schedule_hrtimeout_range_clock+0x44/0x14c) from [<c010bd1c>]
(sys_epoll_wait+0x1b0/0x308)
[45568.530000] [<c010bd1c>] (sys_epoll_wait+0x1b0/0x308) from
[<c00359c0>] (ret_fast_syscall+0x0/0x30)
[45568.530000] kthreadd        S c0397de8     0     2      0 0x00000000
[45568.530000] [<c0397de8>] (schedule+0x588/0x668) from [<c0088f3c>]
(kthreadd+0x6c/0xf8)
[45568.530000] [<c0088f3c>] (kthreadd+0x6c/0xf8) from [<c00363ac>]
(kernel_thread_exit+0x0/0x8)
[45568.530000] ksoftirqd/0     S c0397de8     0     3      2 0x00000000
[45568.530000] [<c0397de8>] (schedule+0x588/0x668) from [<c0076018>]
(run_ksoftirqd+0x78/0x1bc)
[45568.530000] [<c0076018>] (run_ksoftirqd+0x78/0x1bc) from
[<c0088cf4>] (kthread+0x84/0x8c)
[45568.530000] [<c0088cf4>] (kthread+0x84/0x8c) from [<c00363ac>]
(kernel_thread_exit+0x0/0x8)

So you get to see each thread, its state (S) PC, pid, and a backtrace
(from within kernel space). For user-mode stuff, this will only show
you backtrace to the system-call interface. How the stack pointers are
stored in user-space is dependant on the C runtime library that you're
using.

The code for dumping this information calls sysrq_handle_showstate
http://lxr.linux.no/linux+v2.6.39/drivers/tty/sysrq.c#L268

which in turns calls show_state:
http://lxr.linux.no/linux+v2.6.39/include/linux/sched.h#L286

-- 
Dave Hylands
Shuswap, BC, Canada
http://www.davehylands.com

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2011-10-04 18:33 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-10-04  4:20 how does linux restores a thread's stack pointer, program counter and return address Smital Desai
2011-10-04 12:50 ` Chauhan, Himanshu
2011-10-04 18:33 ` Dave Hylands

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.