----- 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 -- Crash-utility mailing list Crash-utility@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/crash-utility