Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Access Violation or Invalide Pointer operation [D7, XP]


balepa ©   (2007-10-17 07:23:00) 



type

TTx = packed record
   ADDR: Word;
   CMD: Byte;
   param: Byte;
   CRC: Word;
 end;

 TRx = packed record
   ADDR: Word;
   CMD: Byte;
   nnnn: Single;
   //nnnn: array[0..3] of BYTE;
   CODE: Byte;
   CRC: Word;
 end;

 TMW = packed record
   mwT: TDateTime;
   mw1,mw2: Single;
   mwSumm: Double;
   mwds,mwhs: Double;
 end;

var
 Form1: TForm1;
   .....
 RWBytes: Cardinal;
 Tx: TTx;
 Rx: TRx;
 CRC: Word;
 count,hCount: Cardinal;
 MW: TMW;
 uEventID: UINT;
 oldS,oldH,oldD: Word;
 f: _SYSTEMTIME;
 mwSummD,mwSummH: Single;

...

procedure ProcTime(uID, msg: UINT; dwUse, dw1, dw2: DWORD); stdcall;
begin
 timeKillEvent(uEventID);
 CRCError:= 0;
 Tx.ADDR:= 1190;
 Tx.CMD:= $40;
 Tx.param:= 0;
 Tx.CRC:= CalculateCRC16(@Tx,4); //44370
 ClearCommError(hComm,errors,@stat);
 SetCommMask(hComm,EV_TXEMPTY);
 WriteFile(hComm,Tx,6,RWBytes,nil);
 WaitCommEvent(hComm,mask,nil);
 sleep(6);
 ReadFile(hComm,Rx,10,RWBytes,nil);
 CRC:= CalculateCRC16(@Rx,8);

 asm
   mov DWORD ptr eax,Rx.nnnn
   bswap eax
   mov DWORD ptr mw.mw1, eax
 end;
 PurgeComm(hComm,PURGE_RXCLEAR or PURGE_TXCLEAR);

 mw.mwSumm:= MW.mw1 + mw.mw2;

 GetSystemTime(f);
 if oldH<>f.wHour then begin
   hcount:= 1;
   oldH:= f.wHour;
   mwSummH:= mw.mwSumm;
   mw.mwhs:= mwSummH;
 end
 else begin
   hCount:= hCount+1;
   mwSummH:= mw.mwSumm + mwSummH;
   mw.mwhs:= mwSummH / hcount;
 end;

 if oldD<>f.wDay then begin
   count:= 1;
   oldD:= f.wDay;
   mw.mwds:= mw.mwSumm;
 end
 else begin
   inc(count);
   mwSummD:= mw.mwSumm + mwSummD;
   mw.mwds:= mwSummD / count;
 end;

 if oldS<>f.wSecond then begin
     WriteFileNow;
     WriteFileArc;
 end;

 Form1.Label1.Caption:= IntToStr(f.wDay)+'.' + IntToStr(f.wMonth)+'.' + IntToStr(f.wYear)+'  '+ IntToStr(f.wHour)+':'+IntToStr(f.wMinute)+':'+IntToStr(f.wSecond)+':'+IntToStr(f.wMilliseconds);
 Form1.Label2.Caption:= 'MW = ' + FloatToStr(mw.mw1);
 Form1.Label3.Caption:= 'Count = ' + IntToStr(count);
 Form1.Label4.Caption:= 'hCount = ' + IntToStr(hcount);
 uEventID := timeSetEvent(orta[1],0,@ProcTime,0,1);

end;


Вот в этой процедуре выскакивает Access Violation или Invalide Pointer operation, последний раз mov [eax+$08],esi в InsertFree, но необязате льно в InsertFree иногда и в др. Но кажись они все относятся к менеджеру памяти


balepa   (2007-10-17 10:40:00) [1]

А я ж читал что он в своем потоке работает и благополучно забыл.

Спасибо за напоминание.


Сергей М.   (2007-10-17 10:13:00) [2]


> balepa ©   (17.10.07 09:38) [9]


Все фигня, кроме пчел.

"Пчелы" - это твои обращения к визуальным VCL-контролам в дополнительном потоке, что делать недопустимо.


Сергей М.   (2007-10-17 09:57:00) [3]


> Чародей   (17.10.07 09:52) [11]
>
> в делфи использовать асм просто так


