断言在用户空间成功但在内核失败
A assertion succeed in userspace but failed in kernel
我是 linux 内核的新手,我在使用“BUG_ON”时发现了 st运行ge 行为。
这是我在用户空间的示例代码,对 16 位整数进行比较:
#include <stdio.h>
#include <assert.h>
typedef unsigned short digit;
int main(){
#define Bn_SHIFT ((sizeof(digit) << 3) - 1)
#define Bn_MASK ((digit)((1 << Bn_SHIFT) - 1))
digit carry = 3694;
printf("Assert(carry <= Bn_MASK), carry=%d, Bn_MASK=%d ", carry, Bn_MASK);
assert(carry <= Bn_MASK);
#undef Bn_SHIFT
#undef Bn_MASK
return 0;
}
使用以下命令运行良好:
~$ gcc userspace.c -o userspace -O0 -Werror -Wall -g
~$ ./userspace
Assert(carry <= Bn_MASK), carry=3694, Bn_MASK=32767
为了在内核模块中实现上述功能,我 fork kobject-example.c 并用它修改:
--- kobject-example-original.c 2021-05-17 16:02:15.952798660 +0800
+++ kobject-example.c 2021-05-17 14:45:00.851229416 +0800
@@ -10,6 +10,7 @@
#include <linux/sysfs.h>
#include <linux/module.h>
#include <linux/init.h>
+#include <linux/bug.h>
/*
* This module shows how to create a simple subdirectory in sysfs called
@@ -22,12 +23,23 @@
static int baz;
static int bar;
+typedef unsigned short digit;
+
/*
* The "foo" file where a static variable is read from and written to.
*/
static ssize_t foo_show(struct kobject *kobj, struct kobj_attribute *attr,
char *buf)
{
+
+
+#define Bn_SHIFT ((sizeof(digit) << 3) - 1)
+#define Bn_MASK ((digit)((1 << Bn_SHIFT) - 1))
+ digit carry = 3694;
+ printk("BUG_ON(carry <= Bn_MASK), carry=%d, Bn_MASK=%d ", carry, Bn_MASK);
+ BUG_ON(carry <= Bn_MASK);
+#undef Bn_SHIFT
+#undef Bn_MASK
return sprintf(buf, "%d\n", foo);
}
生成文件:
CONFIG_MODULE_SIG = n
TARGET_MODULE := kobject-example
obj-m := $(TARGET_MODULE).o
ccflags-y := -std=gnu99 -Wno-declaration-after-statement -g -O0
KDIR := /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)
all:
$(MAKE) -C $(KDIR) M=$(PWD) modules
然而,当我运行它时,BUG_ON
被触发了。
~$ make && sudo ismod kobject-example.ko
~$ cat /sys/kernel/kobject_example/foo
Segmentation fault
我认为这个问题与整数转换无关,因为carry
的运行k小于Bn_MASK
(32位整数)和carry
比较时会隐式转换为32位整数。
有人可以给我提示吗?
assert
条件为假时失败
BUG_ON
条件为真时失败,参见 https://kernelnewbies.org/FAQ/BUG
你的条件是正确的。
我是 linux 内核的新手,我在使用“BUG_ON”时发现了 st运行ge 行为。
这是我在用户空间的示例代码,对 16 位整数进行比较:
#include <stdio.h>
#include <assert.h>
typedef unsigned short digit;
int main(){
#define Bn_SHIFT ((sizeof(digit) << 3) - 1)
#define Bn_MASK ((digit)((1 << Bn_SHIFT) - 1))
digit carry = 3694;
printf("Assert(carry <= Bn_MASK), carry=%d, Bn_MASK=%d ", carry, Bn_MASK);
assert(carry <= Bn_MASK);
#undef Bn_SHIFT
#undef Bn_MASK
return 0;
}
使用以下命令运行良好:
~$ gcc userspace.c -o userspace -O0 -Werror -Wall -g
~$ ./userspace
Assert(carry <= Bn_MASK), carry=3694, Bn_MASK=32767
为了在内核模块中实现上述功能,我 fork kobject-example.c 并用它修改:
--- kobject-example-original.c 2021-05-17 16:02:15.952798660 +0800
+++ kobject-example.c 2021-05-17 14:45:00.851229416 +0800
@@ -10,6 +10,7 @@
#include <linux/sysfs.h>
#include <linux/module.h>
#include <linux/init.h>
+#include <linux/bug.h>
/*
* This module shows how to create a simple subdirectory in sysfs called
@@ -22,12 +23,23 @@
static int baz;
static int bar;
+typedef unsigned short digit;
+
/*
* The "foo" file where a static variable is read from and written to.
*/
static ssize_t foo_show(struct kobject *kobj, struct kobj_attribute *attr,
char *buf)
{
+
+
+#define Bn_SHIFT ((sizeof(digit) << 3) - 1)
+#define Bn_MASK ((digit)((1 << Bn_SHIFT) - 1))
+ digit carry = 3694;
+ printk("BUG_ON(carry <= Bn_MASK), carry=%d, Bn_MASK=%d ", carry, Bn_MASK);
+ BUG_ON(carry <= Bn_MASK);
+#undef Bn_SHIFT
+#undef Bn_MASK
return sprintf(buf, "%d\n", foo);
}
生成文件:
CONFIG_MODULE_SIG = n
TARGET_MODULE := kobject-example
obj-m := $(TARGET_MODULE).o
ccflags-y := -std=gnu99 -Wno-declaration-after-statement -g -O0
KDIR := /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)
all:
$(MAKE) -C $(KDIR) M=$(PWD) modules
然而,当我运行它时,BUG_ON
被触发了。
~$ make && sudo ismod kobject-example.ko
~$ cat /sys/kernel/kobject_example/foo
Segmentation fault
我认为这个问题与整数转换无关,因为carry
的运行k小于Bn_MASK
(32位整数)和carry
比较时会隐式转换为32位整数。
有人可以给我提示吗?
assert
条件为假时失败
BUG_ON
条件为真时失败,参见 https://kernelnewbies.org/FAQ/BUG
你的条件是正确的。