linux - Linux 内核模块中的字符串操作

标签 linux string kernel-module memset garbage

我在为 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。谢谢——

最佳答案

这里有一些问题:

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

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

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

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


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

关于linux - Linux 内核模块中的字符串操作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4702367/

相关文章:

linux - 如何自动激活海康威视DS-2CD2512F-IS?

c - 过滤器类型未声明?

c - 如何检查2台服务器之间的状态?

linux - 为什么大部分内核镜像在加载后在 RAM 中只有 ~1.5MB?

python - 为什么使用 '==' 或 'is' 比较字符串有时会产生不同的结果?

python - 分隔字符串的最佳 ASCII 字符是什么?

linux - 构建linux内核中syscall_32.tbl、syscall_64.tbl文件的参数

c - 如何在Linux内核5.*中正确拦截系统调用?

linux - bash : Add an option to an existing command

java - 在Java中的字符串中查找第二次出现的子字符串