[Crash-utility] [RFC] display function param and local value for backtrace
Dave Anderson
anderson at redhat.com
Tue Oct 16 13:27:56 UTC 2012
----- Original Message -----
>
>
>
> Hi Dave,
>
>
>
> Current I am trying to make crash support display out function param
> and local value while backtracing.
>
> The idea for this patch is to mimic core dump support in gdb,
> teaching the crash to supply the regset to the gdb, so that gdb
> could have full knowledge what is going on in the panic point.
>
> A few progress has been made, the first two frames could display out
> correctly, but while it is going on to display out the third frame,
> it report fail as “Cannot access memory” to the stack address.
>
> While I use the rd command to access this range, and could correct pc
> value there.
>
> With further check, I find it failed at value_fetch_lazy at gdb code.
>
> Do you have any idea why gdb side couldn’t read the stack content?
>
> The generated log as:
>
> crash> bt
> PID: 886 TASK: c54991a0 CPU: 0 COMMAND: "sh"
> #0 sysrq_handle_crash (key=99) at drivers/tty/sysrq.c:132
> No locals.
> #1 0xc02da6dc in __handle_sysrq (key=99, check_mask=false) at drivers/tty/sysrq.c:522
> op_p = 0xc06dbeb8
> orig_log_level = 7
> i = -1066549576
> flags = 1610612755
> Cannot access memory at address 0xd29d5f34
> bt: display local fail at c02da1c0
> crash> rd 0xd29d5f34 1
> d29d5f34: c02da7cc ..-.
> crash> sym c02da7cc
> c02da7cc (t) write_sysrq_trigger+40 /kernel/drivers/tty/sysrq.c: 873
>
> Thanks,
> Lei
Hello Lei,
When the embedded gdb needs to read kernel memory, its code path typically
ends up calling target_read_memory() in gdb-7.3.1/gdb/target.c, which has
been patched to redirect the read back up into the crash source code:
int
target_read_memory (CORE_ADDR memaddr, gdb_byte *myaddr, int len)
{
#ifdef CRASH_MERGE
extern int gdb_readmem_callback(unsigned long, void *, int, int);
if (gdb_readmem_callback(memaddr, (void *)myaddr, len, 0))
return 0;
else
return EIO;
#endif
/* Dispatch to the topmost target, not the flattened current_target.
Memory accesses check target->to_has_(all_)memory, and the
flattened target doesn't inherit those. */
if (target_read (current_target.beneath, TARGET_OBJECT_MEMORY, NULL,
myaddr, memaddr, len) == len)
return 0;
else
return EIO;
}
The gdb_readmem_callback() function is in the crash source file gdb_interface.c.
But since the read is failing, I'm guessing that it's trying to access the
memory from a different path, probably like this:
value_fetch_lazy()
read_value_memory()
and read_value_memory() looks like this:
void
read_value_memory (struct value *val, int embedded_offset,
int stack, CORE_ADDR memaddr,
gdb_byte *buffer, size_t length)
{
if (length)
{
VEC(mem_range_s) *available_memory;
if (get_traceframe_number () < 0
|| !traceframe_available_memory (&available_memory, memaddr, length))
{
if (stack)
read_stack (memaddr, buffer, length); <== this path has never been used
else
read_memory (memaddr, buffer, length);
}
If read_memory() were called, then it would call the patched target_read_memory()
function above, and the read would work OK. But if read_stack() is called, it takes
a different path:
read_stack()
target_read_stack()
and target_read_stack() does not call target_read_memory(), but rather it
calls the similar function target_read_stack().
And it appears that target_read_stack() can be modified in the same way
that target_read_memory() has been, since they are essentially the same:
int
target_read_stack (CORE_ADDR memaddr, gdb_byte *myaddr, int len)
{
/* Dispatch to the topmost target, not the flattened current_target.
Memory accesses check target->to_has_(all_)memory, and the
flattened target doesn't inherit those. */
if (target_read (current_target.beneath, TARGET_OBJECT_STACK_MEMORY, NULL,
myaddr, memaddr, len) == len)
return 0;
else
return EIO;
}
So just try cut-and-pasting the same #ifdef CRASH_MERGE section into target_read_stack().
Dave
More information about the Crash-utility
mailing list