All of lore.kernel.org
 help / color / mirror / Atom feed
From: dhylands@gmail.com (Dave Hylands)
To: kernelnewbies@lists.kernelnewbies.org
Subject: how does linux restores a thread's stack pointer, program counter and return address.
Date: Tue, 4 Oct 2011 11:33:15 -0700	[thread overview]
Message-ID: <CABi1daGe=o=+zG=FRcSSRA8DLNe5kWx09kHUv6aNLHpP8mKiLA@mail.gmail.com> (raw)
In-Reply-To: <D69C90565D53114396BF743585AF5A0912AD48277E@VSHINMSMBX01.vshodc.lntinfotech.com>

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

      parent reply	other threads:[~2011-10-04 18:33 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
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 message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to='CABi1daGe=o=+zG=FRcSSRA8DLNe5kWx09kHUv6aNLHpP8mKiLA@mail.gmail.com' \
    --to=dhylands@gmail.com \
    --cc=kernelnewbies@lists.kernelnewbies.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.