Register use

In general, the rules of register use in an asm statement are the same as those of an external procedure or function. An asm statement must preserve the EDI, ESI, ESP, EBP, and EBX registers, but can freely modify the EAX, ECX, and EDX registers.

Правилом этим пользоваться можно, но осторожно, особенно при оптимизирующей компиляции.


Чародей   (2007-10-17 09:52:00) [4]

в делфи использовать асм просто так нельзя

> asm
>    mov DWORD ptr eax,Rx.nnnn
>    bswap eax
>    mov DWORD ptr mw.mw1, eax
>  end;

asm
   push eax
   mov DWORD ptr eax,Rx.nnnn
   bswap eax
   mov DWORD ptr mw.mw1, eax
   pop eax
 end;
иначе ошибка может проявляться в любой момент, этот же код посмотри в отладчике, что esi и edi не поменялись
PS: я обычно использовал pusha и popa чтоб не заморачиваться


Сергей М.   (2007-10-17 09:42:00) [5]


> Как тут трассировать ?


Ставишь брейкпойнт

procedure ProcTime(uID, msg: UINT; dwUse, dw1, dw2: DWORD); stdcall;
begin
 <- сюда

И вперед, с песней !)


balepa   (2007-10-17 09:38:00) [6]


> Сергей М. ©   (17.10.07 09:27) [8]
>
> > Если б я знал
>
> Как это так ?!
>
> Ты вообще пошагово трассировал свой код ?


uEventID := timeSetEvent(orta[1],0,@ProcTime,0,1);

ProcTime вызывается каждые ~500 мс ошибка возникает когда как, то через несколько секунд, иногда через минуту
Как тут трассировать ?


Сергей М.   (2007-10-17 09:27:00) [7]


> Если б я знал


Как это так ?!

Ты вообще пошагово трассировал свой код ?


balepa   (2007-10-17 09:21:00) [8]


> Сергей М. ©   (17.10.07 09:07) [6]
> И какой резон в в этом bswap ? Поясни ..


Порядок байт поменять в Rx.nnnn, что бы правильно показывало


> На какой конкретно строке ?

Если б я знал.
Просто вылетает AV потом CPU типа

InsertFree:
.
.
.
.
.

mov [eax+$08],esi
.
.
.
.
в  последний раз было в GetSysMem


Сергей М.   (2007-10-17 09:07:00) [9]


> balepa ©   (17.10.07 09:01) [5]
>
>


> Single = 4 байта


Да, верно. Миль пардон.

Тогда зачем DWORD PTR ?

И какой резон в в этом bswap ? Поясни ..


> даже если закоментировать этот кусок AV вылетает


На какой конкретно строке ?


balepa   (2007-10-17 09:01:00) [10]


> Сергей М. ©   (17.10.07 08:53) [3]
>
> > дело сейчас не в этом
> Но начать следует именно с этого.


Тут до этого столько всего было... даже если закоментировать этот кусок AV вылетает


> SizeOf(Single) = SiseOf(Word), с какой же перепугу DWORD


Single = 4 байта
DWORD = Types.LongWord = 4 байта
Word 2 байта
или нет ?


Сергей М.   (2007-10-17 08:57:00) [11]

>  asm
>    mov DWORD ptreax,Rx.nnnn
>    bswap eax
>    mov DWORD ptrmw.mw1, eax
>  end;


Непонятно, что это вообще за выкрутасы ?

SizeOf(Single) = SiseOf(Word), с какой же перепугу DWORD?


Сергей М.   (2007-10-17 08:53:00) [12]


> дело сейчас не в этом


Но начать следует именно с этого.


balepa   (2007-10-17 07:58:00) [13]


> MBo ©   (17.10.07 07:54) [1]
> не слишком ли смело использовать негарантированно инициализированный
> eax ?
>
> asm
>   mov DWORD ptr eax

Может, но дело сейчас не в этом. И без

asm
  mov DWORD ptr eax,Rx.nnnn
  bswap eax
  mov DWORD ptr mw.mw1, eax
end


AV вылетает, я неуверен но кажется при обращении к полям Record'ов.


MBo   (2007-10-17 07:54:00) [14]

не слишком ли смело использовать негарантированно инициализированный eax ?

asm
  mov DWORD ptr eax


Наверх

Титульная страница Поиск, карта сайта Написать письмо