2011-01-15 9 views
1

Ich habe eine harte Zeit in der Manipulation von Strings beim Schreiben von Modulen für Linux. Mein Problem ist, dass ich ein int Array [10] mit verschiedenen Werten habe. Ich muss eine Zeichenfolge erzeugen, um in der my_read-Prozedur an den Puffer senden zu können. Wenn mein Array {0,1,112,20,4,0,0,0,0,0} dann sollte mein ausgegeben:String-Manipulation im Linux-Kernel-Modul

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

wenn ich versuche, die oben genannten Strings in char [] Arrays zu platzieren einige, wie seltsam Zeichen dort am Ende

hier der Code

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; 
} 

es mit diesem ausgearbeitet ist:

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]); 
} 

I frage mich, ob es ein einfaches Flag gibt, um Zeichenketten im Sprint zu multiplizieren. Thanx -

Antwort

2

Hier sind ein paar Probleme:

  1. Sie haben die A vollständig gefüllt, B, C ... Arrays mit Zeichen. Dann übergeben Sie sie an eine E/A-Routine, die nullterminierte Zeichenfolgen erwartet. Da Ihre Zeichenfolgen nicht null-terminiert sind, druckt printk() weiter, was sich im Stapelspeicher nach Ihrem Objekt befindet, bis es durch Zufall eine Null findet.

  2. Multithread-Kernel wie Linux haben strenge und relativ kleine Einschränkungen in Bezug auf Stapelzuweisungen. Alle Instanzen in der Kernel-Aufrufkette müssen in eine bestimmte Größe passen oder etwas wird überschrieben. Sie können keine Entdeckung dieses Fehlers, nur eine Art von Downstream-Absturz als Speicherbeschädigung führt zu einer Panik oder einem Keil. Das Zuordnen von großen und variablen Arrays auf einem Kernel-Stack ist einfach keine gute Idee.

  3. Wenn Sie das Array tmp [] schreiben und es ordnungsgemäß beenden, gibt es keinen Grund, es auch zu initialisieren. Aber wenn Sie es initialisieren würden, könnten Sie dies mit Compiler-generiertem Code tun, indem Sie einfach sagen: char tmp[1024] = { 0 }; (Eine partielle Initialisierung eines Aggregats erfordert durch C99 Initialisierung des gesamten Aggregats.) Eine ähnliche Beobachtung gilt für die anderen Arrays.

  4. Wie wäre es von den meisten dieser Arrays loszuwerden und die meisten dieser Code und nur etwas entlang der Linien zu tun:


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