[ C ] segmentation fault avant le main()
Fermé
FlyerBut
-
28 janv. 2009 à 16:53
Char Snipeur Messages postés 9696 Date d'inscription vendredi 23 avril 2004 Statut Contributeur Dernière intervention 3 octobre 2023 - 30 janv. 2009 à 12:00
Char Snipeur Messages postés 9696 Date d'inscription vendredi 23 avril 2004 Statut Contributeur Dernière intervention 3 octobre 2023 - 30 janv. 2009 à 12:00
A voir également:
- [ C ] segmentation fault avant le main()
- Bagage à main - Guide
- Veuillez patienter quelques minutes avant de réessayer instagram ✓ - Forum Instagram
- Copains d'avant qui a visité mon profil - Forum Facebook
- En préparation avant distribution ✓ - Forum Consommation & Internet
- Dans cette présentation, sarah avait encadré directement le titre de certaines diapositives avant d'automatiser cette mise en forme pour tout le document. sur quelles diapositives avait-elle encadré directement le titre ? ✓ - Forum Bureautique
11 réponses
dubcek
Messages postés
18718
Date d'inscription
lundi 15 janvier 2007
Statut
Contributeur
Dernière intervention
22 mars 2024
5 615
29 janv. 2009 à 15:29
29 janv. 2009 à 15:29
démarre le avec
strace ton_prog
pour avoir une idée de ce qu'il fait avant de crasher
strace ton_prog
pour avoir une idée de ce qu'il fait avant de crasher
kilian
Messages postés
8731
Date d'inscription
vendredi 19 septembre 2003
Statut
Modérateur
Dernière intervention
20 août 2016
1 527
28 janv. 2009 à 16:57
28 janv. 2009 à 16:57
Met bien des "\n" à la fin de tes chaines pour printf, afin de bien vider le buffer dès l'appel à printf.
Sinon à part ça, sans le code source on ne peut pas t'aider.
Sinon à part ça, sans le code source on ne peut pas t'aider.
Char Snipeur
Messages postés
9696
Date d'inscription
vendredi 23 avril 2004
Statut
Contributeur
Dernière intervention
3 octobre 2023
1 297
30 janv. 2009 à 10:25
30 janv. 2009 à 10:25
les \n ne vident pas le buffer. faire un fflush(stdout); pour ça. ou endl en C++.
kilian
Messages postés
8731
Date d'inscription
vendredi 19 septembre 2003
Statut
Modérateur
Dernière intervention
20 août 2016
1 527
>
Char Snipeur
Messages postés
9696
Date d'inscription
vendredi 23 avril 2004
Statut
Contributeur
Dernière intervention
3 octobre 2023
30 janv. 2009 à 10:36
30 janv. 2009 à 10:36
T'es sûr?
Il me sembl qu'il ya pas besoin de passer par le fflush explicite.
Il me sembl qu'il ya pas besoin de passer par le fflush explicite.
Char Snipeur
Messages postés
9696
Date d'inscription
vendredi 23 avril 2004
Statut
Contributeur
Dernière intervention
3 octobre 2023
1 297
>
kilian
Messages postés
8731
Date d'inscription
vendredi 19 septembre 2003
Statut
Modérateur
Dernière intervention
20 août 2016
30 janv. 2009 à 10:43
30 janv. 2009 à 10:43
quasiment. Mes programmes de calcul qui sortent beaucoup de résultats dans des fichiers ou en sortie standard écrivait par bloc indépendamment des retours à la ligne. Et je vois mal printf aller voir si le dernier caractère est un \n (qui selon les OS peut être \r ou \n\r) pour vider le buffer. Mais bon... ma mémoire me joue peut être des tours, il faudrait aller voir les spécifications de printf.
kilian
Messages postés
8731
Date d'inscription
vendredi 19 septembre 2003
Statut
Modérateur
Dernière intervention
20 août 2016
1 527
>
Char Snipeur
Messages postés
9696
Date d'inscription
vendredi 23 avril 2004
Statut
Contributeur
Dernière intervention
3 octobre 2023
30 janv. 2009 à 11:21
30 janv. 2009 à 11:21
Et je vois mal printf aller voir si le dernier caractère est un \n (qui selon les OS peut être \r ou \n\r) pour vider le buffer.
Il me semble que c'est pas un truc propre à printf mais plutôt aux flots de caractères dans les terminaux.
Attends, je vais essayer de retrouver les lignes correspondantes dans les drivers tty de Linux, il me semble être tombé là-dessus l'autre jour...
Il me semble que c'est pas un truc propre à printf mais plutôt aux flots de caractères dans les terminaux.
Attends, je vais essayer de retrouver les lignes correspondantes dans les drivers tty de Linux, il me semble être tombé là-dessus l'autre jour...
dubcek
Messages postés
18718
Date d'inscription
lundi 15 janvier 2007
Statut
Contributeur
Dernière intervention
22 mars 2024
5 615
28 janv. 2009 à 17:02
28 janv. 2009 à 17:02
hello
les 2 ordinateurs tournent le même système d'exploitation ?
les 2 ordinateurs tournent le même système d'exploitation ?
voici mon code:
les 2 OS sont Ubuntu...
Je ne comprends tjs pas...
en ligne de commande via : snmpget -t 3 -r 0 -v 1 -c nomCommunaute ip 1.3.6.1.4.1.9.9.156.1.2.1.1.5.1
ça fonctionne dans les 2 OS!!!
Je ne comprends tjs pas pq le programme me lance un segmentation fault avant de rentrer dans le main...
Si quelqu'un a une idée?
const char *progname = "test_snmp"; const char *revision = "$Revision: 1.0 $"; const char *copyright = "2009-01-23"; const char *email = "exemple@gmail.com"; #include "common.h" #include "utils.h" #include "popen.h" #include <dbi/dbi.h> #define DEFAULT_COMMUNITY "public" #define DEFAULT_OID "1.3.6.1.4.1.9.9.156.1.2.1.1.5." #define DEFAULT_PORT "161" #define DEFAULT_PROTOCOL "1" #define DEFAULT_TIMEOUT "3" #define DEFAULT_RETRIES "0" #define DEFAULT_DELIMITER "=" #define DEFAULT_OUTPUT_DELIMITER " " #define MAX_DELIM_LENGTH 8 int process_arguments (int, char **); void print_usage (void); char *server_address = NULL; char *server_port; char *community = NULL; char *network_interface = "1"; char *destination = "0"; char *oid; char *retries; char *delimiter; char *output_delim; char perfstr[MAX_INPUT_BUFFER] = ""; int main (int argc, char **argv) { int i = 0; int result = STATE_UNKNOWN; int found = 0; char input_buffer[MAX_INPUT_BUFFER]; char *command_line = NULL; char *response = NULL; char *outbuff; char *output; char *ptr = NULL; char *p2 = NULL; char *show = NULL; char type[8] = ""; unsigned int istate; setlocale (LC_ALL, ""); bindtextdomain (PACKAGE, LOCALEDIR); textdomain (PACKAGE); /* Configure variables */ outbuff = strdup (""); output = strdup (""); delimiter = strdup (" = "); output_delim = strdup (DEFAULT_OUTPUT_DELIMITER); server_port = strdup (DEFAULT_PORT); retries = strdup (DEFAULT_RETRIES); oid = strdup (DEFAULT_OID); /* Parse parametres */ if (process_arguments (argc, argv) == ERROR) usage4 (_("Could not parse arguments")); /* Genere OID */ strcat(oid, network_interface); printf("\n%s -t %s -r %s -v 1 -c %s %s %s",PATH_TO_SNMPGET, DEFAULT_TIMEOUT, retries, community, server_address, /*server_port,*/ oid); /* Genere commande */ asprintf (&command_line, "%s -t %s -r %s -v 1 -c %s %s %s", PATH_TO_SNMPGET, DEFAULT_TIMEOUT, retries, community, server_address, /*server_port,*/ oid); /* run the command */ child_process = spopen (command_line); if (child_process == NULL) { printf (_("Could not open pipe: %s\n"), command_line); exit (STATE_UNKNOWN); } // Lecture resultat while (fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_process)) asprintf (&output, "%s%s", output, input_buffer); ptr = output; while (ptr) { char *foo, *ptr2; unsigned int copylen; foo = strstr (ptr, delimiter); copylen = foo-ptr; if (copylen > sizeof(perfstr)-strlen(perfstr)-1) copylen = sizeof(perfstr)-strlen(perfstr)-1; ptr2 = ptr; ptr = foo; if (ptr == NULL) break; ptr += strlen (delimiter); ptr += strspn (ptr, " "); found++; if (ptr[0] == '"') { ptr++; response = strpcpy (response, ptr, "\""); ptr = strpbrk (ptr, "\""); ptr += strspn (ptr, "\"\n"); } else { response = strpcpy (response, ptr, "\n"); ptr = strpbrk (ptr, "\n"); ptr += strspn (ptr, "\n"); while (strstr (ptr, delimiter) && strstr (ptr, "\n") && strstr (ptr, "\n") < strstr (ptr, delimiter)) { response = strpcat (response, ptr, "\n"); ptr = strpbrk (ptr, "\n"); } if (ptr && strstr (ptr, delimiter) == NULL) { asprintf (&response, "%s%s", response, ptr); ptr = NULL; } } /* We strip out the datatype indicator for PHBs */ /* Clean up type array - Sol10 does not necessarily zero it out */ bzero(type, sizeof(type)); if (strstr (response, "Gauge: ")) show = strstr (response, "Gauge: ") + 7; else if (strstr (response, "Gauge32: ")) show = strstr (response, "Gauge32: ") + 9; else if (strstr (response, "Counter32: ")) { show = strstr (response, "Counter32: ") + 11; strcpy(type, "c"); } else if (strstr (response, "Counter64: ")) { show = strstr (response, "Counter64: ") + 11; strcpy(type, "c"); } else if (strstr (response, "INTEGER: ")) show = strstr (response, "INTEGER: ") + 9; else if (strstr (response, "STRING: ")) show = strstr (response, "STRING: ") + 8; else show = response; p2 = show; /* Analyse resultat et update db */ printf("\nName: %s", p2); /* fin analyse */ } /* end while (ptr) */ if (found == 0) { die (STATE_UNKNOWN, "No data received from host\n"); } /* close the pipe */ if (spclose (child_process)) { if (result == STATE_OK) result = STATE_UNKNOWN; asprintf (&outbuff, "%s (%s)", outbuff, "snmpget returned an error status"); } printf ("%s\n", outbuff); return result; } /* process command-line arguments */ int process_arguments (int argc, char **argv) { char *ptr; int c = 1; int j = 0, jj = 0, ii = 0; int option = 0; static struct option longopts[] = { STD_LONG_OPTS, {"community", required_argument, 0, 'C'}, {"interface", required_argument, 0, 'I'}, {"destination", required_argument, 0, 'D'}, {0, 0, 0, 0} }; if (argc < 2) return ERROR; while (1) { c = getopt_long (argc, argv, "C:H:P:R:I:D:", longopts, &option); if (c == -1 || c == EOF) break; switch (c) { case 'C': /* group or community */ community = optarg; break; case 'H': /* Host or server */ server_address = optarg; break; case 'P': /* Port */ server_port = optarg; break; case 'R': /* Retry */ retries = optarg; break; case 'I': /* interface */ network_interface = optarg; break; case 'D': /* destination */ destination = optarg; break; } } return OK; } void print_usage (void) { printf (_("Usage:")); printf ("%s -H <ip_address>\n", progname); printf ("-C <community>\n"); printf ("-I <interface>\n"); printf ("-D <destination>\n"); printf ("[-P <server_port>]\n"); printf ("[-R <retry count>]\n"); }
les 2 OS sont Ubuntu...
Je ne comprends tjs pas...
en ligne de commande via : snmpget -t 3 -r 0 -v 1 -c nomCommunaute ip 1.3.6.1.4.1.9.9.156.1.2.1.1.5.1
ça fonctionne dans les 2 OS!!!
Je ne comprends tjs pas pq le programme me lance un segmentation fault avant de rentrer dans le main...
Si quelqu'un a une idée?
Vous n’avez pas trouvé la réponse que vous recherchez ?
Posez votre question
l'exécution de strace donne:
execve("./test_snmp",["./test_snmp"],/*18vars*/)=0
brk(0) =0x804f000
--- SIGSEGV (segmentation fault) @0 (0) ---
+++ killed by SIGSEGV +++
Process 7529 detached
l'exécution de ltrace donne:
ltrace: Couldn't get section header from "./test_snmp"
:s :s
Comment faire disparaitre le segmantation fault avec ces infos?
execve("./test_snmp",["./test_snmp"],/*18vars*/)=0
brk(0) =0x804f000
--- SIGSEGV (segmentation fault) @0 (0) ---
+++ killed by SIGSEGV +++
Process 7529 detached
l'exécution de ltrace donne:
ltrace: Couldn't get section header from "./test_snmp"
:s :s
Comment faire disparaitre le segmantation fault avec ces infos?
dubcek
Messages postés
18718
Date d'inscription
lundi 15 janvier 2007
Statut
Contributeur
Dernière intervention
22 mars 2024
5 615
29 janv. 2009 à 16:30
29 janv. 2009 à 16:30
que dit
file test_snmp
et sur les 2 systèmes
echo $LD_LIBRARY_PATH
file test_snmp
et sur les 2 systèmes
echo $LD_LIBRARY_PATH
la commande file renvoie sur l'OS où le prgr tourne:
test_snmp: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), for GNU/Linux 2.6.8, dynamically linked (uses shared libs), not stripped
la commande file renvoie sur l'OS où le prgr tourne pas:
test_snmp: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), for GNU/Linux 2.6.8, dynamically linked (uses shared libs), stripped
le echo $LD_LIBRARY_PATH me renvoie une ligne "blanche" sur les 2 OS
test_snmp: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), for GNU/Linux 2.6.8, dynamically linked (uses shared libs), not stripped
la commande file renvoie sur l'OS où le prgr tourne pas:
test_snmp: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), for GNU/Linux 2.6.8, dynamically linked (uses shared libs), stripped
le echo $LD_LIBRARY_PATH me renvoie une ligne "blanche" sur les 2 OS
kilian
Messages postés
8731
Date d'inscription
vendredi 19 septembre 2003
Statut
Modérateur
Dernière intervention
20 août 2016
1 527
29 janv. 2009 à 17:13
29 janv. 2009 à 17:13
Pourrais-tu donner le résultat de cette commandes sur les deux?
Comme ça on verra la version des bibliothèques qu'ils utilisent, particulièrement la glibc. Si ces versions sont différentes, alors ça peut coincer.
ldd /bin/ls
Comme ça on verra la version des bibliothèques qu'ils utilisent, particulièrement la glibc. Si ces versions sont différentes, alors ça peut coincer.
dubcek
Messages postés
18718
Date d'inscription
lundi 15 janvier 2007
Statut
Contributeur
Dernière intervention
22 mars 2024
5 615
29 janv. 2009 à 17:13
29 janv. 2009 à 17:13
est-ce que compiler un petit prog. sur le 2ème système fonctionne ?
main(){printf("hello world\n");}
gcc -o prog prog.c
./prog
main(){printf("hello world\n");}
gcc -o prog prog.c
./prog
sur celui qui fonctionne ldd /bin/ls:
linux-gate.so.1 => (0xb7f80000)
librt.so.1 => /lib/tls/i686/cmov/librt.so.1 (0xb7f6f000)
libselinux.so.1 => /lib/libselinux.so.1 (0xb7f56000)
libacl.so.1 => /lib/libacl.so.1 (0xb7f4e000)
libc.so.6 => /lib/tls/i686/cmov/libc.so.6 (0xb7dff000)
libpthread.so.0 => /lib/tls/i686/cmov/libpthread.so.0 (0xb7de7000)
/lib/ld-linux.so.2 (0xb7f81000)
libdl.so.2 => /lib/tls/i686/cmov/libdl.so.2 (0xb7de3000)
libattr.so.1 => /lib/libattr.so.1 (0xb7ddf000)
sur celui du segmentation fault:
linux-gate.so.1 => (0xb7f80000)
librt.so.1 => /lib/tls/i686/cmov/librt.so.1 (0xb7f6f000)
libselinux.so.1 => /lib/libselinux.so.1 (...)
libacl.so.1 => /lib/libacl.so.1 (...)
libc.so.6 => /lib/tls/i686/cmov/libc.so.6 (...)
libpthread.so.0 => /lib/tls/i686/cmov/libpthread.so.0 (...)
/lib/ld-linux.so.2 (...)
libdl.so.2 => /lib/tls/i686/cmov/libdl.so.2 (...)
libattr.so.1 => /lib/libattr.so.1 (...)
il y a les numeros entre ( ) qui changent...
Pour compiler, ça fonctionne correctement
J'ai fais d'autre tests, des recherches dans googles .. mais rien, tjs ce segmentation fault!
:s
quelqu'un a peut-être une idée avec toutes ces infos?
linux-gate.so.1 => (0xb7f80000)
librt.so.1 => /lib/tls/i686/cmov/librt.so.1 (0xb7f6f000)
libselinux.so.1 => /lib/libselinux.so.1 (0xb7f56000)
libacl.so.1 => /lib/libacl.so.1 (0xb7f4e000)
libc.so.6 => /lib/tls/i686/cmov/libc.so.6 (0xb7dff000)
libpthread.so.0 => /lib/tls/i686/cmov/libpthread.so.0 (0xb7de7000)
/lib/ld-linux.so.2 (0xb7f81000)
libdl.so.2 => /lib/tls/i686/cmov/libdl.so.2 (0xb7de3000)
libattr.so.1 => /lib/libattr.so.1 (0xb7ddf000)
sur celui du segmentation fault:
linux-gate.so.1 => (0xb7f80000)
librt.so.1 => /lib/tls/i686/cmov/librt.so.1 (0xb7f6f000)
libselinux.so.1 => /lib/libselinux.so.1 (...)
libacl.so.1 => /lib/libacl.so.1 (...)
libc.so.6 => /lib/tls/i686/cmov/libc.so.6 (...)
libpthread.so.0 => /lib/tls/i686/cmov/libpthread.so.0 (...)
/lib/ld-linux.so.2 (...)
libdl.so.2 => /lib/tls/i686/cmov/libdl.so.2 (...)
libattr.so.1 => /lib/libattr.so.1 (...)
il y a les numeros entre ( ) qui changent...
Pour compiler, ça fonctionne correctement
J'ai fais d'autre tests, des recherches dans googles .. mais rien, tjs ce segmentation fault!
:s
quelqu'un a peut-être une idée avec toutes ces infos?
dubcek
Messages postés
18718
Date d'inscription
lundi 15 janvier 2007
Statut
Contributeur
Dernière intervention
22 mars 2024
5 615
30 janv. 2009 à 09:45
30 janv. 2009 à 09:45
essaye de recompiler et linker ton programme en static :
gcc -static -static-libgcc ...
pour voir si c'est un problème avec les librairies, en static les modules font faire patrie de l'exécutable alors qu'en dynamique/shared il va utiliser celles du système hôte
gcc -static -static-libgcc ...
pour voir si c'est un problème avec les librairies, en static les modules font faire patrie de l'exécutable alors qu'en dynamique/shared il va utiliser celles du système hôte
Char Snipeur
Messages postés
9696
Date d'inscription
vendredi 23 avril 2004
Statut
Contributeur
Dernière intervention
3 octobre 2023
1 297
30 janv. 2009 à 10:38
30 janv. 2009 à 10:38
Salut.
Je n'ai pas la solutions, mais quelques pistes.
J'ai déjà eu ce problème en utilisant QT, une recompilation complète de mon programme réglai le problème en général. Parfois cela venais d'une mauvaise initialisation de variable. Car il faut bien voir que des choses se font avant le main : initialisation de variable de classes (ou struct) etc.
Une autre erreur se produit sur mon Linux, si je fait un petit programma en utilisant pthread, celui-ci compil très bien avec ou sans le lien -lpthread.
Mais sans une erreur de segmentation avant le main se produit, alors qu'avec pas de souci.
Je te conseil donc de faire des tests de simplification jusqu'à ce que ça fonctionne. Dans l'ordre :
vide les main
supprime les include un à un jusqu'à ce que ça fonctionne
supprime les variables static.
à part :
Je ne comprends pas cette déclaration, que vient faire un entier là dedans ? (on en apprend tout les jours en C !)
Je n'ai pas la solutions, mais quelques pistes.
J'ai déjà eu ce problème en utilisant QT, une recompilation complète de mon programme réglai le problème en général. Parfois cela venais d'une mauvaise initialisation de variable. Car il faut bien voir que des choses se font avant le main : initialisation de variable de classes (ou struct) etc.
Une autre erreur se produit sur mon Linux, si je fait un petit programma en utilisant pthread, celui-ci compil très bien avec ou sans le lien -lpthread.
Mais sans une erreur de segmentation avant le main se produit, alors qu'avec pas de souci.
Je te conseil donc de faire des tests de simplification jusqu'à ce que ça fonctionne. Dans l'ordre :
vide les main
supprime les include un à un jusqu'à ce que ça fonctionne
supprime les variables static.
à part :
int option = 0; static struct option longopts[] = {
Je ne comprends pas cette déclaration, que vient faire un entier là dedans ? (on en apprend tout les jours en C !)
Comme toi, je suis resté quelque peu perplexe face à cette ligne. Alors j'ai essayé le programme suivant:
A la réflexion, c'est logique... mais, à mon humble avis, ce n'est vraiment pas une bonne pratique.
#include<stdio.h> struct option { int x; int y; }; int main(void) { int i; int option = 123; static struct option tOption[] = { {1, 11}, {2, 22} }; printf ("option=%d\n", option); for (i=0; i< 2; i++) printf("i=%d x=%d y=%d\n", i, tOption[i].x, tOption[i].y); return (0); }Et ça marche !!! Le compilateur ne confond pas 'int option' et 'struct option'.
A la réflexion, c'est logique... mais, à mon humble avis, ce n'est vraiment pas une bonne pratique.
Char Snipeur
Messages postés
9696
Date d'inscription
vendredi 23 avril 2004
Statut
Contributeur
Dernière intervention
3 octobre 2023
1 297
30 janv. 2009 à 12:00
30 janv. 2009 à 12:00
OK, en fait, il doit considérer le premier mot venant derrière le mot "struct" comme un identificateur, sans tenter de l'interpréter avec ce qui a été fait avant. D'ailleurs, nous n'avons pas la définition de la structure "option" avant.
Ce n'est pas une bonne pratique pour la lisibilité.
Ce n'est pas une bonne pratique pour la lisibilité.
29 janv. 2009 à 15:57
Quoique je suggèrerais peut être d'essayer ltrace plutôt que strace.
ltrace te fournira l'appel aux fonction de bibliothèques externes (fopen/strdup etc...) tandis que strace ne t'indiquera
que les appels systèmes (open/read....), ce qui est généralement plus difficile à situer dans le code....
ltrace ./monprogramme