Back to home page

OSCL-LXR

 
 

    


0001 #include <stdbool.h>
0002 #include <stdio.h>
0003 #include <unistd.h>
0004 #include <errno.h>
0005 #include <sys/types.h>
0006 #include <sys/stat.h>
0007 #include <fcntl.h>
0008 #include <stdlib.h>
0009 #include <signal.h>
0010 
0011 #define _SDT_HAS_SEMAPHORES 1
0012 #include "sdt.h"
0013 
0014 #define SEC(name) __attribute__((section(name), used))
0015 
0016 #define BUF_SIZE 256
0017 
0018 /* defined in urandom_read_aux.c */
0019 void urand_read_without_sema(int iter_num, int iter_cnt, int read_sz);
0020 /* these are coming from urandom_read_lib{1,2}.c */
0021 void urandlib_read_with_sema(int iter_num, int iter_cnt, int read_sz);
0022 void urandlib_read_without_sema(int iter_num, int iter_cnt, int read_sz);
0023 
0024 unsigned short urand_read_with_sema_semaphore SEC(".probes");
0025 
0026 static __attribute__((noinline))
0027 void urandom_read(int fd, int count)
0028 {
0029     char buf[BUF_SIZE];
0030     int i;
0031 
0032     for (i = 0; i < count; ++i) {
0033         read(fd, buf, BUF_SIZE);
0034 
0035         /* trigger USDTs defined in executable itself */
0036         urand_read_without_sema(i, count, BUF_SIZE);
0037         STAP_PROBE3(urand, read_with_sema, i, count, BUF_SIZE);
0038 
0039         /* trigger USDTs defined in shared lib */
0040         urandlib_read_without_sema(i, count, BUF_SIZE);
0041         urandlib_read_with_sema(i, count, BUF_SIZE);
0042     }
0043 }
0044 
0045 static volatile bool parent_ready;
0046 
0047 static void handle_sigpipe(int sig)
0048 {
0049     parent_ready = true;
0050 }
0051 
0052 int main(int argc, char *argv[])
0053 {
0054     int fd = open("/dev/urandom", O_RDONLY);
0055     int count = 4;
0056     bool report_pid = false;
0057 
0058     if (fd < 0)
0059         return 1;
0060 
0061     if (argc >= 2)
0062         count = atoi(argv[1]);
0063     if (argc >= 3) {
0064         report_pid = true;
0065         /* install SIGPIPE handler to catch when parent closes their
0066          * end of the pipe (on the other side of our stdout)
0067          */
0068         signal(SIGPIPE, handle_sigpipe);
0069     }
0070 
0071     /* report PID and wait for parent process to send us "signal" by
0072      * closing stdout
0073      */
0074     if (report_pid) {
0075         while (!parent_ready) {
0076             fprintf(stdout, "%d\n", getpid());
0077             fflush(stdout);
0078         }
0079         /* at this point stdout is closed, parent process knows our
0080          * PID and is ready to trace us
0081          */
0082     }
0083 
0084     urandom_read(fd, count);
0085 
0086     close(fd);
0087     return 0;
0088 }