uboot自定义命令造成自定义命令后其他命令执行出现data abort
问题现象
添加自定义命令后,自定义命令可以正常运行,但是之后的命令和tab补全都会出现data abort
直接原因
command.h和common.h未按顺序进行引用导致U_BOOT_CMD宏中的NULL被错误定义
#define U_BOOT_CMD(_name, _maxargs, _rep, _cmd, _usage, _help) \
U_BOOT_CMD_COMPLETE(_name, _maxargs, _rep, _cmd, _usage, _help, NULL)
- 错误方式:
- 正确方式
为什么会产生顺序问题
可以看到,common.h和command.h都会应用stddef.h
由此得到,当command.h在前时
- command.h内设置NULL为0,stddef.h内_LINUX_STDDEF_H被定义
- 到common.h引入时,_LINUX_STDDEF_H已被定义,无法将NULL定义为(void*)0
为什么出现data abort
struct cmd_tbl_s {
char *name; /* Command Name */
int maxargs; /* maximum number of arguments */
int repeatable; /* autorepeat allowed? */
/* Implementation function */
int (*cmd)(struct cmd_tbl_s *, int, int, char * const []);
char *usage; /* Usage message (short) */
char *help; /* Help message (long) */
/* do auto completion on the arguments */
int (*complete)(int argc, char * const argv[], char last_char, int maxv, char *cmdv[]);
};
U_BOOT_CMD宏服务于这个结构体,作为命令表的一行。
complete是个函数指针,但是NULL错误的定义会导致0直接被传给complete而不是(void*)0。进而在后续使用中出现异常的指针访问。
PS:可自行搜索 C语言中0与空指针;以及在CPP中 0与空指针,应该就可以理解了。