urandom_read.c 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  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. #define _SDT_HAS_SEMAPHORES 1
  11. #include "sdt.h"
  12. #define SEC(name) __attribute__((section(name), used))
  13. #define BUF_SIZE 256
  14. /* defined in urandom_read_aux.c */
  15. void urand_read_without_sema(int iter_num, int iter_cnt, int read_sz);
  16. /* these are coming from urandom_read_lib{1,2}.c */
  17. void urandlib_read_with_sema(int iter_num, int iter_cnt, int read_sz);
  18. void urandlib_read_without_sema(int iter_num, int iter_cnt, int read_sz);
  19. unsigned short urand_read_with_sema_semaphore SEC(".probes");
  20. static __attribute__((noinline))
  21. void urandom_read(int fd, int count)
  22. {
  23. char buf[BUF_SIZE];
  24. int i;
  25. for (i = 0; i < count; ++i) {
  26. read(fd, buf, BUF_SIZE);
  27. /* trigger USDTs defined in executable itself */
  28. urand_read_without_sema(i, count, BUF_SIZE);
  29. STAP_PROBE3(urand, read_with_sema, i, count, BUF_SIZE);
  30. /* trigger USDTs defined in shared lib */
  31. urandlib_read_without_sema(i, count, BUF_SIZE);
  32. urandlib_read_with_sema(i, count, BUF_SIZE);
  33. }
  34. }
  35. static volatile bool parent_ready;
  36. static void handle_sigpipe(int sig)
  37. {
  38. parent_ready = true;
  39. }
  40. int main(int argc, char *argv[])
  41. {
  42. int fd = open("/dev/urandom", O_RDONLY);
  43. int count = 4;
  44. bool report_pid = false;
  45. if (fd < 0)
  46. return 1;
  47. if (argc >= 2)
  48. count = atoi(argv[1]);
  49. if (argc >= 3) {
  50. report_pid = true;
  51. /* install SIGPIPE handler to catch when parent closes their
  52. * end of the pipe (on the other side of our stdout)
  53. */
  54. signal(SIGPIPE, handle_sigpipe);
  55. }
  56. /* report PID and wait for parent process to send us "signal" by
  57. * closing stdout
  58. */
  59. if (report_pid) {
  60. while (!parent_ready) {
  61. fprintf(stdout, "%d\n", getpid());
  62. fflush(stdout);
  63. }
  64. /* at this point stdout is closed, parent process knows our
  65. * PID and is ready to trace us
  66. */
  67. }
  68. urandom_read(fd, count);
  69. close(fd);
  70. return 0;
  71. }