#!/bin/probevue /* Problem: The "long" problem Description: probevue fails with the following message: Probevue session has been aborted 0x00000000962840fe when __arg3 is accessed in read:entry Things I have tried: - Use different name for local (automatic) variable: Fails. - Use different prototype for read(): Fails. - Use global for size: Fails. - Use unsigned long long for size: Fails. - printf() __arg3 directly: Fails. - trace() __arg3 directly: Type mismatch / fails (differently). - copy_userdata() on __arg3: Argument type mismatch / fails (differently). - Change data type in prototype to unsigned int: Fixed. Of note: - shmget() fails with the same error on the same data type. - Kernel is 64 - Binary (I am watching) is 32 - The long data type should be 64 bit (8 bytes) if declared global. I am seeing long globals as 4 byte values (provided I can trust sizeof()). This may not be a bug, but it is contrary to page 26 of the "Extended Users Guide Specification for ProbeVue". - All data types (according to sizeof()) that are used here are 4 bytes, yet I still see a difference when declaring (prototyping) the read() syscall as unsigned int or unsigned long. - sizeof(__arg3) in read:entry probe succeeds regardless of the type. It is when __arg3 is copied to a local variable (size = __arg3;) or when it is passed to a function (like printf()) that the probevue session dies with the above error. */ /* int read(int fd, char *buf, unsigned long size); */ int read(int fd, char *buf, unsigned int size); /* Right here is fix! */ int write(int fd, char *buf, unsigned long size); unsigned long gul; unsigned int gui; @@BEGIN { /* 32 64 actual */ printf("unsigned long = %d\n", sizeof(unsigned long)); /* 4 8 4 */ printf("unsigned int = %d\n", sizeof(unsigned int)); /* 4 4 4 */ printf("global unsigned long = %d\n", sizeof(gul)); /* 8 8 4 */ printf("global unsigned int = %d\n", sizeof(gui)); /* 4 4 4 */ /* ^ ^ */ /* | | */ /* See p26 of EUG */ } @@syscall:*:read:entry when( __pid == $1 ) { int fd; unsigned int size; fd = __arg1; size = __arg3; /* Right here is where we fail! */ /* size = 0; Used for debuggery */ /* This prints all 4s - despite the prototype for the function (meaning: It does not matter if __arg3 is either unsigned int or unsigned long). printf("[%d %d %d %d %d %d] ", sizeof(unsigned long), sizeof(unsigned int), sizeof(gul), sizeof(gui), sizeof(size), sizeof(__arg3)); */ printf("read(%d, -,%lu) ", fd, size); } @@syscall:*:read:exit when( __pid == $1 ) { int rv; rv = __rv; trace(rv); }