kernel/debug/kdb/kdb_main.c

Source file repositories/reference/linux-study-clean/kernel/debug/kdb/kdb_main.c

File Facts

System
Linux kernel
Corpus path
kernel/debug/kdb/kdb_main.c
Extension
.c
Size
67688 bytes
Lines
2812
Domain
Core OS
Bucket
Scheduler, Processes, Timers, Sync, And Syscalls
Inferred role
Core OS: exported/initcall integration point
Status
integration implementation candidate

Why This File Exists

Core operating-system implementation surface: boot, tasks, memory, VFS, syscall-facing interfaces, synchronization, credentials, and isolation.

Dependency Surface

Detected Declarations

Annotated Snippet

struct kdb_macro {
	kdbtab_t cmd;			/* Macro command */
	struct list_head statements;	/* Associated statement list */
};

struct kdb_macro_statement {
	char *statement;		/* Statement text */
	struct list_head list_node;	/* Statement list node */
};

static struct kdb_macro *kdb_macro;
static bool defcmd_in_progress;

/* Forward references */
static int kdb_exec_defcmd(int argc, const char **argv);

static int kdb_defcmd2(const char *cmdstr, const char *argv0)
{
	struct kdb_macro_statement *kms;

	if (!kdb_macro)
		return KDB_NOTIMP;

	if (strcmp(argv0, "endefcmd") == 0) {
		defcmd_in_progress = false;
		if (!list_empty(&kdb_macro->statements))
			kdb_register(&kdb_macro->cmd);
		return 0;
	}

	kms = kmalloc_obj(*kms, GFP_KDB);
	if (!kms) {
		kdb_printf("Could not allocate new kdb macro command: %s\n",
			   cmdstr);
		return KDB_NOTIMP;
	}

	kms->statement = kdb_strdup(cmdstr, GFP_KDB);
	list_add_tail(&kms->list_node, &kdb_macro->statements);

	return 0;
}

static int kdb_defcmd(int argc, const char **argv)
{
	kdbtab_t *mp;

	if (defcmd_in_progress) {
		kdb_printf("kdb: nested defcmd detected, assuming missing "
			   "endefcmd\n");
		kdb_defcmd2("endefcmd", "endefcmd");
	}
	if (argc == 0) {
		kdbtab_t *kp;
		struct kdb_macro *kmp;
		struct kdb_macro_statement *kms;

		list_for_each_entry(kp, &kdb_cmds_head, list_node) {
			if (kp->func == kdb_exec_defcmd) {
				kdb_printf("defcmd %s \"%s\" \"%s\"\n",
					   kp->name, kp->usage, kp->help);
				kmp = container_of(kp, struct kdb_macro, cmd);
				list_for_each_entry(kms, &kmp->statements,
						    list_node)
					kdb_printf("%s", kms->statement);
				kdb_printf("endefcmd\n");
			}
		}
		return 0;
	}
	if (argc != 3)
		return KDB_ARGCOUNT;
	if (in_dbg_master()) {
		kdb_printf("Command only available during kdb_init()\n");
		return KDB_NOTIMP;
	}
	kdb_macro = kzalloc_obj(*kdb_macro, GFP_KDB);
	if (!kdb_macro)
		goto fail_defcmd;

	mp = &kdb_macro->cmd;
	mp->func = kdb_exec_defcmd;
	mp->minlen = 0;
	mp->flags = KDB_ENABLE_ALWAYS_SAFE;
	mp->name = kdb_strdup(argv[1], GFP_KDB);
	if (!mp->name)
		goto fail_name;
	mp->usage = kdb_strdup_dequote(argv[2], GFP_KDB);
	if (!mp->usage)
		goto fail_usage;

Annotation

Implementation Notes