----- 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