[C/C++] kernel 2.6.12 => segmentation fault

kernel 2.6.12 => segmentation fault [C/C++] - C - Programmation

Marsh Posté le 11-07-2005 à 14:12:46    

Bonjour,
 
   Je travail sur un programme personnel qui fonctionnait très bien avant ma mise à jour kernel du 2.6.11 au 2.6.12. Depuis, j'ai une erreur de segmentation. Cette erreur disparait lorsque je repasse sur mon 2.6.11. J'ai réussit à isoler ce problème dans un petit programme C/C++. Je recherche des personnes pouvant compiler, tester ce programme pour me dire quelle est leur version du noyau et si il y a eu une erreur de segmentation ou non. (Note: utilisation ou non des NPTL). De plus si vous avez une idée pouvant expliquer ce comportement ...
 
Code:
 
 #include <string>  
 #include <unistd.h>  
 #include <pthread.h>  
 #include <expect.h>  
 #include <stdlib.h>  
 #include <iostream>  
 
 using namespace std;  
 
 static char *username;  
 static char *prompt;  
 
 void error(const char *message) {  
   cerr << "Error: " << message << endl;  
   exit(EXIT_FAILURE);  
 }  
 
 void *console_task(void *) {  
   int fd;  
   FILE *cnx = exp_popen("bash" );  
   if (cnx == 0)  
     error("bash connexion failed" );  
   string prompt_regexp(".*" + string(username) + "@.* $" );  
   exp_fexpectl(cnx, exp_regexp, prompt_regexp.c_str(), 1, exp_end);  
   string sleep_command = "sleep 10\n";  
   fwrite(sleep_command.c_str(), sizeof(char), sleep_command.length(), cnx);  
 
   exp_fexpectl(cnx, exp_regexp, prompt, 1, exp_end);  
   //prompt_regexp.c_str(), 1, exp_end);  
   return 0;  
 }  
 
 int main(int argc, char **argv) {  
   username = getenv("USER" );  
   string sprompt(".*" + string(username) + "@.* $" );  
   prompt = (char *)malloc(sprompt.length() + 1 * sizeof(char *));  
   strcpy(prompt, sprompt.c_str());  
   cout << prompt << endl;  
   if (argc > 1)  
     console_task(NULL);  
   else {  
     pthread_t task;  
     
     pthread_create(&task, NULL, console_task, NULL);  
     pthread_join(task, NULL);  
   }  
   return EXIT_SUCCESS;  
 }  
 
