Messages in this thread Patch in this message | | | From | "Petr Vandrovec Ing. VTEI" <> | Date | Thu, 15 Jul 1999 11:58:11 MET-1 | Subject | Re: Register reads in kernel space ... |
| |
> What's the best way to capture a register snapshot within the kernel > context? For example, how do I capture pt_regs in any function, > assuming I'm not taking an exception ... I'm executing normally. > (My question is specific to x86 code). I realize show_registers() > is available for dumping the register state, but to get the current > register state, it looks like you have to pull each register from > the context of get_current(). Is that what we're left with?
I'm using this... It generates pt_regs struct on stack (and prints them+stacktrace). If you need them in some structure, you have to fill it manually - there is no library function AFAIK (patch is for 2.3.11-pre3):
diff -urdN linux/arch/i386/kernel/traps.c linux/arch/i386/kernel/traps.c --- linux/arch/i386/kernel/traps.c Mon Jul 12 11:31:00 1999 +++ linux/arch/i386/kernel/traps.c Mon Jul 12 11:35:20 1999 @@ -191,6 +191,42 @@ printk("\n"); }
+void printstate(void) { + asm volatile ( + "pushl %%ss\n\t" + "pushl %%esp\n\t" + "pushfl\n\t" + "pushl %%cs\n\t" + "call 1f\n" + "1:\n\t" + "pushl %%eax\n\t" + "pushl %%ds\n\t" + "pushl %%es\n\t" + "pushl %%eax\n\t" + "pushl %%ebp\n\t" + "pushl %%edi\n\t" + "pushl %%esi\n\t" + "pushl %%edx\n\t" + "pushl %%ecx\n\t" + "pushl %%ebx\n\t" + "movl %%esp,%%eax\n\t" + "pushl %%eax\n\t" + "call show_registers\n\t" + "addl $4,%%esp\n\t" + "popl %%ebx\n\t" + "popl %%ecx\n\t" + "popl %%edx\n\t" + "popl %%esi\n\t" + "popl %%edi\n\t" + "popl %%ebp\n\t" + "popl %%eax\n\t" + "popl %%es\n\t" + "popl %%ds\n\t" + "popl %%eax\n\t" + "addl $20,%%esp\n\t" + : : : "memory" ); +} + spinlock_t die_lock;
void die(const char * str, struct pt_regs * regs, long err) > And while we're on the topic, what about register snapshots for each > CPU? You are out of luck. You have to add an IPI operation `store my registers somewhere'. Or, you can (with new TSSes) change IPI interrupt to task gate and prepare dummy TSS, which can do (1) endless loop or (2) execute old IPI proc and iret. Then send IPI... In both cases, old TSS will be filled with registers at time of IPI. Or you can change timer interrupt or anything else, but IPI comes to my mind as it is delivered to all (or specific) cpus. > Thanks for any advice. I'm looking for a consistent method to do > this (so we can create proper kernel backtraces for our post-crash > analysis utilities.) If it is `complete crash' postcrash, I think that TSS with endless loop is best. You kill two problems with this: (1) other CPUs will stop doing damage in memory and (2) you'll get their registers... (and (3) you can revive them after that by simple overwritting endless loop with iret). Best regards, Petr Vandrovec vandrove@vc.cvut.cz
P.S.: It is i386 specific, of course. You have to code it for every architecture you support (as each architecture has different registers and different IPI mechanism).
- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.rutgers.edu Please read the FAQ at http://www.tux.org/lkml/
| |