【问题标题】:String manipulation in Linux kernel moduleLinux内核模块中的字符串操作
【发布时间】:2011-01-15 21:57:47
【问题描述】:

在为 linux 编写模块时,我很难处理字符串。我的问题是我有一个 int Array[10] ,其中有不同的值。我需要生成一个字符串才能发送到 my_read 过程中的缓冲区。如果我的数组是 {0,1,112,20,4,0,0,0,0,0} 那么我的输出应该是:

0:(0)
1:-(1)
2:-------------------------------------------------------------------------------------------------------(112)
3:--------------------(20)
4:----(4)
5:(0)
6:(0)
7:(0)
8:(0)
9:(0)

当我尝试将上述字符串放在 char[] 数组中时,一些奇怪的字符最终会出现在哪里

这里是代码

    int my_read (char *page, char **start, off_t off, int count, int *eof, void *data)
{
 int len;   
 if (off > 0){
  *eof =1;
  return 0;
 }
     /* get process tree */
 int task_dep=0;   /* depth of a task from INIT*/
 get_task_tree(&init_task,task_dep);

 char tmp[1024];

 char A[ProcPerDepth[0]],B[ProcPerDepth[1]],C[ProcPerDepth[2]],D[ProcPerDepth[3]],E[ProcPerDepth[4]],F[ProcPerDepth[5]],G[ProcPerDepth[6]],H[ProcPerDepth[7]],I[ProcPerDepth[8]],J[ProcPerDepth[9]];
 int i=0;
 for (i=0;i<1024;i++){ tmp[i]='\0';}

 memset(A, '\0', sizeof(A));memset(B, '\0', sizeof(B));memset(C, '\0', sizeof(C));
 memset(D, '\0', sizeof(D));memset(E, '\0', sizeof(E));memset(F, '\0', sizeof(F));
 memset(G, '\0', sizeof(G));memset(H, '\0', sizeof(H));memset(I, '\0', sizeof(I));memset(J, '\0', sizeof(J));
 printk("A:%s\nB:%s\nC:%s\nD:%s\nE:%s\nF:%s\nG:%s\nH:%s\nI:%s\nJ:%s\n",A,B,C,D,E,F,G,H,I,J);
 memset(A,'-',sizeof(A));
 memset(B,'-',sizeof(B));
 memset(C,'-',sizeof(C));
 memset(D,'-',sizeof(D));
 memset(E,'-',sizeof(E));
 memset(F,'-',sizeof(F));
 memset(G,'-',sizeof(G));
 memset(H,'-',sizeof(H));
 memset(I,'-',sizeof(I));
 memset(J,'-',sizeof(J));
 printk("A:%s\nB:%s\nC:%s\nD:%s\nE:%s\nF:%s\nG:%s\nH:%s\nI:%s\nJ:%\n",A,B,C,D,E,F,G,H,I,J);


 len = sprintf(page,"0:%s(%d)\n1:%s(%d)\n2:%s(%d)\n3:%s(%d)\n4:%s(%d)\n5:%s(%d)\n6:%s(%d)\n7:%s(%d)\n8:%s(%d)\n9:%s(%d)\n",A,ProcPerDepth[0],B,ProcPerDepth[1],C,ProcPerDepth[2],D,ProcPerDepth[3],E,ProcPerDepth[4],F,ProcPerDepth[5],G,ProcPerDepth[6],H,ProcPerDepth[7],I,ProcPerDepth[8],J,ProcPerDepth[9]);  

 return len;
}

解决了这个问题:

 char s[500];
 memset(s,'-',498); 

 for (i=len=0;i<10;++i){ 
      len+=sprintf(page+len,"%d:%.*s(%d)\n",i,ProcPerDepth[i],s,ProcPerDepth[i]); 
} 

我想知道在 sprintf 中是否有一个简单的标志来乘以字符串 char。谢谢——

【问题讨论】:

    标签: linux string kernel-module memset garbage


    【解决方案1】:

    这里有一些问题:

    1. 您已经用字符完全填充了 A、B、C ... 数组。然后,将它们传递给期望以空字符结尾的字符串的 I/O 例程。因为您的字符串不是以空值结尾的,printk() 将继续打印您的对象之后堆栈内存中的任何内容,直到它幸运地找到空值。

    2. Linux 等多线程内核对堆栈分配有严格且相对较小的限制。内核调用链中的所有实例都必须适合特定大小,否则某些内容将被覆盖。您可能无法检测到此错误,只是某种下游崩溃,因为内存损坏会导致恐慌或楔形。 在内核堆栈上分配大型可变数组并不是一个好主意

    3. 如果您要编写 tmp[] 数组并正确地以 nul 终止它,则没有理由同时对其进行初始化。但是,如果您要初始化它,您可以使用编译器生成的代码来执行此操作,只需说:char tmp[1024] = { 0 };(聚合的部分初始化需要 C99 对整个聚合进行初始化。)类似的观察适用于其他数组.

    4. 如何摆脱大部分数组和大部分代码,并按照以下方式做一些事情:


    for(i = j = 0; i < n; ++i)
        j += sprintf(page + j, "...", ...)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-06-09
      • 2012-04-11
      • 2013-12-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-10-30
      相关资源
      最近更新 更多