On Saturday, 19 May 2001, Jeff Dike wrote:
> cemerson@... said:
> > What's the easiest way of checking bits of process memory from the
> > tracing thread?
> If you only know the virtual address:
> call pgd_offset_proc(current_task.mm, 0xdeadbeef)
> call pmd_offset_proc($, 0xdeadbeef)
> call pte_offset_proc($, 0xdeadbeef)
> p/x $.pte_low
Hmm, that doesn't work for me:
# (gdb) call pgd_offset_proc(current_task->next_task->mm, 0x10048000)
# Program received signal SIGSEGV, Segmentation fault.
# 0x200e521c in strlen () at hostfs_kern.c:672
# 672 }
# The program being debugged was signaled while in a function called
# from GDB.
# GDB remains in the frame where the signal was received.
# To change this behavior use "set unwindonsignal on"
# Evaluation of the expression containing the function (pgd_offset_proc)
# will be abandoned.
I have found the problem though. signal_handler() allocates a struct
sigcontext on the stack and uses fill_in_sigcontext() on it. On ppc,
the sigcontext only has a *pointer* to a register set (ie a
sys_pt_regs), not the actual register values themselves.
fill_in_sigcontext() was then dereferencing that (uninitialised)
pointer. This is one of those "I can't believe it worked at all"
I've fixed it by adding YA macro, UM_ALLOCATE_SC(name), which sets up
a sys_pt_regs and the pointer in the sigcontext. Maybe SC_ALLOCATE
would be more consistent with other bits in sysdep/sigcontext.h.
For future reference, I found out the culprit by watching for the
address being corrupted being passed in to do_wp_page() in
mm/memory.c. Since the address was in the code segment, it was
initially mapped read-only until someone wrote to it.
Next problem is that the mount options are being corrupted, but that's
easy in comparision. :-)
I guess I'm due to make another patch soon.
Chris Emerson, obsessed Cambridge juggler
Web page: http://www.chiark.greenend.org.uk/~cemerson/