IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Linux Discussion :

pb fonction, fichier et parametres


Sujet :

Linux

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Octobre 2009
    Messages
    14
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2009
    Messages : 14
    Par défaut pb fonction, fichier et parametres
    Bonjour,

    j'ose poster un message car j ai un probleme qui va me rendre fou,

    Je travaille sur un exe compilé sous linux et qui appelle pleins de fichiers c headers, proc, et requetes sql.
    J ai observé une erreur de segmentation dont j ai repéré la source.

    SQL:
    J ai une table qui contient les attributs (11 a peu pres) de plusieurs produits (92)

    C:
    J' ai une fonction appelée dans un fichier 1.c qui, a laide d'un fetch sur la table sql citée plus haut, récupère dans 11 tableaux, contenant chacun 92 tableaux de char, les valeurs des attributs pour chaque produit.

    C'est a dire que chaque tableau contient pour un type d'attribut donné (d'ou les 11 tableaux) sa valeur pour le produit 1 puis 2 puis... puis 92.
    Chaque valeur etant une chaine de caracteres.

    Ainsi je fais une boucle while pour que la fonction citée plus haut travaille sur chacun des produits (1 par 1). Elle prend donc en parametre les 11 tableaux des valeurs d'attributs pour un un produit donné.
    ex: attributA[27 ], attributB[27], ...

    La fonction en question est écrite dans un fichier 2.c et donc je lui renseigne des *char pour chacun des attributs car chaque attribut est une chaine de caracteres.
    Normal en somme

    PROBLEME:
    Le truc qui me rend fou c'est que les valeurs des attributs qui sont les 7 et 8eme parametres de la fonction plantent complètement. J'ai droit à deux jolies OUT OF BOUNDS.
    Ainsi le fichier 1.c n'arrive pas a transmettre a la fonction du fichier 2.c les 2 chaines le caractères des 7 et 8eme parametres.

    Ce qui est dingue c'est que cela est completement independant du type d'attribut car en changeant totalement l'ordre des parametres de la fonction, ce sont toujours les 7 et 8 eme qui sont deux jolis OUT OF BOUNDS.

    En plus je suis sur que cette méthode marche car j ai d autres fonctions qui procèdedent de la meme facon sauf que ce sont les types de produits qui sont differents et donc leurs nombres d attributs aussi, mais ils restent des chaines de caracteres.

    L'un de vous auraient une idee, probleme de compilation...(aucun warning a propos de ca sous linux en compil, c est en executant que ca plante et je le debogue sous emacs)

    Je donne ma langue au chat j ai passé tout une journée la dessus sans avancer

    Merci

  2. #2
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 832
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 832
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par brunolekid Voir le message
    Ce qui est dingue c'est que cela est completement independant du type d'attribut car en changeant totalement l'ordre des parametres de la fonction, ce sont toujours les 7 et 8 eme qui sont deux jolis OUT OF BOUNDS.
    C'est caractéristique d'un comportement indéterminé. c.a.d. que tu travailles avec des éléments qui ne sont pas conforme à la norme.
    Par exemple: imaginons que tes chaines de caractères (tes attributs) n'aient pas de '\0' (erreur de prog) et que tu les traites via strlen(), scrcpy() ou printf("%s") => comportement indéterminé.

    Il serait intéressant que tu postes le code de la fonction incriminée et un exemple minimaliste montrant comment tu appelles cette fonction...
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Octobre 2009
    Messages
    14
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2009
    Messages : 14
    Par défaut
    Merci de ta réponse
    Alors voila le code du fichier "1.c" qui fait le fetch en appelant une procédure plsql pour récupérer les valeurs des attributs puis qui appelle la fonction "MRXBgen_optchange" pour traiter les attributs d'un produit:


    CODE "1.c": (il vient en fait d'une source .pc car je ne vais pas te mettre tous les détails sql)
    while ((pc_done_fetch == proFAUX) && (*etat == proINITIALISE) &&
    (cr == crOK))
    { /* Fetch des éléments dans des variables c */

    EXEC SQL EXECUTE
    BEGIN
    PLMRXBbrc.PLMRXBget_optchange(
    :pc_batch_size,
    :pc_done_fetch,
    :pc_found,
    :pc_t_cgel_indi_bloq,
    :pc_t_numero_deal,
    :pc_t_contrepartie,
    :pc_t_code_contrepartie,
    :pc_t_date_deal,
    :pc_t_date_echeance,
    :pc_t_type_option,
    :pc_t_style_option,
    :pc_t_type_exercice,
    :pc_t_date_reglement,
    :pc_t_sens_deal,
    :pc_t_book,
    :pc_t_nominal_1,
    :pc_t_nominal_2,
    :pc_t_devise_1,
    :pc_t_devise_2, :pc_t_npv_1,
    :pc_t_devise_3,
    :pc_t_tofx_inst,
    :pc_t_strike,
    :pc_t_product_code_crisp,
    :pc_t_crisp_basic_deal_type,
    :pc_t_gele_elsi_cle,
    :pc_t_gele_indi_trf_sele,
    :pc_t_gele_nint,
    :pc_t_gele_rel_oper_code,
    :pc_t_ffr,
    :pc_t_is_mxg,
    :pc_t_settlement_risq,
    :pc_t_indi_modelis_crisp);
    END;
    END-EXEC;

    if ((cr = BDDctrl_sqlcode(errERR_EXECUTE, func)) == crOK)
    { i = 0;
    while ((cr == crOK) && (i < pc_found))
    {
    /*Appel de la fonction c de traitement des éléments*/
    cr = MRXBgen_optchange( p_brc,
    p_trad,
    &elem_ok,
    sinf_code,
    pc_t_numero_deal[i],
    pc_t_contrepartie[i],
    pc_t_code_contrepartie[i],
    pc_t_date_deal[i],
    pc_t_date_echeance[i],
    pc_t_type_option[i],
    pc_t_style_option[i],
    pc_t_type_exercice[i],
    pc_t_date_reglement[i], pc_t_sens_deal[i],
    pc_t_book[i],
    pc_t_nominal_1[i],
    pc_t_nominal_2[i],
    pc_t_devise_1[i],
    pc_t_devise_2[i],
    pc_t_npv_1[i],
    pc_t_devise_3[i],
    pc_t_tofx_inst[i],
    pc_t_strike[i],
    pc_t_product_code_crisp[i],
    pc_t_crisp_basic_deal_type[i],
    pc_t_gele_elsi_cle[i],
    pc_t_gele_nint[i],
    pc_t_gele_indi_trf_sele[i],
    pc_t_gele_rel_oper_code[i],
    pc_t_ffr[i],
    pc_t_settlement_risq[i],
    pc_t_indi_modelis_crisp[i]);

    }
    i++;
    }





    Comme tu peux le voir les attributs récupérés sont tous les tableaux pc_...
    et il y en a plus que 11 par produit mais c'était juste pour l'exemple.
    Toutes les variables pc_... sont initialisées bien plus haut dans le code et le problème ne vient pas de la car j'ai testé toutes les valeurs de chacun de ces tableaux (un paquet) et elles sont toutes OK.

    Le code plante tout de suite pour i=0;

    Puis voila le code de la fonction en question situé dans le fichier "2.c"
    jusqu'à l'erreur de segmentation.

    CODE "2.c"bon il n'y a pas que des chaines de caractères quelques int short et deux structures en premiers paramètres):
    int MRXBgen_optchange(
    p_brc,
    p_trad,
    elem_ok,
    sinf_code,
    numero_deal,
    contrepartie,
    code_contrepartie,
    date_deal,
    date_echeance,
    type_option,
    style_option,
    type_exercice,
    date_reglement,
    sens_deal,
    book,
    nominal_1,
    nominal_2,
    devise_1,
    devise_2,
    devi1_cref,
    devi2_cref,
    npv_1,
    devise_3,
    tofx_inst,
    tofx_strike,
    product_code_crisp,
    basic_deal_type,
    gele_elsi_cle,
    gele_nint,
    gele_indi_trf_sele,
    gele_rel_oper_code,
    ffr,
    settlement_risq,
    indi_modelis_crisp)

    BRCbrc *p_brc;
    traTRAD *p_trad;
    short *elem_ok;
    char *sinf_code;
    char *numero_deal;
    char *contrepartie;
    char *code_contrepartie;
    char *date_deal;
    char *date_echeance;
    char *type_option;
    char *style_option;
    char *type_exercice;
    char *date_reglement;
    char *sens_deal;
    char *book;
    char *nominal_1;
    char *nominal_2;
    char *devi1_cref;
    char *devi2_cref;
    char *devise_1;
    char *devise_2;
    char *npv_1;
    char *devise_3;
    char *tofx_inst;
    char *tofx_strike;
    char *product_code_crisp;
    char *basic_deal_type;
    char *gele_elsi_cle;
    int gele_nint;
    short gele_indi_trf_sele;
    short gele_rel_oper_code;
    char *ffr;
    char *settlement_risq;
    char *indi_modelis_crisp;

    {
    /*Initialisation des variables necessaries à la fonction*/
    BRCbrcd brcd;
    short elem_ok2 = proOUI;
    short inversion;
    float rapport;
    short trouve;
    int cr = crOK;
    int *svel_nint[30];
    int relp_nint;
    int acti;
    char temp_inst[8];
    char strike_theo[relRELA_LEN+1];
    char relp_code[65] = "\0";
    char book_out[65] = "\0";
    char objid[120] = "\0";
    char anoe_libe[ANOE_LIBE_LEN+1];
    char libe_util_add[ANOE_LIBE_UTIL_LEN+1];
    char libe_info_add[ANOE_LIBE_INFO_LEN+1];
    char func[] = "<MRXBRC.C> MRXBgen_optchange";


    /* Init du rapport */
    rapport=0;

    /*Initialisation de la structure brcd*/
    BRCini_brcd(&brcd);

    /* Création de l'identifiant de l'objet*/
    sprintf(objid,"%s",gele_elsi_cle);



    Et donc le code plante en segm fault au sprintf de la fin car si dans "1.c" pc_t_gele_elsi_cle[0]="FXO_701120080\000\000\000\000\000\000"
    et bien on a dans "2.c"
    gele_elsi_cle=0x2b2a00000002 <Address 0x2b2a00000002 out of bounds>
    d'ou bye bye le sprintf...

    J'ai aussi basic_deal_type=0x1c26b <Address 0x1c26b out of bounds>
    alors que pc_t_basic_deal_type[0]="OP999\000\000\000\000"

    Et donc "ce ne sont pas" ces deux paramètres qui plantent mais bien "leurs positions" dans l'appel de la fonction car en changeant l'ordre des paramètres ce sont toujours les 27 et 28emes paramétres qui prennent des valeurs incohérentes.

    Voila pffffiouuuuuuu...

  4. #4
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 832
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 832
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par brunolekid Voir le message
    Merci de ta réponse
    Alors voila le code du fichier "1.c" qui fait le fetch en appelant une procédure plsql pour récupérer les valeurs des attributs puis qui appelle la fonction "MRXBgen_optchange" pour traiter les attributs d'un produit:


    CODE "1.c": (il vient en fait d'une source .pc car je ne vais pas te mettre tous les détails sql)
    while ((pc_done_fetch == proFAUX) && (*etat == proINITIALISE) &&
    (cr == crOK))
    { /* Fetch des éléments dans des variables c */

    EXEC SQL EXECUTE
    BEGIN
    PLMRXBbrc.PLMRXBget_optchange(
    :pc_batch_size,
    :pc_done_fetch,
    :pc_found,
    :pc_t_cgel_indi_bloq,
    :pc_t_numero_deal,
    :pc_t_contrepartie,
    :pc_t_code_contrepartie,
    :pc_t_date_deal,
    :pc_t_date_echeance,
    :pc_t_type_option,
    :pc_t_style_option,
    :pc_t_type_exercice,
    :pc_t_date_reglement,
    :pc_t_sens_deal,
    :pc_t_book,
    :pc_t_nominal_1,
    :pc_t_nominal_2,
    :pc_t_devise_1,
    :pc_t_devise_2, :pc_t_npv_1,
    :pc_t_devise_3,
    :pc_t_tofx_inst,
    :pc_t_strike,
    :pc_t_product_code_crisp,
    :pc_t_crisp_basic_deal_type,
    :pc_t_gele_elsi_cle,
    :pc_t_gele_indi_trf_sele,
    :pc_t_gele_nint,
    :pc_t_gele_rel_oper_code,
    :pc_t_ffr,
    :pc_t_is_mxg,
    :pc_t_settlement_risq,
    :pc_t_indi_modelis_crisp);
    END;
    END-EXEC;

    if ((cr = BDDctrl_sqlcode(errERR_EXECUTE, func)) == crOK)
    { i = 0;
    while ((cr == crOK) && (i < pc_found))
    {
    /*Appel de la fonction c de traitement des éléments*/
    cr = MRXBgen_optchange( p_brc,
    p_trad,
    &elem_ok,
    sinf_code,
    pc_t_numero_deal[i],
    pc_t_contrepartie[i],
    pc_t_code_contrepartie[i],
    pc_t_date_deal[i],
    pc_t_date_echeance[i],
    pc_t_type_option[i],
    pc_t_style_option[i],
    pc_t_type_exercice[i],
    pc_t_date_reglement[i], pc_t_sens_deal[i],
    pc_t_book[i],
    pc_t_nominal_1[i],
    pc_t_nominal_2[i],
    pc_t_devise_1[i],
    pc_t_devise_2[i],
    pc_t_npv_1[i],
    pc_t_devise_3[i],
    pc_t_tofx_inst[i],
    pc_t_strike[i],
    pc_t_product_code_crisp[i],
    pc_t_crisp_basic_deal_type[i],
    pc_t_gele_elsi_cle[i],
    pc_t_gele_nint[i],
    pc_t_gele_indi_trf_sele[i],
    pc_t_gele_rel_oper_code[i],
    pc_t_ffr[i],
    pc_t_settlement_risq[i],
    pc_t_indi_modelis_crisp[i]);

    }
    i++;
    }





    Comme tu peux le voir les attributs récupérés sont tous les tableaux pc_...
    et il y en a plus que 11 par produit mais c'était juste pour l'exemple.
    Toutes les variables pc_... sont initialisées bien plus haut dans le code et le problème ne vient pas de la car j'ai testé toutes les valeurs de chacun de ces tableaux (un paquet) et elles sont toutes OK.

    Le code plante tout de suite pour i=0;

    Puis voila le code de la fonction en question situé dans le fichier "2.c"
    jusqu'à l'erreur de segmentation.

    CODE "2.c"bon il n'y a pas que des chaines de caractères quelques int short et deux structures en premiers paramètres):
    int MRXBgen_optchange(
    p_brc,
    p_trad,
    elem_ok,
    sinf_code,
    numero_deal,
    contrepartie,
    code_contrepartie,
    date_deal,
    date_echeance,
    type_option,
    style_option,
    type_exercice,
    date_reglement,
    sens_deal,
    book,
    nominal_1,
    nominal_2,
    devise_1,
    devise_2,
    devi1_cref,
    devi2_cref,
    npv_1,
    devise_3,
    tofx_inst,
    tofx_strike,
    product_code_crisp,
    basic_deal_type,
    gele_elsi_cle,
    gele_nint,
    gele_indi_trf_sele,
    gele_rel_oper_code,
    ffr,
    settlement_risq,
    indi_modelis_crisp)

    BRCbrc *p_brc;
    traTRAD *p_trad;
    short *elem_ok;
    char *sinf_code;
    char *numero_deal;
    char *contrepartie;
    char *code_contrepartie;
    char *date_deal;
    char *date_echeance;
    char *type_option;
    char *style_option;
    char *type_exercice;
    char *date_reglement;
    char *sens_deal;
    char *book;
    char *nominal_1;
    char *nominal_2;
    char *devi1_cref;
    char *devi2_cref;
    char *devise_1;
    char *devise_2;
    char *npv_1;
    char *devise_3;
    char *tofx_inst;
    char *tofx_strike;
    char *product_code_crisp;
    char *basic_deal_type;
    char *gele_elsi_cle;
    int gele_nint;
    short gele_indi_trf_sele;
    short gele_rel_oper_code;
    char *ffr;
    char *settlement_risq;
    char *indi_modelis_crisp;

    {
    /*Initialisation des variables necessaries à la fonction*/
    BRCbrcd brcd;
    short elem_ok2 = proOUI;
    short inversion;
    float rapport;
    short trouve;
    int cr = crOK;
    int *svel_nint[30];
    int relp_nint;
    int acti;
    char temp_inst[8];
    char strike_theo[relRELA_LEN+1];
    char relp_code[65] = "\0";
    char book_out[65] = "\0";
    char objid[120] = "\0";
    char anoe_libe[ANOE_LIBE_LEN+1];
    char libe_util_add[ANOE_LIBE_UTIL_LEN+1];
    char libe_info_add[ANOE_LIBE_INFO_LEN+1];
    char func[] = "<MRXBRC.C> MRXBgen_optchange";


    /* Init du rapport */
    rapport=0;

    /*Initialisation de la structure brcd*/
    BRCini_brcd(&brcd);

    /* Création de l'identifiant de l'objet*/
    sprintf(objid,"%s",gele_elsi_cle);



    Et donc le code plante en segm fault au sprintf de la fin car si dans "1.c" pc_t_gele_elsi_cle[0]="FXO_701120080\000\000\000\000\000\000"
    et bien on a dans "2.c"
    gele_elsi_cle=0x2b2a00000002 <Address 0x2b2a00000002 out of bounds>
    d'ou bye bye le sprintf...

    J'ai aussi basic_deal_type=0x1c26b <Address 0x1c26b out of bounds>
    alors que pc_t_basic_deal_type[0]="OP999\000\000\000\000"

    Et donc "ce ne sont pas" ces deux paramètres qui plantent mais bien "leurs positions" dans l'appel de la fonction car en changeant l'ordre des paramètres ce sont toujours les 27 et 28emes paramétres qui prennent des valeurs incohérentes.

    Voila pffffiouuuuuuu...

    Quelques trucs en vrac
    1) au début de ton code, dans ton while, tu vas taper dans "*etat". J'ose espérer que "etat" contient bien une adresse valide.

    2) tu appelles ta fonction "MRXBgen_optchange" en lui passant en paramètre la variable "pc_t_numero_deal[i]" (entre autres). Ensuite, dans ta fonction "MRXBgen_optchange", tu reçois ce paramètre dans une variable "numero_deal" déclarée ensuite comme "char *" (putain ça fait 10 ans que j'avais pas vu cette syntaxe car depuis le C95, on peut maintenant écrire directement "char *numero_deal" dans la parenthèse mais bon, ceci n'a rien à voir).
    Donc pc_t_numero_deal[i] est bien un "char*" puisqu'il est stocké dans un paramètre de type "char*". Donc ça veut dire que "pc_t_numero_deal" est un "char **".
    Question (qui ne concerne que cette variable mais qu'on peut reprendre pour toutes les autres): comment est déclarée/allouée/initialisée la variable "pc_t_numero_deal" ??? J'ai pas regardé toutes les autres variables mais leur déclaration semble identique donc la question se pose pareil. Je me suis d'ailleurs arrêté aussi sur "elem_ok" qui semble être un short puisques tu passes l'adresse de cette variable que tu reçois dans un "short *". Est-ce bien le cas ???

    3) si je lis bien ton code non indenté, tu passes à ta fonction tout un tas de variables[i] mais i ne varie jamais dans ta boucle while (la ligne "i++" est située après l'accolade du while) mais bon, ptet qu'il s'agit d'une erreur de recopie

    4) initialiser une chaine char toto[65]="\0" je ne sais pas trop ce que ça va faire. Normalement on écrit simplement char toto[65]="" et le compilo se charge tout seul d'y rajouter le '\0'. Ou bien on peut, si on veut être sûr, écrire char toto[65]={'\0'} mais mettre ce "\0" entre guillement, je ne sais pas comment il est compris. Toutefois cela ne rend pas la chaine toto invalide. Soit le compilo comprend de travers et remplit toto avec un caractère batard mais il rajoute ensuite automatiquement le '\0' propre à toute chaine, soit il comprend bien et il met le '\0' demandé puis il lui rajoute quand-même un '\0' car ce comportement reste invariant chaque fois qu'on initialise un tableau avec des guillemets. Dans tous les cas ta chaine toto est correcte. Mais c'est maladroitement écrit.

    Bon, les points 3 et 4 ne sont pas graves. mais les points 1 et 2 méritent qu'on s'y intéresse...
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  5. #5
    Membre averti
    Profil pro
    Inscrit en
    Octobre 2009
    Messages
    14
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2009
    Messages : 14
    Par défaut
    1)Pour la variable *etat j'ai etat=0x7ffffde78f7b et *etat=I qui est un flag pour dire que les variables ont bien été initialisées

    2)Etant donné que le fichier 1.c est en fait un proC 1.pc_t_gele_elsi_cle est initialisée dans le fichier 1.c compilé a partir de 1.pc et on a tout en haut du fichier 1.c:
    #ifndef PC_XXXREL_
    #define PC_XXXREL_
    char pc_t_gele_elsi_cle [100][93];

    #endif

    idem pour les autres variables (tailles et types différents)

    Et la variable elem_ok vaut 1 elle est ok

    3)C'est vrai je me suis planté pour le i++

    4)Je travaille sur un vieux projet de plusieures annees dou ces ecritures antiques

Discussions similaires

  1. passer un fichier en parametre à une fonction
    Par medmans dans le forum Langage
    Réponses: 15
    Dernier message: 24/10/2007, 13h59
  2. Appel d'une fonction C avec nom de fichier en paramètre
    Par vince3320 dans le forum Fortran
    Réponses: 4
    Dernier message: 21/11/2006, 14h58
  3. fonction reload avec parametre
    Par zetta dans le forum Général JavaScript
    Réponses: 4
    Dernier message: 18/11/2005, 09h32
  4. Réponses: 3
    Dernier message: 16/06/2004, 11h26
  5. Réponses: 2
    Dernier message: 23/05/2003, 12h22

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo