how does linux restores a thread's stack pointer, program counter and return address.
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" ______________________________________________________________________
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
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
participants (3)
-
Chauhan, Himanshu -
Dave Hylands -
Smital Desai