win32 apps run pretty well in wine in valgrind. Great!
But at the moment, valgrind.h doesn't support win32,
so win32 apps can't do client requests, which
means that you can't instrument the win32 app's
heap.
So I read up on gcc inline assembler syntax, and looked
at valgrind.h... but rather than rot my brain, I decided to
use objdump to display the bytes of a simple
linux app that calls VALGRIND_PRINT.
__SPECIAL_INSTRUCTION_PREAMBLE
appears to expand to
48 c1 c7 03 rol $0x3,%rdi
48 c1 c7 0d rol $0xd,%rdi
48 c1 c7 3d rol $0x3d,%rdi
48 c1 c7 33 rol $0x33,%rdi
while the key bit of VALGRIND_DO_CLIENT_REQUEST
which immediately follows the preamble expands to
48 87 db xchg %rbx,%rbx
I'm a bit mystified by all the 0x48 prefixes. I thought
0x48 was dec ax ... what's going on there?
In spite of not understanding this, I had a shot at porting
VALGRIND_PRINTF. Here's a little test program that
should display "Hello, valgrind" and then a warning about
exit's argument being undefined when run either as a native
linux app, e.g.
gcc valprint.c
valgrind ./a.out
or as a win32 app under wine:
cl valprint.c
(transfer to linux system)
wine winemine & (to avoid valgrinding service startup)
valgrind --trace-children=yes wine valprint.exe
Works fine on linux, and on Wine the exit(undefined)
warning shows up fine, but my implementation of
VALGRIND_PRINTF seems to be a no-op :-(
Here's the test program. Anyone adventurous feel like having a look?
#include <malloc.h>
#ifdef _WIN32
#include <stdlib.h>
#include <stdarg.h>
#define __SPECIAL_INSTRUCTION_PREAMBLE __asm { \
__asm _emit 0x48 __asm _emit 0xc1 __asm _emit 0xc7 __asm _emit 0x03 \
__asm _emit 0x48 __asm _emit 0xc1 __asm _emit 0xc7 __asm _emit 0x0d \
__asm _emit 0x48 __asm _emit 0xc1 __asm _emit 0xc7 __asm _emit 0x3d \
__asm _emit 0x48 __asm _emit 0xc1 __asm _emit 0xc7 __asm _emit 0x33 \
}
enum { VG_USERREQ__RUNNING_ON_VALGRIND = 0x1001,
VG_USERREQ__PRINTF = 0x1401,
} Vg_ClientRequest;
static int
VALGRIND_PRINTF(const char *format, ...)
{
va_list vargs;
volatile unsigned int _zzq_args[6];
unsigned int _qzz_res;
va_start(vargs, format);
_zzq_args[0] = (unsigned int) VG_USERREQ__PRINTF,
_zzq_args[1] = (unsigned int) format;
_zzq_args[2] = (unsigned int) vargs;
_zzq_args[3] = (unsigned int) 0;
_zzq_args[4] = (unsigned int) 0;
_zzq_args[5] = (unsigned int) 0;
__asm mov eax, _zzq_args
__asm mov edx, 0
__SPECIAL_INSTRUCTION_PREAMBLE
__asm xchg ebx,ebx
__asm mov _qzz_res, edx
va_end(vargs);
return (int)_qzz_res;
}
#else
#include <valgrind/valgrind.h>
#endif
int main()
{
char *memory = malloc(10);
VALGRIND_PRINTF("Hello, valgrind!\n");
return memory[0];
}
------------------------------------------------------------------------------
Come build with us! The BlackBerry(R) Developer Conference in SF, CA
is the only developer event you need to attend this year. Jumpstart your
developing skills, take BlackBerry mobile applications to market and stay
ahead of the curve. Join us from November 9 - 12, 2009. Register now!
http://p.sf.net/sfu/devconference
_______________________________________________
Valgrind-users mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/valgrind-users