Pour compiler : g++ -o segfault -lexpect5.42 -lpthread segfault.c
(il sera peut ête nécessaire d'adapter la version de la libexpect).
 
Merci de votre aide,

Reply

Marsh Posté le 11-07-2005 à 14:12:46   

Reply

Marsh Posté le 11-07-2005 à 14:54:24    

ymerejt a écrit :


#include <string>




Pas du C. Le forum C++, c'est la porte à coté...


Message édité par Emmanuel Delahaye le 11-07-2005 à 14:54:48

---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 11-07-2005 à 15:00:38    

sleep_command.c_str(), sizeof(char), sleep_command.length()
 
 
déjà c'est faut ça.  strlen(s.c_str()) <= s.size().
 
ensuite vire tes char*.

Reply

Marsh Posté le 11-07-2005 à 15:15:08    

Emmanuel Delahaye a écrit :

Pas du C. Le forum C++, c'est la porte à coté...


Si vous avez bien lu mon message vous comprendrez que le problème n'est pas de savoir si c'est du C ou du C++, s'il est bien codé ou non. Il est vrai que ce code mélange les deux, et abuse de certaines construction. Néamoins je l'ai précisé c'est un petit programme écrit en deux minutes qui met en exergue le problème que je rencontre dans mon vrai programme qui lui fait 50.000 de C/C++ très propre (il me semblait un peu exagéré de poster ce code ...)
Le problème est l'apparition d'une erreur de segmentation sous 2.6.12 qui finit (backtrace gdb) au niveau des appels systèmes. Ce que je souhaite savoir c'est si ce programme fonctionne correctement ou non sur vos machines personnelles afin de valider un bug probable dans une librairie que j'utilise ou ...
 
Merci de ces réponses un peu attives, j'espère que des discussions constructives suivront.

Reply

Marsh Posté le 11-07-2005 à 15:24:22    

Citation :

je rencontre dans mon vrai programme qui lui fait 50.000 de C/C++ très propre


 
Le C/C++ n'existe pas.  
Soit c'est du C, soit c'est du C++. Les deux langages sont distincts.

Reply

Marsh Posté le 11-07-2005 à 15:43:34    

essaie de le débugger avec gdb tu pourras au moins savoir où se situe le vilain pointeur NULL...

Reply

Marsh Posté le 11-07-2005 à 15:51:58    

propre ? ton code est dégueux, et plein de bug. Des variables globales super ...
 
  if (cnx == 0)  
     error("bash connexion failed" );  
 
c'est gentil de le signaler ... mais ça sert à rien
 
 
Je reste perplexe devant :
 
(char *)malloc(sprompt.length() + 1 * sizeof(char *));  
 

Code :
  1. #include <string>
  2. #include <iostream>
  3. #include <cstdlib>
  4. #include <cstdio>
  5. #include <memory>
  6. extern "C" {
  7. #include <pthread.h>
  8. }
  9. using namespace std;
  10. namespace
  11. {
  12.   struct ConsoleData
  13.   {
  14.     string username;
  15.     string prompt;
  16.   };
  17.   void error(const char *message) {
  18.     cerr << "Error: " << message << endl;
  19.   }
  20.   void *console_task(void *data) {
  21.     auto_ptr<ConsoleData> cd(static_cast<ConsoleData*>(data));
  22.     cout << "console_task\n";
  23.     FILE *cnx = reinterpret_cast<FILE*>(0xdeadbeef); /* exp_popen("bash" ) */
  24.     if(cnx == 0) {
  25.       error("bash connexion failed" );
  26.       return 0;
  27.     }
  28.     string prompt_regexp(".*" + cd->username + "@.* $" );
  29.     // exp_fexpectl(cnx, exp_regexp, prompt_regexp.c_str(), 1, exp_end);
  30.     const char * const sleep_command = "sleep 10\n";
  31.     size_t sleep_command_len = strlen(sleep_command);
  32.     // fwrite(sleep_command, 1, sleep_command_len, cnx);
  33.     // exp_fexpectl(cnx, exp_regexp, cd->prompt.c_str(), 1, exp_end);
  34.     return 0;
  35.   }
  36. }
  37. int main(int argc, char **argv) {
  38.   ConsoleData *cd = new ConsoleData;
  39.   const char *USER = getenv("USER" );
  40.   if(!USER) {
  41.     return 1;
  42.   }
  43.   cd->username = USER;
  44.   cd->prompt = ".*" + cd->username + "@.* $";
  45.   cout << cd->prompt << endl;
  46.   if (argc > 1) {
  47.     console_task(cd);
  48.   }
  49.   else {
  50.     pthread_t task;
  51.     pthread_create(&task, NULL, console_task, cd);
  52.     pthread_join(task, NULL);
  53.   }
  54. }


 
ça marche très bien.

Reply

Marsh Posté le 11-07-2005 à 15:52:08    

Elmoricq a écrit :

Citation :

je rencontre dans mon vrai programme qui lui fait 50.000 de C/C++ très propre


 
Le C/C++ n'existe pas.  
Soit c'est du C, soit c'est du C++. Les deux langages sont distincts.


 
Dans mon code C++ je fais des appels à des bibliothèques C. Par conséquent, je pense qu'à cause de la notion de linkage on peut parler de code C/C++. Cependant, il est évident que ce sont des langages distinct en tant que langage.

Reply

Marsh Posté le 11-07-2005 à 15:53:44    

MiniMoi51 a écrit :

essaie de le débugger avec gdb tu pourras au moins savoir où se situe le vilain pointeur NULL...


 
Ça n'est pas un problème de pointeur NULL. Toutes les erreurs de segmentation ne le sont. Il est cependant vrai que c'est l'erreur la plus courante.

Reply

Marsh Posté le 11-07-2005 à 15:54:22    

Taz a écrit :

propre ? ton code est dégueux, et plein de bug. Des variables globales super ...
 
  if (cnx == 0)  
     error("bash connexion failed" );  
 
c'est gentil de le signaler ... mais ça sert à rien
 
 
Je reste perplexe devant :
 
(char *)malloc(sprompt.length() + 1 * sizeof(char *));  
 

Code :
  1. #include <string>
  2. #include <iostream>
  3. #include <cstdlib>
  4. #include <cstdio>
  5. #include <memory>
  6. extern "C" {
  7. #include <pthread.h>
  8. }
  9. using namespace std;
  10. namespace
  11. {
  12.   struct ConsoleData
  13.   {
  14.     string username;
  15.     string prompt;
  16.   };
  17.   void error(const char *message) {
  18.     cerr << "Error: " << message << endl;
  19.   }
  20.   void *console_task(void *data) {
  21.     auto_ptr<ConsoleData> cd(static_cast<ConsoleData*>(data));
  22.     cout << "console_task\n";
  23.     FILE *cnx = reinterpret_cast<FILE*>(0xdeadbeef); /* exp_popen("bash" ) */
  24.     if(cnx == 0) {
  25.       error("bash connexion failed" );
  26.       return 0;
  27.     }
  28.     string prompt_regexp(".*" + cd->username + "@.* $" );
  29.     // exp_fexpectl(cnx, exp_regexp, prompt_regexp.c_str(), 1, exp_end);
  30.     const char * const sleep_command = "sleep 10\n";
  31.     size_t sleep_command_len = strlen(sleep_command);
  32.     // fwrite(sleep_command, 1, sleep_command_len, cnx);
  33.     // exp_fexpectl(cnx, exp_regexp, cd->prompt.c_str(), 1, exp_end);
  34.     return 0;
  35.   }
  36. }
  37. int main(int argc, char **argv) {
  38.   ConsoleData *cd = new ConsoleData;
  39.   const char *USER = getenv("USER" );
  40.   if(!USER) {
  41.     return 1;
  42.   }
  43.   cd->username = USER;
  44.   cd->prompt = ".*" + cd->username + "@.* $";
  45.   cout << cd->prompt << endl;
  46.   if (argc > 1) {
  47.     console_task(cd);
  48.   }
  49.   else {
  50.     pthread_t task;
  51.     pthread_create(&task, NULL, console_task, cd);
  52.     pthread_join(task, NULL);
  53.   }
  54. }


 
ça marche très bien.


 
Quelle est la version de ton noyau ?
De plus tu as oublié la ligne la plus importante :
exp_fexpectl(cnx, exp_regexp, cd->prompt.c_str(), 1, exp_end);


Message édité par ymerejt le 11-07-2005 à 16:26:55
Reply

Marsh Posté le 11-07-2005 à 15:54:22   

Reply

Marsh Posté le 11-07-2005 à 15:57:42    

2.6.12.2
 
et arrête de délirer. Ton code il est bateau : si c'était la faute aux pthread, tu serais pas là pour en parler ...

Reply

Marsh Posté le 11-07-2005 à 16:06:14    

Taz a écrit :

2.6.12.2
 
et arrête de délirer. Ton code il est bateau : si c'était la faute aux pthread, tu serais pas là pour en parler ...


 
Dans ta version il y a plutôt intérêt que cela fonctionne ... Tu ne fais absoluement rien et surtout tu ne réalise pas l'appel qui fonctionne pas.
 
Utilise donc ce diff :
1d0
< #include <expect.h>
7d5
<  
11d8
<  
26,27c23
<     //FILE *cnx = reinterpret_cast<FILE*>(0xdeadbeef); /* exp_popen("bash" ) */  
<     FILE *cnx = exp_popen("bash" );
---
>     FILE *cnx = reinterpret_cast<FILE*>(0xdeadbeef); /* exp_popen("bash" ) */  
33c29
<     exp_fexpectl(cnx, exp_regexp, prompt_regexp.c_str(), 1, exp_end);  
---
>     // exp_fexpectl(cnx, exp_regexp, prompt_regexp.c_str(), 1, exp_end);  
36,37c32,33
<     fwrite(sleep_command, 1, sleep_command_len, cnx);  
<     exp_fexpectl(cnx, exp_regexp, cd->prompt.c_str(), 1, exp_end);  
---
>     // fwrite(sleep_command, 1, sleep_command_len, cnx);  
>     // exp_fexpectl(cnx, exp_regexp, cd->prompt.c_str(), 1, exp_end);  
 
Et dis moi si ca continue de fonctionner.
Note : la librairie expect est bien sûr nécessaire mais je pense qu'il n'est pas nécessaire de te la préciser.
 
 Merci d'avance et désolé d'être une grosse buse à côté de ton excellence.


Message édité par ymerejt le 11-07-2005 à 16:37:33
Reply

Marsh Posté le 11-07-2005 à 16:53:23    

et le rapport entre expect et linux ?
 
tu prends ton programme, gdb et tu debug. Tu corriges aussi les problèmes qu'on te signale.

Reply

Marsh Posté le 11-07-2005 à 16:59:39    

Taz a écrit :

et le rapport entre expect et linux ?
> Problement les appels systèmes ;)
tu prends ton programme, gdb et tu debug. Tu corriges aussi les problèmes qu'on te signale.


 
En quelle langue faut-il te dire que le problème ne viens pas de là. Sur ce problème j'ai pas mal avancé d'ailleurs.  
strace m'a permis de mettre en évidence que l'appel système futex échoue lorsque je suis en 2.6.12 et passe lorsque je suis en 2.6.11 (au passage, j'aimerai que tu m'explique le rapport avec 0xdeadbeef ...)
 
