为什么这段代码效果很好?它改变了常量存储区域字符串;

时间:2015-06-09 07:14:18

标签: linux module kernel constants

这是一个简单的linux内核模块代码来反转一个字符串,它应该在insmod之后进行Oops,但它运行良好,为什么?

#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
static char *words = "words";
static int __init words_init(void)
{
  printk(KERN_INFO "debug info\n");
  int  len = strlen(words);
  int  k;
  for ( k = 0; k < len/2; k++ )
  {
     printk("the value of k %d\n",k);
     char  a = words[k];
     words[k]= words[len-1-k];
     words[len-1-k]=a;        
 }
 printk(KERN_INFO "words is %s\n", words);
 return 0;
}
static void __exit words_exit(void)
{
  printk(KERN_INFO "words exit.\n");
}
module_init(words_init);
module_exit(words_exit);
module_param(words, charp, S_IRUGO);
MODULE_LICENSE("GPL");

2 个答案:

答案 0 :(得分:0)

static!= const

您的示例中的

static表示&#34;仅在当前文件中显示&#34;。见What does "static" mean?

const只是意味着&#34;可以看到此声明的代码不应该更改变量&#34;。但在某些情况下,您仍然可以创建一个指向同一地址的非const指针并修改内容。

Space removal from a String - In Place C style with Pointers建议不应该写入字符串值。

由于static是您的代码与问题代码之间的唯一区别,因此我进一步了解了这一点:Global initialized variables declared as "const" go to text segment, while those declared "Static" go to data segment. Why?

尝试static const char *word,这应该可以解决问题。

答案 1 :(得分:0)

哈哈!我自己从linux内核源代码中得到答案;当你使用insmod时,它将调用init_moudle,load_module,strndup_usr然后调用memdup_usr函数; memdup_usr函数将使用kmalloc_track_caller来分配来自slab的memery和然后使用copy_from_usr将模块paragram复制到内核中;这意味着linux内核模块paragram存储在堆中,而不是在常量存储区域!所以我们可以改变它的内容!