2011-01-15 3 views
1

Linux用のモジュールを書くときに文字列を操作するのに苦労しています。私の問題は、配列値が異なるint配列[10]があることです。 my_readプロシージャでバッファに送るために文字列を生成する必要があります。私の配列は{0,1,112,20,4,0,0,0,0,0} であれば、私の出力は次のようになりますLinuxカーネルモジュールの文字列操作

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

Iが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を乗算するのが簡単なフラグがあるのだろうかと思います。ありがとう -

答えて

2

ここではいくつかの問題です:

  1. あなたは完全に文字をA、B、C ...の配列を埋めてきました。次に、それらをヌル終了文字列を必要とするI/Oルーチンに渡します。あなたの文字列はNULLで終了していないので、printk()は、オブジェクトの後ろのスタックメモリにあるものを何でも印刷し続けます。

  2. Linuxのようなマルチスレッドカーネルは、スタック割り当てに関して厳密かつ比較的小さな制約があります。カーネルコールチェーン内のすべてのインスタンスは、特定のサイズに収まる必要があります。何かが上書きされます。このエラーは検出されないかもしれません。メモリ破損がパニックやウェッジにつながるようなダウンストリームクラッシュのようなものです。 カーネルスタックに大規模な変数配列を割り当てることは良い考えではありません。

  3. もしtmp []配列を書き、それを適切にヌル終了するなら、それを初期化する理由はありません。しかし、初期化するつもりならば、コンパイラが生成したコードをchar tmp[1024] = { 0 };とすることができます(集合体の部分初期化では、集合体全体のC99初期化が必要です)。他の配列に対しても同様のことが言えます。

  4. どのようにそれらの配列の大部分を取り除くと、そのコードの大部分だけの線に沿って何かやって得ることについて:


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