futex(0xb7c57bf8, FUTEX_WAIT, 5365, NULL) = -1 EINTR (Interrupted system call)
--- SIGALRM (Alarm clock) @ 0 (0) ---
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
alarm(0)                                = 0
futex(0x804d4f8, FUTEX_WAIT, 2, NULL)   = 0
futex(0x804d4f8, FUTEX_WAKE, 1)         = 0
+++ killed by SIGSEGV (core dumped) +++


Message édité par ymerejt le 11-07-2005 à 17:01:08
Reply

Marsh Posté le 11-07-2005 à 17:33:47    

non j'avoue je comprends pas ... ça vient pas de là, mais c'est l'appel système qui est le problème. Sors ton gdb et vérifies les arguments que tes fonctions exp_*

Reply

Marsh Posté le 11-07-2005 à 17:51:53    

Taz a écrit :

non j'avoue je comprends pas ... ça vient pas de là, mais c'est l'appel système qui est le problème. Sors ton gdb et vérifies les arguments que tes fonctions exp_*


 
J'ai déjà vérifier celà. Les appels sont impécables de plus ce prog fonctionne parfaitement en 2.6.11.
Je suis en train de me cogner les morceaux de codes choisies de la bibliothèque expect. Mon but étant de réussir à générer un petit programme C/C++ qui mettrait en évidence le problème sans utiliser la bibliothèque expect.
 
