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 :

[Linux - Laz 2.2.4 / FPC 3.2.2] SIGSEGV dans un code que je supposais fonctionnel [Lazarus]


Sujet :

Lazarus Pascal

  1. #1
    Expert éminent sénior
    Avatar de Jipété
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    10 730
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 10 730
    Points : 15 132
    Points
    15 132
    Par défaut [Linux - Laz 2.2.4 / FPC 3.2.2] SIGSEGV dans un code que je supposais fonctionnel
    Bonjour,

    j'ouvre un nouveau post en espérant trouver une solution parce que sinon, lentement mais surement, je vais devenir fou...

    Toujours avec mes embrouilles de son, je suis parti d'un lien chez Ian (https://www.un4seen.com/forum/?topic...85684#msg85684) où l'on peut lire
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    // If you want to get all of the file's sample data, you could do something like this...
    HSTREAM decoder=BASS_StreamCreateFile(FALSE, filename, 0, 0, BASS_SAMPLE_FLOAT|BASS_STREAM_DECODE); // create a stream from the file
    DWORD length=BASS_ChannelGetLength(decoder, BASS_POS_BYTE); // get byte length
    float *data=malloc(length); // allocate a buffer for the data
    length=BASS_ChannelGetData(decoder, data, length); // decode the stream into the buffer
    // do something with the data...
    ce qui, traduit du C vers Pascal, devient, après deux adaptations de noms (je ne pouvais pas utiliser son length, c'est une fonction Pascal) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    decoder := BASS_StreamCreateFile(FALSE, filename, 0, 0, {pas de float BASS_SAMPLE_FLOAT | } BASS_STREAM_DECODE); // create a stream from the file
    datalength := BASS_ChannelGetLength(decoder, BASS_POS_BYTE); // get byte length
    SetLength(data, datalength); // allocate a buffer for the data
    alength := BASS_ChannelGetData(decoder, data, datalength); // decode the stream into the buffer
    // do something with the data...
    Ça semble trop simple pour être vrai et efficace, alors je teste avec un bouton et un mémo sur une fiche, et des "exit;" puisque ce matin Lazarus a décidé de me les casser menu menu, genre Ctrl F2 pour arrêter ne fonctionne pas, et quand le prog part en SIGSEGV ça me bloque le Bureau, je ne peux prendre aucune note dans un bloc-note, bonheur de travailler en debug à coups de "exit;" judicieusement placés... :
    (EDIT : ça s'est arrangé après un redémarrage de la machine, )
    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
    const
      SAMPLERATE = 44100;
     
    procedure TForm1.Button1Click(Sender: TObject);
    type
      TByteArray = array of byte;
    var
      f: string;
      decoder: HStream;
      buffer: TByteArray;
      i: integer;
      DataLength: int64;
    begin
      f := '/temp/audac_qq-échantillons-M16pcm.wav'; // DataLength : 22, fichier 66 bytes
    //  f := '/temp/soundFFD1.wav'; // DataLength : 88200, fichier 88244 bytes
      memo.Append('f : '+f);
     
    { 1- create a stream from a file}
      decoder := BASS_StreamCreateFile(FALSE, PChar(f), 0, 0, {pas de float BASS_SAMPLE_FLOAT |} BASS_STREAM_DECODE);
      DataLength := BASS_ChannelGetLength(decoder, BASS_POS_BYTE); // en bytes
      SetLength(buffer, DataLength);
      memo.Append('DataLength : '+IntToStr(DataLength));
    //exit; // ok 1st et 2nd fichiers
     
    { 2- get data}
      i := BASS_ChannelGetData(decoder, @buffer, DataLength); // SIGSEGV ! why ? -- ok après suppression de tous les fichiers dans ./lib
    //exit; 
      memo.Append('i : '+IntToStr(i)); // 22 with 1st file, ok -- KC avec 2nd fichier ! <<<<<<<<<<< ! ! !
      memo.Append('ErrorCode  = '+inttostr(BASS_ErrorGetCode));
      //memo.Append('buf length : '+IntToStr(length(buffer))); // SIGSEGV ! why ?
      Application.ProcessMessages; // pour voir les data dans le mémo
     
    { 3- do something with the data...}
      for i := 0 to DataLength-1 do begin
        memo.Append('i = '+inttostr(i)); // ok si ligne seule
        //memo.Append('i = '+inttostr(i)+' -- byte : '+inttostr(buffer[i])); // SIGSEGV ! why ?
      end;
      BASS_StreamFree(decoder);
      memo.Append('finish');
      Application.ProcessMessages; // pour voir les data dans le mémo
    end; // SIGSEGV ici si accès au buffer ci-dessus commenté ! why ?
     
    procedure TForm1.FormCreate(Sender: TObject);
    begin
      if (HIWORD(BASS_GetVersion) <> BASSVERSION) then begin
        ShowMessage('Mauvaise version de la librairie BASS !');
        Halt;
      end;
     
      if not BASS_Init(-1, SAMPLERATE, 0, nil, nil) then begin
        ShowMessage('BASS ne peut pas s''initialiser !');
        Exit;
      end;
    end;
    Concernant l'accès au buffer, j'ai tout tenté au pif (rajouter avant/après son nom le chapeau^ ^chinois ou l'arobase), rien ne compile à part ce qui est écrit ci-dessus.

    Les fichiers .wav concernés : 2ficspourforum.zip

    Voilà.
    Je ne sais pas quoi dire d'autre, alors je compte sur vous et vos idées lumineuses, moi, je n'ai plus que du brouillard dans la tête...

    Et juste pour rire, après avoir longuement préparé ce post à coups de nombreux essais sur le 1er fichier, j'ai tenté avec le 2nd fichier, le gros, de 88244 octets, et ça n'a pas trainé, je vous remets la ligne concernée, au cas où elle vous aurait échappée :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
      memo.Append('i : '+IntToStr(i)); // 22 with 1st file, ok -- KC avec 2nd fichier, SIGSEGV comm' d'hab' ! <<<<<<<<<<< ! ! !
    Merci,
    Il a à vivre sa vie comme ça et il est mûr sur ce mur se creusant la tête : peutêtre qu'il peut être sûr, etc.
    Oui, je milite pour l'orthographe et le respect du trait d'union à l'impératif.
    Après avoir posté, relisez-vous ! Et en cas d'erreur ou d'oubli, il existe un bouton « Modifier », à utiliser sans modération
    On a des lois pour protéger les remboursements aux faiseurs d’argent. On n’en a pas pour empêcher un être humain de mourir de misère.
    Mes 2 cts,
    --
    jp

  2. #2
    Modérateur
    Avatar de tourlourou
    Homme Profil pro
    Biologiste ; Progr(amateur)
    Inscrit en
    Mars 2005
    Messages
    3 858
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Biologiste ; Progr(amateur)

    Informations forums :
    Inscription : Mars 2005
    Messages : 3 858
    Points : 11 302
    Points
    11 302
    Billets dans le blog
    6
    Par défaut
    Bonjour Jean-Pierre,
    C'est toujours pénible de jongler avec ces types. Ça passe souvent mieux quand on reste basique, comme en C. Il me semble d'ailleurs que cette erreur est de même nature qu'une résolue récemment.
    Un TByteArray n'est pas seulement un tableau d'octets comme en C. Il en contient un, évidemment, dont l'adresse est @buffer[0], à passer à mon avis pour remplir comme tu t'y attends le buffer.
    Delphi 5 Pro - Delphi 11.3 Alexandria Community Edition - CodeTyphon 6.90 sous Windows 10 ; CT 6.40 sous Ubuntu 18.04 (VM)
    . Ignorer la FAQ Delphi et les Cours et Tutoriels Delphi nuit gravement à notre code !

  3. #3
    Expert éminent sénior
    Avatar de Jipété
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    10 730
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 10 730
    Points : 15 132
    Points
    15 132
    Par défaut
    Bonsoir Yves,

    Ah, tu me sauves la vie ! Moi j'ai la mémoire qui flanche et tous ces trucs tordus, j'ai du mal à m'en souvenir -- alors je prends des notes, mais où sont-elles rangées ?

    Et comme il n'y a pas un mot à ce propos dans l'aide, on est mal barrés !

    Bref, j'ai simplement fait comme ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    //i := BASS_ChannelGetData(decoder, @buffer, DataLength); // SIGSEGV ! why ?
      i := BASS_ChannelGetData(decoder, @buffer[0], DataLength); // solved !
    et c'est tout bon.

    Faudrait que je me le fasse tatouer sur l'avant-bras,

    Grand, énorme merci à toi.
    Il a à vivre sa vie comme ça et il est mûr sur ce mur se creusant la tête : peutêtre qu'il peut être sûr, etc.
    Oui, je milite pour l'orthographe et le respect du trait d'union à l'impératif.
    Après avoir posté, relisez-vous ! Et en cas d'erreur ou d'oubli, il existe un bouton « Modifier », à utiliser sans modération
    On a des lois pour protéger les remboursements aux faiseurs d’argent. On n’en a pas pour empêcher un être humain de mourir de misère.
    Mes 2 cts,
    --
    jp

  4. #4
    Expert éminent sénior
    Avatar de Jipété
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    10 730
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 10 730
    Points : 15 132
    Points
    15 132
    Par défaut
    Trois quarts d'heure plus tard, je reviens deux secondes sur ce point, qui m'a causé tant de souci, car un truc me turlupine :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    { 2- get data}
      i := BASS_ChannelGetData(decoder, @buffer[0], DataLength); // "[0]" O-BLI-GA-TOI-RE !
    { 3- do something with the data...}
      for i := 0 to DataLength-1 do
        memo.Append('i = '+inttostr(i)+' -- byte : '+inttostr(buffer[i]));
    Et donc step 2 on écrit des données à l'index [0] du buffer, et quand on lit step 3 ce même index [0] au premier pas de la boucle for, on récupère autre chose que ce qu'on y a mis.

    Ou alors c'est la fonction BASS_ChannelGetData qui s'en dépatouille ? On lui passe l'adresse de la première zone du buffer et la quantité de données à y mettre et elle incrémente toute seule ?
    si c'est ça (et ça doit être ça), c'est dommage que BASS ne remonte pas une erreur ou ne soit pas capable de se débrouiller avec ce qu'on lui donne.

    En tout cas, en C, ça ne fait pas de chichis, ça ne fait pas sa mijaurée : length=BASS_ChannelGetData(decoder, data, length); // decode the stream into the buffer. et zou !

    Bon, faudra juste pas oublier la différence C <> Pascal.
    Il a à vivre sa vie comme ça et il est mûr sur ce mur se creusant la tête : peutêtre qu'il peut être sûr, etc.
    Oui, je milite pour l'orthographe et le respect du trait d'union à l'impératif.
    Après avoir posté, relisez-vous ! Et en cas d'erreur ou d'oubli, il existe un bouton « Modifier », à utiliser sans modération
    On a des lois pour protéger les remboursements aux faiseurs d’argent. On n’en a pas pour empêcher un être humain de mourir de misère.
    Mes 2 cts,
    --
    jp

  5. #5
    Rédacteur/Modérateur
    Avatar de Andnotor
    Inscrit en
    Septembre 2008
    Messages
    5 695
    Détails du profil
    Informations personnelles :
    Localisation : Autre

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 695
    Points : 13 133
    Points
    13 133
    Par défaut
    C'est le compilateur qui est un peu trop tatillon sur les types en mode objfpc.

    Une variable de type tableau dynamique est un pointeur par définition et en Delphi (ou mode Delphi) comme en C on écrirait simplement buffer.

    Buffer étant une variable, @buffer est l'adresse de cette variable et non son contenu. Lorsqu'on écrit @buffer[0], buffer est dans un premier temps déréférencé pour ensuite récupérer l'adresse de son premier élément.
    Mais puisque buffer est un pointeur, on aurait tout aussi bien pu transtyper par pointer(buffer) juste histoire de calmer les ardeurs du compilateur.

    Après tu peux avoir toute l'aide que tu veux mais si tu passes la mauvaise adresse ça n'y changera rien !

  6. #6
    Membre confirmé

    Homme Profil pro
    Retraité
    Inscrit en
    Avril 2012
    Messages
    170
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Vaucluse (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Retraité
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Avril 2012
    Messages : 170
    Points : 455
    Points
    455
    Par défaut
    Bonjour,

    Citation Envoyé par Jipété Voir le message
    Et donc step 2 on écrit des données à l'index [0] du buffer, et quand on lit step 3 ce même index [0] au premier pas de la boucle for, on récupère autre chose que ce qu'on y a mis.
    Avec @buffer[0], tu n'écris aucune donnée à l'index [0] du buffer. Tu donnes simplement à la fonction BASS_ChannelGetData l'adresse du début du buffer.

    Citation Envoyé par Jipété Voir le message
    Ou alors c'est la fonction BASS_ChannelGetData qui s'en dépatouille ? On lui passe l'adresse de la première zone du buffer et la quantité de données à y mettre et elle incrémente toute seule ?
    Tout à fait.

    Citation Envoyé par Jipété Voir le message
    si c'est ça (et ça doit être ça), c'est dommage que BASS ne remonte pas une erreur ou ne soit pas capable de se débrouiller avec ce qu'on lui donne.
    Il se débrouille avec ce que tu lui donnes. Les erreurs possibles sont :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    BASS_ERROR_HANDLE	   handle n'est pas un canal valide.
    BASS_ERROR_ENDED	   Il n'y a plus de données dans le canal.
    BASS_ERROR_NOTAVAIL   Le flag BASS_DATA_AVAILABLE ne peut aps être utilisé avec un canal de décodage. On ne peut pas obtenir les données des flux de sortie mixés. (utilisant STREAMPROC_DEVICE).
    BASS_ERROR_ILLPARAM   Des flux invalides sont utilisés. Par exemple BASS_DATA_NOREMOVE sutra un canal non enregistré.
    Il t'appartient donc de fournir une adresse de buffer valide et une taille suffisante. Comme tu travailles avec une bibliothèque externe, elle ne peut pas vérifier ces deux points, et elle va écrire là où tu lui dis. De même le compilateur n'a aucune idée de ce que fait la bibliothèque. Donc il ne peut pas te signaler une erreur. Si l'adresse est mauvaise, ou si tu dépasses la taille, tu as l'erreur SIGSEGV à l'exécution, parce que ton programme (ou la bibliothèque qu'il appelle) va tripoter une adresse mémoire qui ne lui appartient pas.

    bb84000

  7. #7
    Expert éminent sénior
    Avatar de Jipété
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    10 730
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 10 730
    Points : 15 132
    Points
    15 132
    Par défaut
    Bonjour,

    et ok, merci à vous deux pour ces précisions.
    J'ai fait le test d'Andnotor (pointeur(son_nom)) et ça a fonctionné aussi bien que ma manière d'hier, donc tout va bien.

    Bon après-midi,
    Il a à vivre sa vie comme ça et il est mûr sur ce mur se creusant la tête : peutêtre qu'il peut être sûr, etc.
    Oui, je milite pour l'orthographe et le respect du trait d'union à l'impératif.
    Après avoir posté, relisez-vous ! Et en cas d'erreur ou d'oubli, il existe un bouton « Modifier », à utiliser sans modération
    On a des lois pour protéger les remboursements aux faiseurs d’argent. On n’en a pas pour empêcher un être humain de mourir de misère.
    Mes 2 cts,
    --
    jp

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Probleme rs232 avec fpc et linux
    Par michastro dans le forum Applications et environnements graphiques
    Réponses: 1
    Dernier message: 28/09/2020, 17h52
  2. Réponses: 7
    Dernier message: 06/03/2016, 15h09
  3. Réponses: 25
    Dernier message: 20/10/2013, 21h04
  4. [Free Pascal] [FPC4NDS][Linux] Conflit avec Lazarus au niveau du .fpc.cfg
    Par Alcatîz dans le forum Free Pascal
    Réponses: 7
    Dernier message: 16/03/2010, 19h28
  5. Réponses: 2
    Dernier message: 16/12/2008, 13h32

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