⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 core-lite.patch

📁 Linux-2.6.18内核调试工具补丁程序KGDB。
💻 PATCH
📖 第 1 页 / 共 5 页
字号:
+				shadowregs = kgdb_shadow_regs(linux_regs,+							      kgdb_usethreadid -+							      pid_max -+							      num_online_cpus+							      ());+				if (!shadowregs) {+					error_packet(remcom_out_buffer,+						     -EINVAL);+					break;+				}+				regs_to_gdb_regs(gdb_regs, shadowregs);+			} else if (local_debuggerinfo)+				regs_to_gdb_regs(gdb_regs, local_debuggerinfo);+			else {+				/* Pull stuff saved during+				 * switch_to; nothing else is+				 * accessible (or even particularly relevant).+				 * This should be enough for a stack trace. */+				sleeping_thread_to_gdb_regs(gdb_regs, thread);+			}+			kgdb_mem2hex((char *)gdb_regs, remcom_out_buffer,+				     NUMREGBYTES);+			break;++			/* set the value of the CPU registers - return OK */+		case 'G':+			kgdb_hex2mem(&remcom_in_buffer[1], (char *)gdb_regs,+				     NUMREGBYTES);++			if (kgdb_usethread && kgdb_usethread != current)+				error_packet(remcom_out_buffer, -EINVAL);+			else {+				gdb_regs_to_regs(gdb_regs, linux_regs);+				strcpy(remcom_out_buffer, "OK");+			}+			break;++			/* mAA..AA,LLLL  Read LLLL bytes at address AA..AA */+		case 'm':+			ptr = &remcom_in_buffer[1];+			if (kgdb_hex2long(&ptr, &addr) > 0 && *ptr++ == ',' &&+			    kgdb_hex2long(&ptr, &length) > 0) {+				if (IS_ERR(ptr = kgdb_mem2hex((char *)addr,+							      remcom_out_buffer,+							      length)))+					error_packet(remcom_out_buffer,+						     PTR_ERR(ptr));+			} else+				error_packet(remcom_out_buffer, -EINVAL);+			break;++			/* MAA..AA,LLLL: Write LLLL bytes at address AA..AA */+		case 'M':+			if (IS_ERR(ptr = write_mem_msg(0)))+				error_packet(remcom_out_buffer, PTR_ERR(ptr));+			else+				strcpy(remcom_out_buffer, "OK");+			break;+			/* XAA..AA,LLLL: Write LLLL bytes at address AA..AA */+		case 'X':+			if (IS_ERR(ptr = write_mem_msg(1)))+				error_packet(remcom_out_buffer, PTR_ERR(ptr));+			else+				strcpy(remcom_out_buffer, "OK");+			break;++			/* kill or detach. KGDB should treat this like a+			 * continue.+			 */+		case 'D':+			if ((error = remove_all_break()) < 0) {+				error_packet(remcom_out_buffer, error);+			} else {+				strcpy(remcom_out_buffer, "OK");+				kgdb_connected = 0;+			}+			put_packet(remcom_out_buffer);+			goto default_handle;++		case 'k':+			/* Don't care about error from remove_all_break */+			remove_all_break();+			kgdb_connected = 0;+			goto default_handle;++			/* Reboot */+		case 'R':+			/* For now, only honor R0 */+			if (strcmp(remcom_in_buffer, "R0") == 0) {+				printk(KERN_CRIT "Executing reboot\n");+				strcpy(remcom_out_buffer, "OK");+				put_packet(remcom_out_buffer);+				emergency_sync();+				/* Execution should not return from+				 * machine_restart()+				 */+				machine_restart(NULL);+				kgdb_connected = 0;+				goto default_handle;+			}++			/* query */+		case 'q':+			switch (remcom_in_buffer[1]) {+			case 's':+			case 'f':+				if (memcmp(remcom_in_buffer + 2, "ThreadInfo",+					   10)) {+					error_packet(remcom_out_buffer,+						     -EINVAL);+					break;+				}++				/*+				 * If we have not yet completed in+				 * pidhash_init() there isn't much we+				 * can give back.+				 */+				if (!pidhash_init_done) {+					if (remcom_in_buffer[1] == 'f')+						strcpy(remcom_out_buffer,+						       "m0000000000000001");+					break;+				}++				if (remcom_in_buffer[1] == 'f') {+					threadid = 1;+				}+				remcom_out_buffer[0] = 'm';+				ptr = remcom_out_buffer + 1;+				for (i = 0; i < 17 && threadid < pid_max ++				     numshadowth; threadid++) {+					thread = getthread(linux_regs,+							   threadid);+					if (thread) {+						int_to_threadref(&thref,+								 threadid);+						pack_threadid(ptr, &thref);+						ptr += 16;+						*(ptr++) = ',';+						i++;+					}+				}+				*(--ptr) = '\0';+				break;++			case 'C':+				/* Current thread id */+				strcpy(remcom_out_buffer, "QC");++				threadid = shadow_pid(current->pid);++				int_to_threadref(&thref, threadid);+				pack_threadid(remcom_out_buffer + 2, &thref);+				break;+			case 'T':+				if (memcmp(remcom_in_buffer + 1,+					   "ThreadExtraInfo,", 16)) {+					error_packet(remcom_out_buffer,+						     -EINVAL);+					break;+				}+				threadid = 0;+				ptr = remcom_in_buffer + 17;+				kgdb_hex2long(&ptr, &threadid);+				if (!getthread(linux_regs, threadid)) {+					error_packet(remcom_out_buffer,+						     -EINVAL);+					break;+				}+				if (threadid < pid_max) {+					kgdb_mem2hex(getthread(linux_regs,+							       threadid)->comm,+						     remcom_out_buffer, 16);+				} else if (threadid >= pid_max ++					   num_online_cpus()) {+					kgdb_shadowinfo(linux_regs,+							remcom_out_buffer,+							threadid - pid_max -+							num_online_cpus());+				} else {+					static char tmpstr[23 ++							   BUF_THREAD_ID_SIZE];+					sprintf(tmpstr, "Shadow task %d"+						" for pid 0",+						(int)(threadid - pid_max));+					kgdb_mem2hex(tmpstr, remcom_out_buffer,+						     strlen(tmpstr));+				}+				break;+			}+			break;++			/* task related */+		case 'H':+			switch (remcom_in_buffer[1]) {+			case 'g':+				ptr = &remcom_in_buffer[2];+				kgdb_hex2long(&ptr, &threadid);+				thread = getthread(linux_regs, threadid);+				if (!thread && threadid > 0) {+					error_packet(remcom_out_buffer,+						     -EINVAL);+					break;+				}+				kgdb_usethread = thread;+				kgdb_usethreadid = threadid;+				strcpy(remcom_out_buffer, "OK");+				break;++			case 'c':+				ptr = &remcom_in_buffer[2];+				kgdb_hex2long(&ptr, &threadid);+				if (!threadid) {+					kgdb_contthread = NULL;+				} else {+					thread = getthread(linux_regs,+							   threadid);+					if (!thread && threadid > 0) {+						error_packet(remcom_out_buffer,+							     -EINVAL);+						break;+					}+					kgdb_contthread = thread;+				}+				strcpy(remcom_out_buffer, "OK");+				break;+			}+			break;++			/* Query thread status */+		case 'T':+			ptr = &remcom_in_buffer[1];+			kgdb_hex2long(&ptr, &threadid);+			thread = getthread(linux_regs, threadid);+			if (thread)+				strcpy(remcom_out_buffer, "OK");+			else+				error_packet(remcom_out_buffer, -EINVAL);+			break;+		/* Since GDB-5.3, it's been drafted that '0' is a software+		 * breakpoint, '1' is a hardware breakpoint, so let's do+		 * that.+		 */+		case 'z':+		case 'Z':+			bpt_type = &remcom_in_buffer[1];+			ptr = &remcom_in_buffer[2];++			if (kgdb_ops->set_hw_breakpoint && *bpt_type >= '1') {+				/* Unsupported */+				if (*bpt_type > '4')+					break;+			} else if (*bpt_type != '0' && *bpt_type != '1')+				/* Unsupported. */+				break;+			/* Test if this is a hardware breakpoint, and+			 * if we support it. */+			if (*bpt_type == '1' &&+			    !kgdb_ops->flags & KGDB_HW_BREAKPOINT)+				/* Unsupported. */+				break;++			if (*(ptr++) != ',') {+				error_packet(remcom_out_buffer, -EINVAL);+				break;+			} else if (kgdb_hex2long(&ptr, &addr)) {+				if (*(ptr++) != ',' ||+				    !kgdb_hex2long(&ptr, &length)) {+					error_packet(remcom_out_buffer,+						     -EINVAL);+					break;+				}+			} else {+				error_packet(remcom_out_buffer, -EINVAL);+				break;+			}++			if (remcom_in_buffer[0] == 'Z' && *bpt_type == '0')+				error = kgdb_set_sw_break(addr);+			else if (remcom_in_buffer[0] == 'Z' && *bpt_type == '1')+				error = kgdb_set_hw_break(addr);+			else if (remcom_in_buffer[0] == 'z' && *bpt_type == '0')+				error = kgdb_remove_sw_break(addr);+			else if (remcom_in_buffer[0] == 'z' && *bpt_type == '1')+				error = kgdb_remove_hw_break(addr);+			else if (remcom_in_buffer[0] == 'Z')+				error = kgdb_ops->set_hw_breakpoint(addr,+								    (int)length,+								    *bpt_type);+			else if (remcom_in_buffer[0] == 'z')+				error = kgdb_ops->remove_hw_breakpoint(addr,+								       (int)+								       length,+								       *bpt_type);++			if (error == 0)+				strcpy(remcom_out_buffer, "OK");+			else+				error_packet(remcom_out_buffer, error);++			break;+		case 'c':+		case 's':+			if (kgdb_contthread && kgdb_contthread != current) {+				/* Can't switch threads in kgdb */+				error_packet(remcom_out_buffer, -EINVAL);+				break;+			}+			kgdb_activate_sw_breakpoints();+			/* Followthrough to default processing */+		default:+		      default_handle:+			error = kgdb_arch_handle_exception(ex_vector, signo,+							   err_code,+							   remcom_in_buffer,+							   remcom_out_buffer,+							   linux_regs);++			if (error >= 0 || remcom_in_buffer[0] == 'D' ||+			    remcom_in_buffer[0] == 'k')+				goto kgdb_exit;++		}		/* switch */++		/* reply to the request */+		put_packet(remcom_out_buffer);+	}++      kgdb_exit:+	/* Call the I/O driver's post_exception routine if the I/O+	 * driver defined one.+	 */+	if (kgdb_io_ops.post_exception)+		kgdb_io_ops.post_exception();++	kgdb_info[processor].debuggerinfo = NULL;+	kgdb_info[processor].task = NULL;+	atomic_set(&procindebug[processor], 0);++	if (!debugger_step || !kgdb_contthread) {+		for (i = 0; i < NR_CPUS; i++)+			spin_unlock(&slavecpulocks[i]);+		/* Wait till all the processors have quit+		 * from the debugger. */+		for (i = 0; i < NR_CPUS; i++) {+			while (atomic_read(&procindebug[i])) {+				int j = 10;	/* an arbitrary number */++				while (--j)+					cpu_relax();+			}+		}+	}++#ifdef CONFIG_SMP+	/* This delay has a real purpose.  The problem is that if you+	 * are single-stepping, you are sending an NMI to all the+	 * other processors to stop them.  Interrupts come in, but+	 * don't get handled.  Then you let them go just long enough+	 * to get into their interrupt routines and use up some stack.+	 * You stop them again, and then do the same thing.  After a+	 * while you blow the stack on the other processors.  This+	 * delay gives some time for interrupts to be cleared out on+	 * the other processors.+	 */+	if (debugger_step)+		mdelay(2);+#endif+kgdb_restore:+	/* Free debugger_active */+	atomic_set(&debugger_active, 0);+	local_irq_restore(flags);++	return error;+}++/*+ * GDB places a breakpoint at this function to know dynamically+ * loaded objects. It's not defined static so that only one instance with this+ * name exists in the kernel.+ */++int module_event(struct notifier_block *self, unsigned long val, void *data)+{+	return 0;+}++static struct notifier_block kgdb_module_load_nb = {+	.notifier_call = module_event,+};++void kgdb_nmihook(int cpu, void *regs)+{+#ifdef CONFIG_SMP+	if (!atomic_read(&procindebug[cpu]) && atomic_read(&debugger_active) != (cpu + 1))+		kgdb_wait((struct pt_regs *)regs);+#endif+}++/*+ * This is called when a panic happens.  All we need to do is+ * breakpoint().+ */+static int kgdb_panic_notify(struct notifier_block *self, unsigned long cmd,+			     void *ptr)+{+	breakpoint();++	return 0;+}++static struct notifier_block kgdb_panic_notifier = {+	.notifier_call = kgdb_panic_notify,+};++/*+ * Initialization that needs to be done in either of our entry points.+ */+static void __init kgdb_internal_init(void)+{+	int i;++	/* Initialize our spinlocks. */+	for (i = 0; i < NR_CPUS; i++)+		spin_lock_init(&slavecpulocks[i]);++	for (i = 0; i < MAX_BREAKPOINTS; i++)+		kgdb_break[i].state = bp_none;++	/* Initialize the I/O handles */+	memset(&kgdb_io_ops_prev, 0, sizeof(kgdb_io_ops_prev));++	/* We can't do much if this fails */+	register_module_notifier(&kgdb_module_load_nb);++	kgdb_initialized = 1;+

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -