op_agent_t op_open_agent(void) { char pad_bytes[7] = {0, 0, 0, 0, 0, 0, 0}; int pad_cnt; char dump_path[PATH_MAX]; char err_msg[PATH_MAX + 16]; int rc; struct jitheader header; int fd; struct timeval tv; FILE * dumpfile = NULL; /* Coverity complains about 'time-of-check-time-of-use' race if we do stat() on * a file (or directory) and then open or create it afterwards. So instead, * we'll try to open it and see what happens. */ int create_dir = 0; DIR * dir1 = opendir(TMP_OPROFILE_DIR); if (!dir1) { if (errno == ENOENT) { create_dir = 1; } else if (errno == ENOTDIR) { fprintf(stderr, "Error: Creation of directory %s failed. File exists where directory is expected.\n", TMP_OPROFILE_DIR); return NULL; } } else { closedir(dir1); } if (create_dir) { create_dir = 0; rc = mkdir(TMP_OPROFILE_DIR, S_IRWXU | S_IRWXG | S_IRWXO); if (rc && (errno != EEXIST)) { fprintf(stderr, "Error trying to create %s dir.\n", TMP_OPROFILE_DIR); return NULL; } } dir1 = opendir(JITDUMP_DIR); if (!dir1) { if (errno == ENOENT) { create_dir = 1; } else if (errno == ENOTDIR) { fprintf(stderr, "Error: Creation of directory %s failed. File exists where directory is expected.\n", JITDUMP_DIR); return NULL; } } else { closedir(dir1); } if (create_dir) { rc = mkdir(JITDUMP_DIR, S_IRWXU | S_IRWXG | S_IRWXO); if (rc && (errno != EEXIST)) { fprintf(stderr, "Error trying to create %s dir.\n", JITDUMP_DIR); return NULL; } } snprintf(dump_path, PATH_MAX, "%s/%i.dump", JITDUMP_DIR, getpid()); snprintf(err_msg, PATH_MAX + 16, "Error opening %s\n", dump_path); // make the dump file only accessible for the user for security reason. fd = creat(dump_path, S_IRUSR|S_IWUSR); if (fd == -1) { fprintf(stderr, "%s\n", err_msg); return NULL; } dumpfile = fdopen(fd, "w"); if (!dumpfile) { fprintf(stderr, "%s\n", err_msg); close(fd); return NULL; } if (define_bfd_vars()) { fclose(dumpfile); return NULL; } header.magic = JITHEADER_MAGIC; header.version = JITHEADER_VERSION; header.totalsize = sizeof(header) + strlen(_bfd_target_name) + 1; /* calculate amount of padding '\0' */ pad_cnt = PADDING_8ALIGNED(header.totalsize); header.totalsize += pad_cnt; header.bfd_arch = _bfd_arch; header.bfd_mach = _bfd_mach; if (gettimeofday(&tv, NULL)) { fclose(dumpfile); fprintf(stderr, "gettimeofday failed\n"); return NULL; } header.timestamp = tv.tv_sec; snprintf(err_msg, PATH_MAX + 16, "Error writing to %s", dump_path); if (!fwrite(&header, sizeof(header), 1, dumpfile)) { fclose(dumpfile); fprintf(stderr, "%s\n", err_msg); return NULL; } if (!fwrite(_bfd_target_name, strlen(_bfd_target_name) + 1, 1, dumpfile)) { fclose(dumpfile); fprintf(stderr, "%s\n", err_msg); return NULL; } /* write padding '\0' if necessary */ if (pad_cnt && !fwrite(pad_bytes, pad_cnt, 1, dumpfile)) { fclose(dumpfile); fprintf(stderr, "%s\n", err_msg); return NULL; } fflush(dumpfile); return (op_agent_t)dumpfile; }
op_agent_t op_open_agent(void) { char pad_bytes[7] = {0, 0, 0, 0, 0, 0, 0}; int pad_cnt; char dump_path[PATH_MAX]; char err_msg[PATH_MAX + 16]; struct stat dirstat; int rc; struct jitheader header; int fd; struct timeval tv; FILE * dumpfile = NULL; rc = stat(AGENT_DIR, &dirstat); if (rc || !S_ISDIR(dirstat.st_mode)) { if (!rc) errno = ENOTDIR; fprintf(stderr,"libopagent: Jitdump agent directory %s " "missing\n", AGENT_DIR); fprintf(stderr,"libopagent: do opcontrol --setup or " "opcontrol --reset, first\n"); return NULL; } snprintf(dump_path, PATH_MAX, "%s/%i.dump", AGENT_DIR, getpid()); snprintf(err_msg, PATH_MAX + 16, "Error opening %s\n", dump_path); fd = creat(dump_path, S_IRUSR|S_IWUSR); if (fd == -1) { fprintf(stderr, "%s\n", err_msg); return NULL; } dumpfile = fdopen(fd, "w"); if (!dumpfile) { fprintf(stderr, "%s\n", err_msg); return NULL; } if (define_bfd_vars()) return NULL; header.magic = JITHEADER_MAGIC; header.version = JITHEADER_VERSION; header.totalsize = sizeof(header) + strlen(_bfd_target_name) + 1; pad_cnt = PADDING_8ALIGNED(header.totalsize); header.totalsize += pad_cnt; header.bfd_arch = _bfd_arch; header.bfd_mach = _bfd_mach; if (gettimeofday(&tv, NULL)) { fprintf(stderr, "gettimeofday failed\n"); return NULL; } header.timestamp = tv.tv_sec; snprintf(err_msg, PATH_MAX + 16, "Error writing to %s", dump_path); if (!fwrite(&header, sizeof(header), 1, dumpfile)) { fprintf(stderr, "%s\n", err_msg); return NULL; } if (!fwrite(_bfd_target_name, strlen(_bfd_target_name) + 1, 1, dumpfile)) { fprintf(stderr, "%s\n", err_msg); return NULL; } if (pad_cnt && !fwrite(pad_bytes, pad_cnt, 1, dumpfile)) { fprintf(stderr, "%s\n", err_msg); return NULL; } fflush(dumpfile); return (op_agent_t)dumpfile; }