AccessViolation su dll solo per alcuni computer

di Anonimizzato12685 il
2 risposte
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

  • 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.
  • 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