Cependant, ma requête originale reste toujours vraie. As-tu une erreur de segmentation à l'exécution sur ton 2.6.12 ? Cette question est importante pour vérifier que ça n'est pas mon installation qui s'est dégradé et qui pourrait provoquer des problèmes ...
 
Merci d'avance

Reply

Marsh Posté le 11-07-2005 à 19:01:30    

ymerejt a écrit :

Le problème est l'apparition d'une erreur de segmentation sous 2.6.12 qui finit (backtrace gdb) au niveau des appels systèmes.


Dans ce cas le bon forum est


 FORUM HardWare.fr
  OS Alternatifs
  Codes et scripts

 
En indiquant [Linux 2.6]. Poster dans le bon forum peut éviter des malentendus...


---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 11-07-2005 à 19:42:05    

code impeccable ? c'est une blague ?
 
montre ta bt full qu'on se marre

Reply

Marsh Posté le 11-07-2005 à 20:03:45    

et puis ton exp_ il part en parallèle, il serait bon d'attendre sa fin avant de quitter main.

Reply

Marsh Posté le 11-07-2005 à 20:58:06    

Premièrement je n'ai jamais dit que le code était impeccable mais que l'appel à bibliothèque est bon. Deuxièmement exp_fexpectl ne part pas du tout en parallèle. Enfin, la backtrace part complètement en couille à la suite de l'erreur sur futex.

Reply

Marsh Posté le 12-07-2005 à 01:35:04    

si ça part en //. Le programme rends la main, ça revient au shell, affiche le sleep, bloque, et puis finalement ça termine. même dans gdb,  ça me ramene au shell, termine le sleep, puis reviens dans gdb.

Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed