1 #include <stdbool.h> 2 #include <stdio.h> 3 #include <unistd.h> 4 #include <errno.h> 5 #include <sys/types.h> 6 #include <sys/stat.h> 7 #include <fcntl.h> 8 #include <stdlib.h> 9 #include <signal.h> 10 11 #define _SDT_HAS_SEMAPHORES 1 12 #include "sdt.h" 13 14 #define SHARED 1 15 #include "bpf/libbpf_internal.h" 16 17 #define SEC(name) __attribute__((section(name), used)) 18 19 #define BUF_SIZE 256 20 21 /* defined in urandom_read_aux.c */ 22 void urand_read_without_sema(int iter_num, int iter_cnt, int read_sz); 23 /* these are coming from urandom_read_lib{1,2}.c */ 24 void urandlib_read_with_sema(int iter_num, int iter_cnt, int read_sz); 25 void urandlib_read_without_sema(int iter_num, int iter_cnt, int read_sz); 26 27 int urandlib_api(void); 28 COMPAT_VERSION(urandlib_api_old, urandlib_api, LIBURANDOM_READ_1.0.0) 29 int urandlib_api_old(void); 30 int urandlib_api_sameoffset(void); 31 32 unsigned short urand_read_with_sema_semaphore SEC(".probes"); 33 34 static noinline void urandom_read(int fd, int count) 35 { 36 char buf[BUF_SIZE]; 37 int i; 38 39 for (i = 0; i < count; ++i) { 40 read(fd, buf, BUF_SIZE); 41 42 /* trigger USDTs defined in executable itself */ 43 urand_read_without_sema(i, count, BUF_SIZE); 44 STAP_PROBE3(urand, read_with_sema, i, count, BUF_SIZE); 45 46 /* trigger USDTs defined in shared lib */ 47 urandlib_read_without_sema(i, count, BUF_SIZE); 48 urandlib_read_with_sema(i, count, BUF_SIZE); 49 } 50 } 51 52 static volatile bool parent_ready; 53 54 static void handle_sigpipe(int sig) 55 { 56 parent_ready = true; 57 } 58 59 int main(int argc, char *argv[]) 60 { 61 int fd = open("/dev/urandom", O_RDONLY); 62 int count = 4; 63 bool report_pid = false; 64 65 if (fd < 0) 66 return 1; 67 68 if (argc >= 2) 69 count = atoi(argv[1]); 70 if (argc >= 3) { 71 report_pid = true; 72 /* install SIGPIPE handler to catch when parent closes their 73 * end of the pipe (on the other side of our stdout) 74 */ 75 signal(SIGPIPE, handle_sigpipe); 76 } 77 78 /* report PID and wait for parent process to send us "signal" by 79 * closing stdout 80 */ 81 if (report_pid) { 82 while (!parent_ready) { 83 fprintf(stdout, "%d\n", getpid()); 84 fflush(stdout); 85 } 86 /* at this point stdout is closed, parent process knows our 87 * PID and is ready to trace us 88 */ 89 } 90 91 urandom_read(fd, count); 92 93 urandlib_api(); 94 urandlib_api_old(); 95 urandlib_api_sameoffset(); 96 97 close(fd); 98 return 0; 99 } 100