0

I know there potentially can be multiple different threading libraries that one use, but for this question I'm specifically thinking about POSIX pthreads.

Figuring out where the stack for the "process/main task/main thread/thread group leader" it's not all that difficult I think. Looking in the /proc/ filesystem one can guess where this stuff is for a particular task.

What I want to be able to do, is find out where pthread placed the stack for the newly created thread and if this is even possible to figure out? This functionality would be, for instance used in a debugger like GDB.

One can pass stack address and stack size to the pthread_create function, so obviously some control over where it's located in virtual memory is possible.

Is there possibly a way to write a kernel module that looks at stack addresses of a pid/tid and determine from there, where in virtual memory of the process, where it's located? The stack member variable of struct task_struct in the kernel, seems to point to the physical memory and not the virtual memory, which is what I'm actually interested in.

ptrace doesn't seem to have an API for this either, which is unfortunate (for me). From a debugger's perspective this could be interesting information.

Looking at the stack pointer of a task and "going backwards" until a memory mapping's start, certainly isn't a clean way to do it and I'm not sure if that's even 100% certain to be correct either.

I would greatly appreciate if anybody had any ideas or if this is even possible.

6
  • 1
    You mean like man7.org/linux/man-pages/man3/pthread_getattr_np.3.html ? Commented Jan 5, 2023 at 23:10
  • It depends on what exactly you're trying to do. You can find thread stacks by looking at the /proc/... info and look for the non-writeable stack pages - the thread stacks will appear immediately above the guard pages. You could also call a function from the start of the thread function to look at the address of a stack variable, and estimate where the stack is located (IIRC there is an example implementation online) Commented Jan 5, 2023 at 23:43
  • @KamilCuk yes, it would be the equivalent of that, but remember (and I perhaps wasn't clear enough on that), the perspective is something like a debugger; the question relates to situations where "we" are not "the program", i.e. in a debugger situation we are the tracer and inspecting the tracee. Commented Jan 6, 2023 at 11:36
  • @Den-Jason I'm trying to figure out where pthread placed the individual stacks for threads, this can be used for many debugger-purposes, like checkpointing the application, using fork for instance and recreate threads, but you would have to know where their stacks were, not just their immediate context (like the register file of each individual task). Perhaps the only way here would be to keep track of when threads are created in the tracee/debugee and look at new mappings that got mapped in during the creation of that thread. Commented Jan 6, 2023 at 11:39
  • See the sources github.com/lattera/glibc/blob/master/nptl/… . It reads /proc/self/maps and finds something inside __libc_stack_end Commented Jan 6, 2023 at 11:55

1 Answer 1

1

the question relates to situations where "we" are not "the program", i.e. in a debugger situation we are the tracer and inspecting the tracee.

You are probably looking for td_thr_get_info() from libthread_db, which (among other info) returns

 paddr ti_stkbase; /* base of thread's stack area*/ int ti_stksize; /* size in bytes of thread's allocated stack region*/ 

P.S. Looking in /proc/$pid/maps is a possibility, but you wouldn't necessarily know which anonymous mappings "belong" to thread stacks.

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.