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

Lazarus Pascal Discussion :

External SIGSEGV avec gdb (Windows), impliquant un tableau dynamique


Sujet :

Lazarus Pascal

  1. #1
    Membre confirmé

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2013
    Messages
    343
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Novembre 2013
    Messages : 343
    Points : 536
    Points
    536
    Billets dans le blog
    2
    Par défaut External SIGSEGV avec gdb (Windows), impliquant un tableau dynamique
    Bjr à tous,

    Je suis confronté à un pb franchement gonflant avec le débogueur gdb.

    Lorsque j'utilise une variable tableau, gdb me remonte une 'sigsegv' au droit d'une utilisation de tableau dynamique correctement initialisé, erreur qui n'a pas lieu d'être.

    Voici la déclaration de ma classe qui pose pb
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
     
    const COLORS_TABLE_SIZE = 256;
    type TArray256Colors = array of TColor;
    type
     
    { TPalette256 }
     
     TPalette256 = class
        procedure GenerateWeb216Palette; deprecated;
        procedure GenerateACADPalette; deprecated;
        procedure GenerateGrayScalePalette; deprecated;
      private
        FColorArray    : TArray256Colors;
        procedure ViderTableCouleurs();
      public
        procedure GenerateTOPOROBOTPalette();
        function  GetColorByIndex(const Idx: Integer):TColor;
     
    end;
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
     
    procedure TPalette256.GenerateWeb216Palette;
    var
      i, j, k  : integer;
      r,g,b    : byte;
      IdxColor : integer;
    begin
      AfficherMessage(ClassName+'.GenerateWeb216Palette');
      ViderTableCouleurs();
      for i:=1 to 6 do
        for j:=1 to 6 do
          for k:=1 to 6 do
            begin
              IdxColor:=(i-1)*36+
                        (j-1)*6+
                        (k-1);
              r:=255 - (i-1) * 51;
              g:=255 - (j-1) * 51;
              b:=255 - (k-1) * 51;
              FColorArray[IdxColor]:=RGBToColor(r,g,b);
            end;
    end;
    function TPalette256.GetColorByIndex(const Idx: Integer): TColor;
    begin
      try
        Result := self.FColorArray[Idx]; // sous GDB, provoque un External SIGSEGV
      except
        Result := clSilver;
      end;
    end;
     
    procedure TPalette256.ViderTableCouleurs;
    var
      i: Integer;
    begin
      SetLength(FColorArray, COLORS_TABLE_SIZE);
      for i:= 0 to COLORS_TABLE_SIZE - 1 do FColorArray[i] := clSilver;
    end;
    Franchement exaspérant, ce genre de pb qui m'entrave dans mon métier

  2. #2
    Expert confirmé
    Avatar de anapurna
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2002
    Messages
    3 419
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Mai 2002
    Messages : 3 419
    Points : 5 818
    Points
    5 818
    Par défaut
    salut


    il te sert a quoi le self devant le tableau ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    function TPalette256.GetColorByIndex(const Idx: Integer): TColor;
    begin
       if (Idx >=0) and   (Idx<COLORS_TABLE_SIZE) Then
       begin
          try
            //Result := self.FColorArray[Idx]; // sous GDB, provoque un External SIGSEGV
            Result := FColorArray[Idx]; // sous GDB, provoque un External SIGSEGV
          except
            Result := clSilver;
          end;
       end;
    end;
    Nous souhaitons la vérité et nous trouvons qu'incertitude. [...]
    Nous sommes incapables de ne pas souhaiter la vérité et le bonheur, et sommes incapables ni de certitude ni de bonheur.
    Blaise Pascal
    PS : n'oubliez pas le tag

  3. #3
    Membre confirmé

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2013
    Messages
    343
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Novembre 2013
    Messages : 343
    Points : 536
    Points
    536
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par anapurna Voir le message
    salut


    il te sert a quoi le self devant le tableau ?

    FColorArray est un tableau privé appartenant à la classe TPalette256
    Le self devant un membre veut dire 'moi-même'. Il permet de lever des homonymies

    Evidemment, j'ai le même pb en retirant le self

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    TPalette256 = class
        procedure GenerateWeb216Palette; deprecated;
        procedure GenerateACADPalette; deprecated;
        procedure GenerateGrayScalePalette; deprecated;
      private
        FColorArray    : TArray256Colors;
        procedure ViderTableCouleurs();
      public
        procedure GenerateTOPOROBOTPalette();
        function  GetColorByIndex(const Idx: Integer):TColor;

  4. #4
    Membre averti

    Homme Profil pro
    Diverses
    Inscrit en
    Février 2014
    Messages
    122
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Diverses

    Informations forums :
    Inscription : Février 2014
    Messages : 122
    Points : 428
    Points
    428
    Par défaut
    As-tu un constructeur pour TPalette256 ? Si oui reserve-t-il la place pour les 256 TColor de FColorArray et est-il appelé ?

  5. #5
    Membre confirmé

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2013
    Messages
    343
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Novembre 2013
    Messages : 343
    Points : 536
    Points
    536
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par yamer Voir le message
    As-tu un constructeur pour TPalette256 ? Si oui reserve-t-il la place pour les 256 TColor de FColorArray et est-il appelé ?
    TPalette256 utilise le constructeur par défaut. Le membre privé FColorArray est redimensionné par ViderTableCouleurs(), appelée depuis Generate*()

    Notons qu'en déclarant FColorArray comme tableau statique, j'ai le même problème

  6. #6
    Membre confirmé

    Homme Profil pro
    Autre
    Inscrit en
    Novembre 2015
    Messages
    145
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Autre

    Informations forums :
    Inscription : Novembre 2015
    Messages : 145
    Points : 625
    Points
    625
    Par défaut
    Je suis peut-être passé à côté du problème, mais chez moi (Windows 32 bits) pas de SIGSEV (cf. capture d'écran).

    Test avec 1 forme et 2 boutons:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    unit Unit1;
     
    {$mode objfpc}{$H+}
     
    interface
     
    uses
      Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls;
     
    type
     
      { TForm1 }
     
      TForm1 = class(TForm)
        Button1: TButton;
        Button2: TButton;
        procedure Button1Click(Sender: TObject);
        procedure Button2Click(Sender: TObject);
      private
        { private declarations }
      public
        { public declarations }
      end;
     
    var
      Form1: TForm1;
     
    implementation
     
    {$R *.lfm}
     
    { TForm1 }
     
    procedure AfficherMessage(const str: string); forward;
     
    const COLORS_TABLE_SIZE = 256;
    type TArray256Colors = array of TColor;
    type
     
    { TPalette256 }
     
    TPalette256 = class
       procedure GenerateWeb216Palette; deprecated;
    //   procedure GenerateACADPalette; deprecated;
    //   procedure GenerateGrayScalePalette; deprecated;
     private
       FColorArray    : TArray256Colors;
       procedure ViderTableCouleurs();
     public
    //   procedure GenerateTOPOROBOTPalette();
       function  GetColorByIndex(const Idx: Integer):TColor;
    end;
     
    //------------------------------------------------------------------------------
     
    procedure AfficherMessage(const str: string);
    begin
      ShowMessage(str);
    end;
     
    procedure TForm1.Button1Click(Sender: TObject);
    begin
      Application.Terminate;
    end;
     
    procedure TForm1.Button2Click(Sender: TObject);
    var test: TPalette256;
    var tt0, tt100, tt255: TColor;
    begin
      test:= TPalette256.Create();
      test.GenerateWeb216Palette;
      tt0 := test.GetColorByIndex(0);
      tt100 := test.GetColorByIndex(100);
      tt255 := test.GetColorByIndex(255);
      AfficherMessage('tt='+IntToStr(integer(tt0))+' '+IntToStr(integer(tt100))+' '+IntToStr(integer(tt255)));
      test.Free;
    end;
     
    procedure TPalette256.GenerateWeb216Palette;
    var
     i, j, k  : integer;
     r,g,b    : byte;
     IdxColor : integer;
    begin
     AfficherMessage(ClassName+'.GenerateWeb216Palette');
     ViderTableCouleurs();
     for i:=1 to 6 do
       for j:=1 to 6 do
         for k:=1 to 6 do
           begin
             IdxColor:=(i-1)*36+
                       (j-1)*6+
                       (k-1);
             r:=255 - (i-1) * 51;
             g:=255 - (j-1) * 51;
             b:=255 - (k-1) * 51;
             FColorArray[IdxColor]:=RGBToColor(r,g,b);
           end;
    end;
     
    function TPalette256.GetColorByIndex(const Idx: Integer): TColor;
    begin
     try
       Result := self.FColorArray[Idx]; // sous GDB, provoque un External SIGSEGV
     except
       Result := clSilver;
     end;
    end;
     
    procedure TPalette256.ViderTableCouleurs;
    var
     i: Integer;
    begin
     SetLength(FColorArray, COLORS_TABLE_SIZE);
     for i:= 0 to COLORS_TABLE_SIZE - 1 do FColorArray[i] := clSilver;
    end;
     
    end.

    Mais je ne suis pas certain d'avoir compris ce que vous indiquez au niveau de votre utilisation de gdb.
    Images attachées Images attachées  

  7. #7
    Membre du Club
    Homme Profil pro
    Inscrit en
    Décembre 2012
    Messages
    71
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Décembre 2012
    Messages : 71
    Points : 60
    Points
    60
    Par défaut Une solution ?
    Bonjour.

    J'ai eu et ai de nouveau le même problème.

    Il s'agit d'une structure de données

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    TLpointer = array of pointer;
    TColl = record
        nlig,ncol:longword;
        nature,taille:word;
        vects:TLpointer;     { le champ où la segmentation a lieu }
    end;
    qui elle-même apparaît comme élément de la table d'une autre structure

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     TVariable = record
        nom:string;
        format:word;
        nb:longword;
        donnees:TLpointer;   { pointeur sur un des types de données }
    end;
    L'allocation de la table donnees fonctionne sans problème mais j'obtiens une erreur de segmentation quand je tente d'allouer la table vects ou de lui affecter nil.

    J'ai soupçonné un problème d'alignement d'adresses, la taille de la structure faisant 16 octets donc j'ai doublé la taille allouée à TColl (stockée dans donnees[0]) sans différence.

    Toujours sur cette idée d'alignement ou de décalage d'adresse (pourtant la bonne d'après le code) j'ai fait une très légère modification pour casser l'alignement :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     TColl = record
        vects:TLpointer;      { ça marche en déplaçant la table }
        nlig,ncol:longword;
        nature,taille:word;
    end;
    Voici le début du code où l'erreur se produit, avec les tests. Il s'agit de lire un fichier wav PCF. Variables est une table de TVariables déjà allouée. dans est le numéro dans cette table, nom le nom du fichier. Les autres champs n'ont pas un grand intérêt à cette étape.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    procedure chargerWAV(dans:integer;nom:string);
      var
        entete:TenteteWAV;
        tmp:PByte;
        taille,lus,i,j,max:word;
        y:smallint;
        donnee:array of PReal;
        echln:PSmallInt;
        nb:word;
        cRIFF,cWAVE,cfmt,cDATA:longword;
        coll:^TColl;
        t_coll:word;
        p:pointer;
        vects:TLPointer;
     
      begin
      { constantes en small endian pour comparaison des id de l'entète }
        cRIFF:=1179011410;       { 'RIFF4 }
        cWAVE:=1163280727;       { 'WAVE' }
        cfmt:=544501094;         { ' fmt' }
        cDATA:=1635017060;       { 'DATA' }
      {!!! vérification que l'assignation se fait bien ! }
        system.Assign(f,nom);
        reset(f,1);
        Blockread(f,entete,sizeof(entete),lus);
        nb:=entete.Datasize div entete.BytePerBloc;
        taille:=entete.BytePerBloc*nb;
        getmem(tmp,taille);
        Blockread(f,tmp^,taille,lus);
      {!!! si mono }
        variables[dans].format:=cdnCollection;
        variables[dans].nb:=1;
        setlength(variables[dans].donnees,1);
        t_coll:=sizeof(TColl);
        getmem(coll,t_coll);
        variables[dans].donnees[0]:=coll;
      { test des adresses dans la structure }
        p:=@(coll^.nlig);     { +4 } 
        p:=@(coll^.ncol);    { +4 }
        p:=@(coll^.nature); { +2 }
        p:=@(coll^.taille);   { +2 }
        p:=@(coll^.vects);
      { ici pas d'erreur }
        coll^.nlig:=entete.NbrCanaux;
        coll^.ncol:=nb;
        coll^.nature:=cnReel;
        coll^.taille:=ctReel;
      { ces trois lignes provoquent la même erreur de segmentation si vects est en queue de TColl }
        coll^.vects:=nil;
        setlength(coll^.vects,0);
        setlength(coll^.vects,entete.NbrCanaux);
    {...}
    end
    ;

Discussions similaires

  1. [FPDF] problème avec les images dans un tableau dynamique
    Par GADSN dans le forum Bibliothèques et frameworks
    Réponses: 4
    Dernier message: 08/04/2009, 11h11
  2. Réponses: 10
    Dernier message: 24/05/2007, 09h27
  3. pb avec "bordure" droite d'un tableau
    Par 3psilOn dans le forum Balisage (X)HTML et validation W3C
    Réponses: 5
    Dernier message: 05/11/2004, 03h14
  4. Réponses: 4
    Dernier message: 23/04/2004, 16h06
  5. Serveur Linux avec clients Windows
    Par ostaquet dans le forum Installation
    Réponses: 2
    Dernier message: 01/08/2002, 15h40

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