Commit b2c95d90 authored by Josh Triplett's avatar Josh Triplett Committed by Len Brown

turbostat: Clean up error handling; disambiguate error messages; use err and errx

Most of turbostat's error handling consists of printing an error (often
including an errno) and exiting.  Since perror doesn't support a format
string, those error messages are often ambiguous, such as just showing a
file path, which doesn't uniquely identify which call failed.

turbostat already uses _GNU_SOURCE, so switch to the err and errx
functions from err.h, which take a format string.
Signed-off-by: default avatarJosh Triplett <josh@joshtriplett.org>
Signed-off-by: default avatarLen Brown <len.brown@intel.com>
parent 57a42a34
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
#include MSRHEADER #include MSRHEADER
#include <stdarg.h> #include <stdarg.h>
#include <stdio.h> #include <stdio.h>
#include <err.h>
#include <unistd.h> #include <unistd.h>
#include <sys/types.h> #include <sys/types.h>
#include <sys/wait.h> #include <sys/wait.h>
...@@ -624,12 +625,10 @@ delta_thread(struct thread_data *new, struct thread_data *old, ...@@ -624,12 +625,10 @@ delta_thread(struct thread_data *new, struct thread_data *old,
old->tsc = new->tsc - old->tsc; old->tsc = new->tsc - old->tsc;
/* check for TSC < 1 Mcycles over interval */ /* check for TSC < 1 Mcycles over interval */
if (old->tsc < (1000 * 1000)) { if (old->tsc < (1000 * 1000))
fprintf(stderr, "Insanely slow TSC rate, TSC stops in idle?\n"); errx(-3, "Insanely slow TSC rate, TSC stops in idle?\n"
fprintf(stderr, "You can disable all c-states by booting with \"idle=poll\"\n"); "You can disable all c-states by booting with \"idle=poll\"\n"
fprintf(stderr, "or just the deep ones with \"processor.max_cstate=1\"\n"); "or just the deep ones with \"processor.max_cstate=1\"");
exit(-3);
}
old->c1 = new->c1 - old->c1; old->c1 = new->c1 - old->c1;
...@@ -1180,10 +1179,8 @@ void free_all_buffers(void) ...@@ -1180,10 +1179,8 @@ void free_all_buffers(void)
FILE *fopen_or_die(const char *path, const char *mode) FILE *fopen_or_die(const char *path, const char *mode)
{ {
FILE *filep = fopen(path, "r"); FILE *filep = fopen(path, "r");
if (!filep) { if (!filep)
perror(path); err(1, "%s: open failed", path);
exit(1);
}
return filep; return filep;
} }
...@@ -1201,10 +1198,8 @@ int parse_int_file(const char *fmt, ...) ...@@ -1201,10 +1198,8 @@ int parse_int_file(const char *fmt, ...)
vsnprintf(path, sizeof(path), fmt, args); vsnprintf(path, sizeof(path), fmt, args);
va_end(args); va_end(args);
filep = fopen_or_die(path, "r"); filep = fopen_or_die(path, "r");
if (fscanf(filep, "%d", &value) != 1) { if (fscanf(filep, "%d", &value) != 1)
perror(path); err(1, "%s: failed to parse number from file", path);
exit(1);
}
fclose(filep); fclose(filep);
return value; return value;
} }
...@@ -1319,10 +1314,8 @@ int for_all_proc_cpus(int (func)(int)) ...@@ -1319,10 +1314,8 @@ int for_all_proc_cpus(int (func)(int))
fp = fopen_or_die(proc_stat, "r"); fp = fopen_or_die(proc_stat, "r");
retval = fscanf(fp, "cpu %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d\n"); retval = fscanf(fp, "cpu %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d\n");
if (retval != 0) { if (retval != 0)
perror("/proc/stat format"); err(1, "%s: failed to parse format", proc_stat);
exit(1);
}
while (1) { while (1) {
retval = fscanf(fp, "cpu%u %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d\n", &cpu_num); retval = fscanf(fp, "cpu%u %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d\n", &cpu_num);
...@@ -1426,19 +1419,15 @@ void check_dev_msr() ...@@ -1426,19 +1419,15 @@ void check_dev_msr()
{ {
struct stat sb; struct stat sb;
if (stat("/dev/cpu/0/msr", &sb)) { if (stat("/dev/cpu/0/msr", &sb))
fprintf(stderr, "no /dev/cpu/0/msr\n"); err(-5, "no /dev/cpu/0/msr\n"
fprintf(stderr, "Try \"# modprobe msr\"\n"); "Try \"# modprobe msr\"");
exit(-5);
}
} }
void check_super_user() void check_super_user()
{ {
if (getuid() != 0) { if (getuid() != 0)
fprintf(stderr, "must be root\n"); errx(-6, "must be root");
exit(-6);
}
} }
int has_nehalem_turbo_ratio_limit(unsigned int family, unsigned int model) int has_nehalem_turbo_ratio_limit(unsigned int family, unsigned int model)
...@@ -1979,10 +1968,8 @@ void check_cpuid() ...@@ -1979,10 +1968,8 @@ void check_cpuid()
fprintf(stderr, "%d CPUID levels; family:model:stepping 0x%x:%x:%x (%d:%d:%d)\n", fprintf(stderr, "%d CPUID levels; family:model:stepping 0x%x:%x:%x (%d:%d:%d)\n",
max_level, family, model, stepping, family, model, stepping); max_level, family, model, stepping, family, model, stepping);
if (!(edx & (1 << 5))) { if (!(edx & (1 << 5)))
fprintf(stderr, "CPUID: no MSR\n"); errx(1, "CPUID: no MSR");
exit(1);
}
/* /*
* check max extended function levels of CPUID. * check max extended function levels of CPUID.
...@@ -1992,10 +1979,8 @@ void check_cpuid() ...@@ -1992,10 +1979,8 @@ void check_cpuid()
ebx = ecx = edx = 0; ebx = ecx = edx = 0;
__get_cpuid(0x80000000, &max_level, &ebx, &ecx, &edx); __get_cpuid(0x80000000, &max_level, &ebx, &ecx, &edx);
if (max_level < 0x80000007) { if (max_level < 0x80000007)
fprintf(stderr, "CPUID: no invariant TSC (max_level 0x%x)\n", max_level); errx(1, "CPUID: no invariant TSC (max_level 0x%x)", max_level);
exit(1);
}
/* /*
* Non-Stop TSC is advertised by CPUID.EAX=0x80000007: EDX.bit8 * Non-Stop TSC is advertised by CPUID.EAX=0x80000007: EDX.bit8
...@@ -2004,10 +1989,8 @@ void check_cpuid() ...@@ -2004,10 +1989,8 @@ void check_cpuid()
__get_cpuid(0x80000007, &eax, &ebx, &ecx, &edx); __get_cpuid(0x80000007, &eax, &ebx, &ecx, &edx);
has_invariant_tsc = edx & (1 << 8); has_invariant_tsc = edx & (1 << 8);
if (!has_invariant_tsc) { if (!has_invariant_tsc)
fprintf(stderr, "No invariant TSC\n"); errx(1, "No invariant TSC");
exit(1);
}
/* /*
* APERF/MPERF is advertised by CPUID.EAX=0x6: ECX.bit0 * APERF/MPERF is advertised by CPUID.EAX=0x6: ECX.bit0
...@@ -2028,7 +2011,7 @@ void check_cpuid() ...@@ -2028,7 +2011,7 @@ void check_cpuid()
has_epb ? ", EPB": ""); has_epb ? ", EPB": "");
if (!has_aperf) if (!has_aperf)
exit(-1); errx(-1, "No APERF");
do_nehalem_platform_info = genuine_intel && has_invariant_tsc; do_nehalem_platform_info = genuine_intel && has_invariant_tsc;
do_nhm_cstates = genuine_intel; /* all Intel w/ non-stop TSC have NHM counters */ do_nhm_cstates = genuine_intel; /* all Intel w/ non-stop TSC have NHM counters */
...@@ -2048,9 +2031,8 @@ void check_cpuid() ...@@ -2048,9 +2031,8 @@ void check_cpuid()
void usage() void usage()
{ {
fprintf(stderr, "%s: [-v][-R][-T][-p|-P|-S][-c MSR# | -s]][-C MSR#][-m MSR#][-M MSR#][-i interval_sec | command ...]\n", errx(1, "%s: [-v][-R][-T][-p|-P|-S][-c MSR# | -s]][-C MSR#][-m MSR#][-M MSR#][-i interval_sec | command ...]\n",
progname); progname);
exit(1);
} }
...@@ -2093,19 +2075,15 @@ void topology_probe() ...@@ -2093,19 +2075,15 @@ void topology_probe()
fprintf(stderr, "num_cpus %d max_cpu_num %d\n", topo.num_cpus, topo.max_cpu_num); fprintf(stderr, "num_cpus %d max_cpu_num %d\n", topo.num_cpus, topo.max_cpu_num);
cpus = calloc(1, (topo.max_cpu_num + 1) * sizeof(struct cpu_topology)); cpus = calloc(1, (topo.max_cpu_num + 1) * sizeof(struct cpu_topology));
if (cpus == NULL) { if (cpus == NULL)
perror("calloc cpus"); err(1, "calloc cpus");
exit(1);
}
/* /*
* Allocate and initialize cpu_present_set * Allocate and initialize cpu_present_set
*/ */
cpu_present_set = CPU_ALLOC((topo.max_cpu_num + 1)); cpu_present_set = CPU_ALLOC((topo.max_cpu_num + 1));
if (cpu_present_set == NULL) { if (cpu_present_set == NULL)
perror("CPU_ALLOC"); err(3, "CPU_ALLOC");
exit(3);
}
cpu_present_setsize = CPU_ALLOC_SIZE((topo.max_cpu_num + 1)); cpu_present_setsize = CPU_ALLOC_SIZE((topo.max_cpu_num + 1));
CPU_ZERO_S(cpu_present_setsize, cpu_present_set); CPU_ZERO_S(cpu_present_setsize, cpu_present_set);
for_all_proc_cpus(mark_cpu_present); for_all_proc_cpus(mark_cpu_present);
...@@ -2114,10 +2092,8 @@ void topology_probe() ...@@ -2114,10 +2092,8 @@ void topology_probe()
* Allocate and initialize cpu_affinity_set * Allocate and initialize cpu_affinity_set
*/ */
cpu_affinity_set = CPU_ALLOC((topo.max_cpu_num + 1)); cpu_affinity_set = CPU_ALLOC((topo.max_cpu_num + 1));
if (cpu_affinity_set == NULL) { if (cpu_affinity_set == NULL)
perror("CPU_ALLOC"); err(3, "CPU_ALLOC");
exit(3);
}
cpu_affinity_setsize = CPU_ALLOC_SIZE((topo.max_cpu_num + 1)); cpu_affinity_setsize = CPU_ALLOC_SIZE((topo.max_cpu_num + 1));
CPU_ZERO_S(cpu_affinity_setsize, cpu_affinity_set); CPU_ZERO_S(cpu_affinity_setsize, cpu_affinity_set);
...@@ -2201,8 +2177,7 @@ allocate_counters(struct thread_data **t, struct core_data **c, struct pkg_data ...@@ -2201,8 +2177,7 @@ allocate_counters(struct thread_data **t, struct core_data **c, struct pkg_data
return; return;
error: error:
perror("calloc counters"); err(1, "calloc counters");
exit(1);
} }
/* /*
* init_counter() * init_counter()
...@@ -2259,10 +2234,8 @@ void allocate_output_buffer() ...@@ -2259,10 +2234,8 @@ void allocate_output_buffer()
{ {
output_buffer = calloc(1, (1 + topo.num_cpus) * 256); output_buffer = calloc(1, (1 + topo.num_cpus) * 256);
outp = output_buffer; outp = output_buffer;
if (outp == NULL) { if (outp == NULL)
perror("calloc"); err(-1, "calloc output buffer");
exit(-1);
}
} }
void setup_all_buffers(void) void setup_all_buffers(void)
...@@ -2316,17 +2289,13 @@ int fork_it(char **argv) ...@@ -2316,17 +2289,13 @@ int fork_it(char **argv)
} else { } else {
/* parent */ /* parent */
if (child_pid == -1) { if (child_pid == -1)
perror("fork"); err(1, "fork");
exit(1);
}
signal(SIGINT, SIG_IGN); signal(SIGINT, SIG_IGN);
signal(SIGQUIT, SIG_IGN); signal(SIGQUIT, SIG_IGN);
if (waitpid(child_pid, &status, 0) == -1) { if (waitpid(child_pid, &status, 0) == -1)
perror("wait"); err(status, "waitpid");
exit(status);
}
} }
/* /*
* n.b. fork_it() does not check for errors from for_all_cpus() * n.b. fork_it() does not check for errors from for_all_cpus()
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment