[minicoredumper] gdb corrupt stack

Marco.Felsch at preh.de Marco.Felsch at preh.de
Wed Jul 12 18:44:25 CEST 2017


Hi John

On 11.07.2017 15:56, John Ogness wrote:
> On 2017-07-11, John Ogness <john.ogness at linutronix.de> wrote:
>>> I've tried to obtain the stack pointer with the use of ptrace(2)
>>> equally to strace(1). But there are some pitfalls because the tracee
>>> is in the 'core dump' state.
>>>
>>> My approach was:
>>> 	ptrace(PTRACE_SEIZE, pid, NULL, PTRACE_O_TRACEEXIT)
>>> 	ptrace(PTRACE_CONT, pid, NULL, SIGCONT)
>>> 	waitpid(pid, &status, (WCONTINUED | __WALL))
>>>
>>> After some research I found out that there were some patches in 2012
>>> to support ptrace(2) in a 'core dump' state. But these never applied
>>> to the kernel.
>>>
>>> A other solution is to obtain the stack pointer from the ELF-Header.
>>> Are you agree with this approach?
>>
>> Sure. This is how gdb gets it. We just need to get the program counter
>> for the process.
> 
> Sorry, that is wrong. I forgot we are looking for the stack pointer, not
> the program counter. Is this information available in the ELF header?
> 
> I noticed that this information is also located in /proc/PID/maps. This
> might be a more compatible way to access it.

That's right but only for the 'MainThread'. It's not possible to obtain 
the stacks from the child's, this possibility was removed with 
/proc/PID/stat opportunity (merge commit [1])

So the last option to obtain the information is the core file. After 
some searching I found the location where the sp is written to the core 
file:

binfmt_elf:
static int fill_thread_core_info(struct elf_thread_core_info *t,
				 const struct user_regset_view *view,
				 long signr, size_t *total)
{
	...

	fill_prstatus(&t->prstatus, t->task, signr);
	(void) view->regsets[0].get(t->task, &view->regsets[0], 0,
				    regset_size, &t->prstatus.pr_reg,
				    NULL);

	fill_note(&t->notes[0], "CORE", NT_PRSTATUS,
		  PRSTATUS_SIZE(t->prstatus, regset_size),
		  &t->prstatus);

	*total += notesize(&t->notes[0]);
	do_thread_regset_writeback(t->task, &view->regsets[0]);

	...
}

Now we have to extract this from the core-file. Are you agree with me?

Marco Felsch

[1] 
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?h=v4.12&id=86c5bf7101991608483c93e7954b93acdc85ea57


More information about the minicoredumper mailing list