cs_mounjetado
Messages postés66Date d'inscriptionlundi 13 mars 2006StatutMembreDernière intervention 4 août 2008
-
28 sept. 2007 à 14:47
cs_mounjetado
Messages postés66Date d'inscriptionlundi 13 mars 2006StatutMembreDernière intervention 4 août 2008
-
1 oct. 2007 à 12:19
bonjour,
je reviens vers vous aujourd'hui avec un petit souci récurrent tout à fait incompréhensible.
en effet, j'ai une erreur EInvalidPointer qui apparaît à l'écran après 204 passes d'un point d'arrêt.
en exécutant pas à pas, je passe dans du code assembleur qui parle ci et là de Heap(le tas semble-t-il, après une recherche dans un dictionnaire FR-EN).
j'explique un peu le déroulement de mon programme:
une appli console tourne en permanence et appelle une procedure en callback.
celle-ci fait appel à une fonction dans une autre unité, fonction publique d'un objet de mon cru.
cette fonction appelle enfin une fonction dans une DLL, lui passant deux entiers en paramètres, et recevant un type à moi (en fait un tableau bi-dimensionnel, dont une dimension est dynamique:
TWholeMeasure = Array of TMeasure;
TMeasure = Array[0..7] of Word; ).
je réceptionne mes valeurs sans problème, tout en comptant le nombre de TWholeMeasure reçus, et donc je ne m'explique pas ce plantage pour le moins curieux.
si encore ça plantait à tous les coups, ou bien à un endroit précis... mais en pas-à-pas, je sors de ma fonction contenue dans la DLL pour ne jamais retourner dans la méthode appelante!
notez que le numéro de la passe au point d'arrêt n'est ni 203 ni 205 ni 200, mais 204 et seulement 204! allez savoir pourquoi! d'ailleurs, c'est ce que j'attends de vous: l'illumination géniale pour que je parte moins bête en week-end...
un sacréddéfi pour DelphiProg sûrement; il a l'air très calé sur les pointeurs...
à bientôt de vous lire et grand merci à vous tous
f0xi
Messages postés4205Date d'inscriptionsamedi 16 octobre 2004StatutModérateurDernière intervention12 mars 202235 28 sept. 2007 à 19:49
sans code ça vas etre dur de t'aider.
EInvalidPointer est déclenchée quand une application tente une opération incorrecte sur des pointeurs.Par exemple,cette exception se produit si une application essaye de libérer deux fois le même pointeur ou de faire référence à un pointeur déjà libéré.
Remarque : Ne déclenchez jamais directement d'exception EInvalidPointer.EInvalidPointer est déclenchée en interne par le gestionnaire de mémoire.
cs_mounjetado
Messages postés66Date d'inscriptionlundi 13 mars 2006StatutMembreDernière intervention 4 août 2008 29 sept. 2007 à 09:54
ok lundi dès mon arrivée au boulot je vous mets le code.
mais pouvez-vous me dire si on peut le mettre en fichiers attachés et si oui comment?
sinon je coperai ce que je pense être le strict nécesaire à la compréhension et la résolution de mon problème.
bon week-end et à lundi donc!
{-------- TABLEAU des codes du registre de contrôle --------}
{-------- SANS DONGLE SUR PORT PARALLELE --------}
{logique} {physique}
{C O E T} {C O E T}
OFF = 02; { VALEUR DE REPOS } {0 0 1 0} {1 0 0 1}
PCD = 32; { bit 5 du registre de contrôle pour configurer
la direction du flux de données sur port parallèle étendu (ECP/EPP); 1 lecture, 0 écriture }
IMPORT = TRIG+PCD;
procedure entree( pp1_adr : word;
var octet : byte ); assembler;
var temp : word;
begin
asm
MOV DX,[pp1_adr]
MOV AH,$00
IN AL,DX
MOV temp,AX
end;
octet:=LO(temp);
end;
procedure anal_out( reg : integer;
octet : byte );
begin
// val:=ECR;
sortie((p1_ad+2),ECR); {verrouiller les canaux de mesure; ouvrir DAC}
sortie((p1_ad+0),octet); {charger valeur 0..255 dans le port de donnees}
if reg = 1
then begin
// val:=ECR+1; {REG1 de DAC selectionne par defaut; voir OFF}
sortie((p1_ad+2),ECR+1); {envoyer TRIG en gardant ECR}
end
else begin
// val:=ECR+4; {en deux pas...}
sortie((p1_ad+2),ECR+4); {- selectionner REG2 de DAC en gardant ECR}
// val:=val+1; {- envoyer TRIG en gardant ECR & OUT2}
sortie((p1_ad+2),ECR+5);
end;
// val:=OFF;
sortie((p1_ad+2),OFF);
end;
procedure synchro_carte(const d, f : SmallInt); pascal;
var i,j : Integer;
begin
for i:=d to f do
begin
// val:=CONV;
sortie((p1_ad+2),CONV);
for j:=1 to 350*multiple do;
// val:=OFF; {se promener entre les 4 cartes max et}
sortie((p1_ad+2),OFF); { le nombre reel de cartes branchees }
for j:=1 to 350*multiple do;
end;
end;
procedure init_carte; pascal;
begin
sortie((p1_ad+2),ECR);
sortie((p1_ad+2),INIT);
sortie((p1_ad+2),ECR);
sortie((p1_ad+2),OFF);
synchro_carte(1,3);
end;
function noyau_mes( const mc, ms, accuracy : SmallInt) : TMeasure; pascal;
var n,m : integer;
bit : integer;
op : byte;
octet : byte;
canal : TMeasure;
begin
for bit:=ChValFormat-1 downto 0 do {initialiser tous les canaux}
canal[bit]:=0;
for m:=1 to 2500*multiple do; {boucle d'attente -----> indisp. pour}
{éviter des crêtes; aussi: f_eff=11kHz}
if ((mc<mcMax) and (ms=mcMin-1))
then for n:=accuracy downto 1
do begin
sortie((p1_ad+2),TRIG);
for m:=1 to 300*multiple do;
sortie((p1_ad+2),OFF);
for m:=1 to 300*multiple do;
end;
sortie((p1_ad+2),CONV); {Impulsion de conv./preset }
if ms=1 {..... boucle d'attente: }
then for m:=1 to 3800*multiple do; {faire durer cette impulsion 20µs}
sortie((p1_ad+2),OFF); {avant remise }
for m:=1 to 2000*multiple do;
for n:=accuracy downto 1
do begin
sortie((p1_ad+2),IMPORT); { 32: bit interne du registre de }
for m:=1 to 300*multiple do; { contrôle pour la lecture... }
entree((p1_ad+0),octet); { fait entrer l'octet de données }
for bit:=7 downto 0
do begin
canal[bit]:=canal[bit] shl 1;
op:=(1 shl bit);
if (octet and op)=op
then inc(canal[bit]);
end;
sortie((p1_ad+2),OFF);
for m:=1 to 300*multiple do;
end;
Result := canal;
end;
function global_mes( const mc, accuracy : SmallInt) : TWholeMeasure; pascal;
var cps : SmallInt; {cartes presentes successives}
tabmes : TWholeMeasure;
begin
SetLength(tabmes,mc);
for cps:=Low(tabmes) to High(tabmes) do
tabmes[cps]:=noyau_mes(mc,cps,accuracy);
synchro_carte(mc+1,mcMax);
Result := tabmes;
tabmes := nil;
end;
var
ChannelsInitValues : TMeasure; //= (0,0,0,0,0,0,0,0);
ModId : SmallInt;
implementation
uses
SysUtils;
{ TMeasureAcquirer }
function TMeasureAcquirer.GetTORActivation : Boolean;
begin
Result := FTORActivation;
end;
procedure TMeasureAcquirer.SetTORActivation(const ATORActivation : Boolean);
begin
FTORActivation := ATORActivation;
end;
function TMeasureAcquirer.GetTORStatus : Byte;
begin
Result := FTORStatus;
end;
procedure TMeasureAcquirer.SetTORStatus;
begin
FTORStatus := Byte(LO(FWholeMeasure[mcMin-1,chHWCntTOR] AND $0007))
end;
function TMeasureAcquirer.GetSensorsAccuracy : SmallInt;
begin
Result := FSensorsAccuracy;
end;
procedure TMeasureAcquirer.SetSensorsAccuracy(const NewAccurIndex : SmallInt);
begin
FSensorsAccuracy := NewAccurIndex;
end;
function TMeasureAcquirer.GetModulesCount : SmallInt;
begin
Result := FModulesCount;
end;
procedure TMeasureAcquirer.SetModulesCount(const NewModCount : SmallInt);
begin
if ((NewModCount<mcMin) OR (NewModCount>mcMax))
then Exit //ShowMessage('Nombre de modules non-valide')
else FModulesCount := NewModCount;
end;
function TMeasureAcquirer.GetActiveModule : SmallInt;
begin
Result := FActiveModule;
end;
procedure TMeasureAcquirer.SetActiveModule(const NewModActive : SmallInt);
begin
if ((NewModActive<mcMin) OR (NewModActive>mcMax))
then Exit //ShowMessage('Nombre de modules non-valide')
else FActiveModule := NewModActive;
end;
function TMeasureAcquirer.GetMovingWay : SmallInt;
begin
Result := FMovingWay;
end;
procedure TMeasureAcquirer.SetMovingWay(const AMovingWay : SmallInt);
begin
FMovingWay := AMovingWay;
end;
function TMeasureAcquirer.GetMeasuresCount : Int64;
begin
Result := FMeasuresCount;
end;
function TMeasureAcquirer.GetDeviceClockCount : Int64;
begin
Result := FDeviceClockCount;
end;
procedure TMeasureAcquirer.SetDeviceClockCount;
begin
FDeviceClockCount := FWholeMeasure[mcMin-1,chHWCntTOR];
end;
function TMeasureAcquirer.GetSystemClockFreq : Int64;
begin
Result := FSystemClockFreq;
end;
function TMeasureAcquirer.GetSystemClockCount : Int64;
begin
Result := FSystemClockCount;
end;
procedure TMeasureAcquirer.SetSystemClockCount;
begin
if QueryPerformanceFrequency(FSystemClockFreq)
then QueryPerformanceCounter(FSystemClockCount)
else FSystemClockCount := GetTickCount;
end;
procedure TMeasureAcquirer.CaptureModuleMeasure;
begin
FModuleMeasure := noyau_mes(FModulesCount,FActiveModule,FSensorsAccuracy);
end;
function TMeasureAcquirer.ProcessModuleMeasure : Boolean;
begin
try
ExitCode := MEASURE_NO_ERROR;
Inc(FMeasuresCount);
CaptureModuleMeasure;
SetSystemClockCount;
SetTORStatus;
if ((FSensorsAccuracy=caHigh) and TORActivation)
then ShiftR3ModuleMeasure;
except
//Définit ExitCode <> MEASURE_NO_ERROR pour indiquer la condition d'erreur (par convention)
ExitCode := MEASURE_PICKING_ERROR;
//Gérer la condition d'erreur
Dec(FMeasuresCount);
SetLastError(ExitCode);
end; Result :(ExitCode MEASURE_NO_ERROR);
end;
procedure TMeasureAcquirer.ShiftR3ModuleMeasure;
var bit : SmallInt;
hs : SmallInt;
begin
for bit:= Low(FModuleMeasure) to High(FModuleMeasure) { MSB=15 mais AD7806, }
do FModuleMeasure[bit] := FModuleMeasure[bit] shr 3; { i.e. 12 bits }
end;
function TMeasureAcquirer.GetModuleMeasure : TMeasure;
begin
Result := FModuleMeasure;
end;
procedure TMeasureAcquirer.CaptureWholeMeasure;
begin
FWholeMeasure := global_mes(FModulesCount,FSensorsAccuracy);
end;
function TMeasureAcquirer.ProcessWholeMeasure : Int64;
begin
try
ExitCode := MEASURE_NO_ERROR;
Inc(FMeasuresCount);
CaptureWholeMeasure;
SetSystemClockCount;
if (FSensorsAccuracy=caHigh)
then begin
if TORActivation
then SetTORStatus;
ShiftR3WholeMeasure;
end;
SetDeviceClockCount;
Result := GetMeasuresCount;
except
//Définit ExitCode <> MEASURE_NO_ERROR pour indiquer la condition d'erreur (par convention)
ExitCode := MEASURE_PICKING_ERROR;
//Gérer la condition d'erreur
Dec(FMeasuresCount);
SetLastError(ExitCode);
Result := -1;
end;
end;
procedure TMeasureAcquirer.ShiftR3WholeMeasure;
var bit : SmallInt;
hs : SmallInt;
begin
for hs:= Low(FWholeMeasure) to High(FWholeMeasure)
do for bit:= Low(FWholeMeasure[hs]) to High(FWholeMeasure[hs]) { MSB=15 mais AD7806, }
do FWholeMeasure[hs,bit] := FWholeMeasure[hs,bit] shr 3; { i.e. 12 bits }
end;
function TMeasureAcquirer.GetWholeMeasure : TWholeMeasure;
begin
Result := FWholeMeasure;
end;
procedure TMeasureAcquirer.Change;
begin
if Assigned(FOnChange) then FOnChange(Self);
end;
procedure TMeasureAcquirer.CaptureTerminated( Sender: TObject );
begin
if MeasuresList<>nil
then if Odd(ChangeList)
then ThreadMeasuresList1.UnlockList
else ThreadMeasuresList0.UnlockList;
end;
uses
SysUtils,
Windows,
Dialogs,
Classes,
uCommonTypesandValues in '..\MesSources\uCommonTypesandValues.pas',
uParalPortR in '..\MesSources\uParalPortR.pas';
procedure ProceedMeasure;
var ch : SmallInt;
OneCompleteMeasure : TCompleteMeasure;
TempWholeMeasure : TWholeMeasure;
begin
iMeasureCount := WalkMeasureAcquirer.ProcessWholeMeasure;
end;
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
///////////////////////////// PROGRAMME PRINCIPAL /////////////////////////////
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
begin
//////////////////////////////////////////////////////////////
// PARAMETRES A ENVOYER LORS DE L'EXECUTION //
// PAR LIGNE DE COMMANDE OU //
// EN TANT QUE SERVICE //
//////////////////////////////////////////////////////////////
// Lecture des paramètres de la ligne de commande pour déterminer
// le fichier de configuration à prendre en compte
pchCmdLn := PAnsiChar('StrengthPlate');
// pchCmdLn := GetCommandLine;
sConfigFileName := String(pchCmdLn) + 'Config.txt';
// Récupère le handle sur l'évenement créé par le programme principal
// grâce à son nom (il faut évidemment mettre le même dans les deux applis !!)
MeasureCloseEvent := OpenEvent(EVENT_ALL_ACCESS, False, 'MEASURE_CONSOLE_CLOSE_EVENT');
iConverterAccuracy := StrToInt(ConfigList.ValueFromIndex[ConfigList.IndexOfName('ConverterAccuracy')]);
bTOREnabled := StrToBool(ConfigList.ValueFromIndex[ConfigList.IndexOfName('TOREnabled')]);
iPresentModulesCount := StrToInt(ConfigList.ValueFromIndex[ConfigList.IndexOfName('PresentModulesCount')]);
iMeasureLength := StrToInt(ConfigList.ValueFromIndex[ConfigList.IndexOfName('MeasureLength')]);
iFrequency := StrToInt(ConfigList.ValueFromIndex[ConfigList.IndexOfName('Frequency')]);
except
//Définit ExitCode <> MEASURE_NO_ERROR pour indiquer la condition d'erreur (par convention)
ExitCode := GetLastError;
//Gérer la condition d'erreur
sWrite := 'Exception imprévue dans la lecture du fichier texte de configuration ('
+ IntToStr(ExitCode) + ')';
JournalList.Add(sWrite);
raise Exception.Create(sWrite);
ExitProcess(ExitCode);
end;
finally
// Libération de la mémoire
ConfigList.Free;
TestInfoList.Free;
end;
try
// Data File Creation
try
hDataFileHandle := CreateFile( PAnsiChar(sStoreDefaultPath + sResultsDirectory + sDataFileName),
GENERIC_READ or GENERIC_WRITE,
FILE_SHARE_READ or FILE_SHARE_WRITE,
saDataFileSecAttr,
CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
0);
except
// Définit ExitCode <> MEASURE_NO_ERROR pour indiquer la condition d'erreur (par convention)
ExitCode := GetLastError;
// Gérer la condition d'erreur
sWrite := 'Exception imprévue dans la création du fichier de mesures ('
+ IntToStr(ExitCode) + ')';
raise Exception.Create(sWrite);
JournalList.Add(sWrite);
CloseHandle(hDataFileHandle);
ExitProcess(ExitCode);
end;
// Acquisition Board Object Creation
try
WalkMeasureAcquirer := TMeasureAcquirer.CreateSelf( iPresentModulesCount,
iConverterAccuracy,
iMovingWay,
bTOREnabled);
except
//Définit ExitCode <> MEASURE_NO_ERROR pour indiquer la condition d'erreur (par convention)
ExitCode := GetLastError;
//Gérer la condition d'erreur
sWrite := 'Exception imprévue dans la définition du système ('
+ IntToStr(ExitCode) + ')';
JournalList.Add(sWrite);
raise Exception.Create(sWrite);
ExitProcess(ExitCode);
end;
// Once Critical Section Initialization
try
InitializeCriticalSection(RTLCriticSection);
except
//Définit ExitCode <> MEASURE_NO_ERROR pour indiquer la condition d'erreur (par convention)
ExitCode := GetLastError;
//Gérer la condition d'erreur
sWrite := 'Exception imprévue dans la création de la variable de données ('
+ IntToStr(ExitCode) + ')';
JournalList.Add(sWrite);
raise Exception.Create(sWrite);
ExitProcess(ExitCode);
end;
// Program Main Loop
while not ShouldClose // Closing Condition
do try
// Prise de mesure
EnterCriticalSection(RTLCriticSection);
ProceedMeasure;
LeaveCriticalSection(RTLCriticSection);
// Temporisation
// Sleep(1);
// Test de la condition de fermeture de l'application console ShouldClose :WaitForSingleObject(MeasureCloseEvent, 0) WAIT_OBJECT_0;
except
//Définit ExitCode <> 0 pour indiquer la condition d'erreur (par convention)
ExitCode := GetLastError;
//Gérer la condition d'erreur
sWrite := 'Fin de programme dûe à une exception dans la boucle principale ('
+ IntToStr(ExitCode) + ')';
JournalList.Add(sWrite);
raise Exception.Create('Exception imprévue dans la boucle principale');
ExitProcess(ExitCode);
end;
finally
// Libération de la mémoire
DeleteCriticalSection(RTLCriticSection);
CloseHandle(hDataFileHandle);
// Libération de l'évenement
ResetEvent(MeasureCloseEvent);
CloseHandle(MeasureCloseEvent);
// Sauvegarde des évenements survenus pendant le test
JournalList.SaveToFile(sStoreDefaultPath + sResultsDirectory + sJournalFileName);
JournalList.Free;
WalkMeasureAcquirer.Destroy;
end;
effectivement mon application atterrit tout droit dans la méthode _FreeMem qui reçoit en paramètre un pointeur. mais je n'arrive pas vraiment à cerner à quel moment cela se passe ni avec quel pointeur (sinon je ne serais pas là à vous implorer lol). par contre ce n'est pas sûr que ce soit tout le temps à la passe 204 de mon point d'arrêt que l'erreur se produit... mais elle revient plus ou moins régulièrement...