int main(int argc, char **argv) { prog_name = argv[0]; int show_the_system_info = 0; int show_the_numastat_info = 0; static struct option long_options[] = { {"help", 0, 0, '?'}, {0, 0, 0, 0} }; int long_option_index = 0; int opt; while ((opt = getopt_long(argc, argv, "cmnp:s::vVz?", long_options, &long_option_index)) != -1) { switch (opt) { case 0: printf("Unexpected long option %s", long_options[long_option_index].name); if (optarg) { printf(" with arg %s", optarg); } printf("\n"); display_usage_and_exit(); break; case 'c': compress_display = 1; break; case 'm': show_the_system_info = 1; break; case 'n': show_the_numastat_info = 1; break; case 'p': if ((optarg) && (all_digits(optarg))) { add_pid_to_list(atoi(optarg)); } else { add_pids_from_pattern_search(optarg); } break; case 's': sort_table = 1; if ((optarg) && (all_digits(optarg))) { sort_table_node = atoi(optarg); } break; case 'v': verbose = 1; break; case 'V': display_version_and_exit(); break; case 'z': show_zero_data = 0; break; default: case '?': display_usage_and_exit(); break; } } // Figure out the display width, which is used to format the tables // and limit the output columns per row screen_width = get_screen_width(); // Any remaining arguments are assumed to be additional process specifiers while (optind < argc) { if (all_digits(argv[optind])) { add_pid_to_list(atoi(argv[optind])); } else { add_pids_from_pattern_search(argv[optind]); } optind += 1; } // If there are no program options or arguments, be extremely compatible // with the old numastat perl script (which is included at the end of this // file for reference) compatibility_mode = (argc == 1); init_node_ix_map_and_header(compatibility_mode); // enumarate the NUMA nodes if (compatibility_mode) { show_numastat_info(); free_node_ix_map_and_header(); exit(EXIT_SUCCESS); } // Figure out page sizes page_size_in_bytes = (double)sysconf(_SC_PAGESIZE); huge_page_size_in_bytes = get_huge_page_size_in_bytes(); // Display the info for the process specifiers if (num_pids > 0) { sort_pids_and_remove_duplicates(); show_process_info(); } if (pid_array != NULL) { free(pid_array); } // Display the system-wide memory usage info if (show_the_system_info) { show_system_info(); } // Display the numastat statistics info if ((show_the_numastat_info) || ((num_pids == 0) && (!show_the_system_info))) { show_numastat_info(); } free_node_ix_map_and_header(); exit(EXIT_SUCCESS); }
static void run_postmortem_debugger (void) { static int calls = 0; static char buf[1024]; int len; if (calls++ == 0) { printk ("====Welcome to kernel panic debugger====\n"); show_panic_debugger_banner(); } printk ("\npanic dbg=>"); len = uart_dppm_rx_line (buf); switch (buf[0]) { case 'd': //dump memory { static unsigned int mem; static unsigned int mem_len; char *p=buf; p++; p=skip_space(p); if(*p==0) break; mem = simple_strtoul(p, &p, 0); p=skip_space(p); if(*p==0) break; mem_len=simple_strtoul(p, 0, 0); mem_len=(mem_len+3)&(~3); //make mem_len four bytes aligned! dump_mem("\nmemory dump",mem,mem+mem_len); break; } case 's': //current process's stack, you can derive the backtrace from the stack { unsigned int cur_sp; __asm__ __volatile__("mov %0,%%sp":"=r"(cur_sp)); printk ("pid=%d\n", current->pid); dump_mem ("Stack: ", cur_sp, 8192 + (unsigned long) current); /* current sp upwards to origin of stack */ dump_mem ("Below stack: ", (unsigned long) current, cur_sp); /* base of tsk upwards to current sp */ break; } case 'm': //show module info, the start address of the module symbol, mainly for backtrace show_module_symbols(); break; case 'p': //show process information show_process_info(); break; case 't': //show process's stack { static int pid; char *p=buf; p++; p=skip_space(p); if(*p==0) break; pid=simple_strtoul(p,0,0); show_process_stack(pid); break; } case 'r': watchdog_force_reset (1); /* fixme... this is PNX0106 specific (maybe should call generic code instead) */ break; case 'a': show_process_stack_all(); break; case '?': //show usage show_panic_debugger_banner(); break; default: break; } }