Hello Hackers!

I have an idea which could be used to track FreeBSD performance and regression 
testing. Please take a look and give Your opinion on how usefull that would be 
for the FreeBSD project.


The basis for this system would be hijacking certain functions execution with 
injected code. Hijacker program runs target binary with LD_PRELOAD to inject 
some code (code doing statistics, tests, etc..) and installs redirections using 
ptrace (injecting jump instructions here and there). It then deattaches and the 
program runs almost as normal. (A little demo of how this might look later).

This approach has its pros and cons:
+ no context switch to fire hijacking code
+ flexible - You can hijack any function that has a symbol. Hijacking PLT 
(done) and relocations in shared libraries (will be done) included.
+ transparent - there needs to be no modiffication in target binary; hackers 
don't own all the hardware. It's hard to ask people with interesting equipement 
to recompile their binaries with profiling options. This would allow them to 
measure performance without changing their system.
+ small performance impact - put code only in places You want, and put there 
only the code which is needed there. (can be made O(1) unless You make it worse)

- ABI / Architecture dependent
- needs all the shared library mechanism to inject code (LD_PRELOAD)
- needs symbols
- writes the ro code pages on installing the redirections (negligible?)

And here is the demo of poc code (not particulary usefull..but..)
This hijack code has a static table indexed by read sizes in which we count how 
many times a read of this size was called.
------------------------------------
#include <hijack.h>
#include <stdio.h>

#define PROBES 400
#define QUANT 0x10
static int stats[PROBES];
static int max_read;
// RV(type) gives return value of the code

HIJACK(int, read, (int fd, char *buf, size_t size),
/* before call*/
,
/* after call*/
        printf("read() = %d\n", RV(int));
        if (max_read < RV(int))
                max_read = RV(int);
        if ((RV(int) >=0) && (RV(int) < QUANT * PROBES))
        {
                stats[RV(int) / QUANT]++;
        }

)

HIJACK(int, main, (),
        printf("hello hijacking!\n");
,
)

HIJACK(int, exit, (),
        int i;
        for (i=0; i<PROBES; i++)
                if (stats[i])
                        fprintf(stdout,"%04d %04d\n", i*QUANT, stats[i]);
        fprintf(stdout,"and max read was %d\n", max_read);
        fclose(stdout);
        printf("finish!\n");
        return RV(int);
        ,
)
----------------------
i compile it
gcc -o apa.so -shared -I. apa.c hijack.c
(hijack.c has some required runtime functions)

I run it on apache:

./hijack -c ./apa.so -h *libc.so.5:read -h *libc.so*:exit -h main 
/usr/local/sbin/httpd -X
hello
read() = 4096
read() = 4096
read() = 2732
(some of these....)
read() = 0
read() = 961
read() = 425
read() = 0
(here i press ^C)
0000 0010
0112 0002
0256 0002
0416 0003
0512 0002
0656 0002
0960 0001
1120 0002
2720 0002
4096 0046
and max read was 4096
------------------------------------

So, again, please send Your opinions on this idea. Do You think this (+ all 
needed utilities to do statistics etc) would be applicable to Summer Of Code 
"Tracking performance over time" project?


best regards,
-- 
Marcin Koziej
_______________________________________________
freebsd-hackers@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-hackers
To unsubscribe, send any mail to "[EMAIL PROTECTED]"

Reply via email to