Segmentation fault occurs with --calibrate
Lekensteyn
Hi,
With the new Powertop 2.0, powertop --calibrate segfaults. Debugging output is attached:
Quoted 16 lines
Starting program:
/tmp/powertop-2.0/src/powertop--calibrate [Thread debugging usinglibthread_dbenabled]
Using hostlibthread_dblibrary "/lib/x86_64-linux-gnu/libthread_db.so.1". Starting PowerTOP power estimate calibration
Calibrating idleProgram received signal SIGSEGV, Segmentation fault.
perf_bundle::start(this=0x0) at perf/perf_bundle.cpp:180
180 for (i = 0; i <events.size(); i++) {
(gdb) bt#0 perf_bundle::start (this=0x0) at perf/perf_bundle.cpp:180 #1 0x000000000040f9b0 in start_cpu_measurement () at cpu/cpu.cpp:297 #2 0x0000000000442655 in one_measurement (seconds=15) at main.cpp:182 #3 0x000000000043f4c2 in idle_calibration () at calibrate/calibrate.cpp:423 #4 calibrate () at calibrate/calibrate.cpp:466 #5 0x000000000040665f in main (argc=2, argv=0x7fffffffe718) at main.cpp:325
Quoted 5 lines
(gdb) up
#10x000000000040f9b0instart_cpu_measurement() at cpu/cpu.cpp:297
297perf_events->start()
(gdb) printperf_events
$5 = (perf_bundle*)0x0
The order of processing seems flawed. Immediately during argument processing, calibrate() is called. But start_cpu_measurement requires some initialization which is done by enumerate_cpus() in the main() function after arguments processing. You know your code better, so I'll gratefully wait for your patches.
Thanks,
Peter
Sergey Senozhatsky
PATCH 1/1 factor out powertop_init() function [was "Segmentation fault occurs with --calibrate"]
[PATCH] factor out powertop_init() function
Factor out powertop_init() function to perform basic initialization on powertop start up.
Commit 057d6126eb6329c86b29a2e0219c0d0e49a84191 moved init after commandline options parsing. However, in some cases we need it before parsing, e.g. -- calibration.
---
src/main.cpp | 110 +++++++++++++++++++++++++++++++--------------------------- 1 file changed, 58 insertions(+), 52 deletions(-)
src/main.cpp +58 -52
@@ -280,15 +280,68 @@ static void checkroot() { } } -int main(int argc, char **argv) + +static void powertop_init(void) { + static char initialized = 0; int ret; + struct statfs st_fs; + + if (initialized) + return; + + checkroot(); + ret = system("/sbin/modprobe cpufreq_stats > /dev/null 2>&1"); + ret = system("/sbin/modprobe msr > /dev/null 2>&1"); + statfs("/sys/kernel/debug", &st_fs); + + if (st_fs.f_type != (long) DEBUGFS_MAGIC) { + if (access("/bin/mount", X_OK) == 0) { + ret = system("/bin/mount -t debugfs debugfs /sys/kernel/debug > /dev/null 2>&1"); + } else { + ret = system("mount -t debugfs debugfs /sys/kernel/debug > /dev/null 2>&1"); + } + if (ret != 0) { + printf(_("Failed to mount debugfs!\n")); + printf(_("exiting...\n")); + exit(EXIT_FAILURE); + } + } + + srand(time(NULL)); + + if (access("/var/cache/", W_OK) == 0) + mkdir("/var/cache/powertop", 0600); + else + mkdir("/data/local/powertop", 0600); + + load_results("saved_results.powertop"); + load_parameters("saved_parameters.powertop"); + + enumerate_cpus(); + create_all_devices(); + detect_power_meters(); + + register_parameter("base power", 100, 0.5); + register_parameter("cpu-wakeups", 39.5); + register_parameter("cpu-consumption", 1.56); + register_parameter("gpu-operations", 0.5576); + register_parameter("disk-operations-hard", 0.2); + register_parameter("disk-operations", 0.0); + register_parameter("xwakes", 0.1); + + load_board_params(); + initialized = 1; +} + + +int main(int argc, char **argv) +{ int option_index; int c; bool wantreport = FALSE; char filename[4096]; int iterations = 1; - struct statfs st_fs; #ifndef DISABLE_TRYCATCH set_new_handler(out_of_memory);
@@ -322,6 +375,7 @@ int main(int argc, char **argv) break; case 'c': + powertop_init(); calibrate(); break;
@@ -350,48 +404,8 @@ int main(int argc, char **argv) break; } } - - checkroot(); - ret = system("/sbin/modprobe cpufreq_stats > /dev/null 2>&1"); - ret = system("/sbin/modprobe msr > /dev/null 2>&1"); - - statfs("/sys/kernel/debug", &st_fs); - if (st_fs.f_type != (long) DEBUGFS_MAGIC) { - if (access("/bin/mount", X_OK) == 0) { - ret = system("/bin/mount -t debugfs debugfs /sys/kernel/debug > /dev/null 2>&1"); - } else { - ret = system("mount -t debugfs debugfs /sys/kernel/debug > /dev/null 2>&1"); - } - if (ret != 0) { - printf(_("Failed to mount debugfs!\n")); - printf(_("exiting...\n")); - exit(EXIT_FAILURE); - } - } - - srand(time(NULL)); - - if (access("/var/cache/", W_OK) == 0) - mkdir("/var/cache/powertop", 0600); - else - mkdir("/data/local/powertop", 0600); - load_results("saved_results.powertop"); - load_parameters("saved_parameters.powertop"); - - enumerate_cpus(); - create_all_devices(); - detect_power_meters(); - - register_parameter("base power", 100, 0.5); - register_parameter("cpu-wakeups", 39.5); - register_parameter("cpu-consumption", 1.56); - register_parameter("gpu-operations", 0.5576); - register_parameter("disk-operations-hard", 0.2); - register_parameter("disk-operations", 0.0); - register_parameter("xwakes", 0.1); - - load_board_params(); + powertop_init(); if (wantreport) report(time_out, iterations, filename);
@@ -399,8 +413,6 @@ int main(int argc, char **argv) if (debug_learning) printf("Learning debugging enabled\n"); - - learn_parameters(250, 0); save_parameters("saved_parameters.powertop");
@@ -412,7 +424,6 @@ int main(int argc, char **argv) exit(0); } - /* first one is short to not let the user wait too long */ init_display(); one_measurement(1);
@@ -420,11 +431,9 @@ int main(int argc, char **argv) tuning_update_display(); show_tab(0); - - while (!leave_powertop) { - one_measurement(time_out); show_cur_tab(); + one_measurement(time_out); learn_parameters(15, 0); } #ifndef DISABLE_NCURSES
@@ -432,7 +441,6 @@ int main(int argc, char **argv) #endif printf(_("Leaving PowerTOP\n")); - end_process_data(); clear_process_data(); end_cpu_data();
@@ -450,6 +458,4 @@ int main(int argc, char **argv) clear_all_cpus(); return 0; - - }