Ejemplo n.º 1
0
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;
	}
}