100 lines · c
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 112#include "sdt.h"13 14#define SHARED 115#include "bpf/libbpf_internal.h"16 17#define SEC(name) __attribute__((section(name), used))18 19#define BUF_SIZE 25620 21/* defined in urandom_read_aux.c */22void urand_read_without_sema(int iter_num, int iter_cnt, int read_sz);23/* these are coming from urandom_read_lib{1,2}.c */24void urandlib_read_with_sema(int iter_num, int iter_cnt, int read_sz);25void urandlib_read_without_sema(int iter_num, int iter_cnt, int read_sz);26 27int urandlib_api(void);28COMPAT_VERSION(urandlib_api_old, urandlib_api, LIBURANDOM_READ_1.0.0)29int urandlib_api_old(void);30int urandlib_api_sameoffset(void);31 32unsigned short urand_read_with_sema_semaphore SEC(".probes");33 34static 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 52static volatile bool parent_ready;53 54static void handle_sigpipe(int sig)55{56 parent_ready = true;57}58 59int 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 their73 * 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" by79 * closing stdout80 */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 our87 * PID and is ready to trace us88 */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