AccessViolation su dll solo per alcuni computer

di il
2 risposte

AccessViolation su dll solo per alcuni computer

Ciao a tutti,
ho un problema che mi sta facendo addannare da un po di tempo,
spiego la situazione:

Sviluppo un software con Delphi XE che gestisce un database in postgresql.
Utilizzo inoltre una dll scritta in Delphi4 per alcune funzioni che scrissi a suo tempo.

Disribuisco il software di cui sopra a diverse centinaia di utilizzatori senza problemi, ma su talune macchine, a prescindere dal OS utilizzato (XP, Win7, Vista, Win8), ho un access violation nel momento in cui vado a chiamare una funzione della su detta dll.

Preciso che la casisticha delle macchine che mi danno il problema è del 2 % circa delle installazioni fatte e preciso anche è successo più volte che installato il programma va tutto bene. Poi dopo un po di tempo il cliente chiama e viene riscontrato il problema. Quindi qualcosa è cambiato nella macchina, non certo nel programma o nella dll.

Mi domando cosa posso andare a verificare sulla macchina per risolvere il problema senza dover formattare necessariamente.

Di seguito riporto la chiamata della funzione alla DLL

FUNCTION PARS410(Source,
sP, sIV: PAnsiChar;
ToC, bBase: boolean;
iTipo: byte=1;
bPadR:boolean=False): PAnsiChar; external DLL_FUNZIONI;

l'access violation si verifica nel momento in cui viene restituito il valore della funzione come nell'esempio seguente:

var sResult :String;
...
sRESULT := PARS410(pAnsiChar(a1), pAnsiChar(a2), pAnsiChar(a3), bCri, True, iTipo, iCampo <= 2) ;

Ripeto sulla stragrande maggioranza delle macchine non ho nessun problema con il medesimo programma e la medesima dll

che significa?

un grazie anticipato a chiunque sappia o provi a suggerirmi qualcosa

2 Risposte

  • Re: AccessViolation su dll solo per alcuni computer

    Si possono fare solo ipotesi e quello che secondo me succede è che parte del codice presenta un problema che si può presentare molto raramente (ovvero, in certe specifiche condizioni).

    Non ho capito se tu hai il codice sorgente della

    PARS410

    o no.
  • Re: AccessViolation su dll solo per alcuni computer

    Grazie per avermi risposto, in ogni caso certamente ho il codice della funzione nella DLL, lo scrivo di seguito.

    Da notare che nel codice creo una TStringList e assegno un valore
    ssss:=tstringlist.create;
    ssss.Text := sTmp;
    Cosi facendo, le mcchine che darebbero Access Violation superano il problema non dando l'eccezione. Si tratta però di una "zozzatura" di codice e vorrei evitarla. Inoltre non mi spiego cosa intervenga nella macchina da prima che funzionava tutto correttamente (senza quindi l'intervento di questa TSTringList) a poi che interviene questo access violation ??

    Grazie anticipatamente

    qui il codice nella DLL:
    FUNCTION PARS410(Source, sP, sIV: Pchar; ToC, bBase: boolean; iTipo: byte=1; bPadR:boolean=False): Pchar; 
    var
      Cipher : TDCP_blockcipher;
      sTmp, Key, IV: string;
      KeySize   : word; // = 32; // 32 bytes = 256 bits
      BlockSize : word; // = 16; // 16 bytes = 128 bits
    sDebug, SSS:String;
    ssss:tstringlist;
    
        function PadWithZeros(const str : String; size : integer) : String;
        var
          origsize, i : integer;
        begin
          Result := str;
          origsize := Length(Result);
          if ((origsize mod size) <> 0) or (origsize = 0) then
          begin
            SetLength(Result,((origsize div size)+1)*size);
            for i := origsize+1 to Length(Result) do
              Result[i] := #0;
          end;
        end;
    
    begin
      RESULT := '';
    
      if iTipo = 1 then begin
        Cipher := TDCP_Rijndael.Create(nil);
      end else
      if iTipo = 2 then begin
        Cipher := TDCP_3DES.Create(nil);
      end else begin
        Cipher := TDCP_DES.Create(nil);
      end;
    
      KeySize   := 32;  //poi faccio i multipli di 8 ??
      BlockSize := 16;  //poi faccio i multipli di 8 ??
    
      try
    
        Key := PadWithZeros(sP,  KeySize);
        IV  := PadWithZeros(sIV, BlockSize);
    
        Cipher.CipherMode := cmCBC;
    
        if Length(sP) <= 16 then begin
          Cipher.Init(Key[1],128,@IV[1]);
        end else
        if Length(sP) <= 24 then begin
          Cipher.Init(Key[1],192,@IV[1]);
        end else begin
          Cipher.Init(Key[1],256,@IV[1]);
        end;
    
        sTmp := Source;
    
        if ToC then begin
          if bPadR then begin
            While (Length(sTmp) mod 16) <> 0 do begin
              sTmp := sTmp + ' ';
            end;
            Source := pChar(sTmp);
          end;
    
          if bBase then begin
            Cipher.EncryptCBC(sTmp[1], sTmp[1], Length(sTmp));
            sTmp   := Base64EncodeStr(sTmp);
            RESULT := PChar(sTmp); //(Source);
          end else begin
            RESULT := PChar(Cipher.EncryptString(sTmp));
          end;
        end else begin
          if bBase then begin
            sTmp := Base64DecodeStr(sTmp);
            Cipher.DecryptCBC(sTmp[1], sTmp[1], Length(sTmp));
            RESULT := Pchar(sTmp);
          end else begin
            RESULT := Pchar(Cipher.DecryptString(sTmp));
          end;
        end;
    
        Cipher.Burn;
    
    
    ssss:=tstringlist.create;
    ssss.Text := sTmp;
    //ssss.free;
    
      finally
        Cipher.Free;
      end;
    end;
    
Devi accedere o registrarti per scrivere nel forum
2 risposte