Re: Cute kernel trick, or communistic ploy?

From: Werner Almesberger (wa@almesberger.net)
Date: Fri May 30 2003 - 20:37:30 EST


Carl Spalletta wrote:
> This program works fine in the um arch but I was wondering what
> the pitfalls are in an approach like this.

You mean calling functions from a debugger ? By and large, this
should be okay. I'm doing it all the time in umlsim :-)

You have to make sure you're really allowed to call these functions
from the point where you've stopped the kernel, i.e.

- that they don't change data structures protected by a common
spinlock (which may be absent on UP)
- that they don't sleep

Besides that, you may run into problems if gdb doesn't understand
the calling convention. So far, I haven't found a case where this
happens. (But then, I'm working directly from the DWARF2 data, so
I wouldn't notice bugs in gdb, only wrong or incomplete debugging
information. And I haven't tried FASTCALL functions yet.)

Also, you probably can't call inline functions from gdb. You can
probably work around this by adding a file somewhere to the kernel
that includes all the headers with inline functions you want, and
then compile it with -fkeep-inline-functions -Wno-unused-function.
Depending on what you include, you may also need to

void __this_fixmap_does_not_exist(void)
{
panic("__this_fixmap_does_not_exist called\n");
}

Oh, and when you explore further, be warned that accessing local
variables can be messy, particularly when inline functions are
involved.

I ran your example with umlsim. Here's what it looks like:

#define GFP_ATOMIC 0x20
$uml = $run_uml("A","no-such-script",1);
$page = (char *) kmalloc(4096,GFP_ATOMIC);
$start = (char **) kmalloc(4,GFP_ATOMIC);
$eof = (int *) kmalloc(4,GFP_ATOMIC);
$data = kmalloc(1,GFP_ATOMIC);
uptime_read_proc($page,$start,0,0,$eof,$data);
kfree((void *) $eof);
kfree((void *) $start);
kfree((void *) $data);
printk(*$start);
kfree((void *) $page);

(I shouldn't need to kmalloc $data or the casts in kfree.
Two more things to fix ...)

If you don't like the printk, umlsim could also copy the
data to the simulator and print it from there, but the
syntax is a bit ugly:

print (char ["umlsim_inline.c".strlen(*$start)+1]) *$start;

By the way, it may also matter how you stop your process. I
normally use breakpoints (INT3), and things work fine. I'm
still experimenting with SIGSTOP.

- Werner

--
_________________________________________________________________________
/ Werner Almesberger, Buenos Aires, Argentina wa@xxxxxxxxxxxxxxx /
/_http://www.almesberger.net/____________________________________________/
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/