如何解释RtlLeaveCriticalSection中的访问冲突 [英] How to explain access violation in RtlLeaveCriticalSection

查看:314
本文介绍了如何解释RtlLeaveCriticalSection中的访问冲突的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个应用程序,请求一个表单上的计时器触发的数据库中的数据。如果有错误(与数据库的连接丢失),我有时会得到预期的异常(EIBO_ISCError),有时我会在ntdll.dll的RtlLeaveCriticalSection中获得访问冲突。这是对应的Eurekalog堆栈:

  ------------------- -------------------------------------------------- --------------------------------- 
| Adresse | Modul | Unit | Klasse | Prozedur / Methode | Zeile |
---------------------------------------------- -------------------------------------------------- ------
| Laufender主题:ID = 1320; Priorität= 0;的Klasse =; [Haupt Thread] |
| --------------------------------------------- -------------------------------------------------- ----- |
| 76FD2280 | ntdll.dll | | | RtlLeaveCriticalSection | |
| 76FDE0ED | ntdll.dll | | | RtlAllocateHeap | |
| 76FE6CC5 | ntdll.dll | | | LdrUnlockLoaderLock | |
| 7552EF19 | KERNELBASE.dll | | | VirtualQueryEx | |
| 7552EF02 | KERNELBASE.dll | | | VirtualQueryEx | |
| 7552EFE6 | KERNELBASE.dll | | | VirtualQuery | |
| 76FC012E | ntdll.dll | | | KiUserExceptionDispatcher | |
| 0069D997 | Program.exe | IBODataset.pas | TIBOInternalDataset | DoHandleError | 8407 [23] |
| 0063B3F7 | Program.exe | IB_Components.pas | TIB_Session | DoHandleError | 13181 [2] |
| 0068B36C | Program.exe | IB_Session.pas | TIB_SessionBase | HandleException | 1442 [58] |
| 0068B03C | Program.exe | IB_Session.pas | TIB_SessionBase | HandleException | 1384 [0] |
| 0064EE74 | Program.exe | IB_Components.pas | TIB_Statement | API_Execute | 22927 [14] |
| 0064EE10 | Program.exe | IB_Components.pas | TIB_Statement | API_Execute | 22913 [0] |
| 00655D1D | Program.exe | IB_Components.pas | TIB_Dataset | SysExecSelect | 26432 [1] |
| 0064DA60 | Program.exe | IB_Components.pas | TIB_Statement | SysExecStatement | 22259 [9] |
| 0064D7A1 | Program.exe | IB_Components.pas | TIB_Statement | SysExecute | 22173 [12] |
| 0064D708 | Program.exe | IB_Components.pas | TIB_Statement | SysExecute | 22161 [0] |
| 00655A9F | Program.exe | IB_Components.pas | TIB_Dataset | SysExecute | 26373 [7] |
| 00655210 | Program.exe | IB_Components.pas | TIB_Dataset | SysOpen | 26160 [23] |
| 006550F8 | Program.exe | IB_Components.pas | TIB_Dataset | SysOpen | 26137 [0] |
| 006994E5 | Program.exe | IBODataset.pas | TIBODataset | DoBeforeOpen | 6312 [17] |
| 0061FBEA | Program.exe | mvdb.pas | TImvDatabase | QueryRun | 1393 [10] |
...
| 00B1D440 | Program.exe | StartDialogForm.pas | TFormStartDialog | UpdateStartBar | 494 [0] |
| 00B1D4C3 | Program.exe | StartDialogForm.pas | TFormStartDialog | TimerExBarTimer | 521 [6] |
| 76667BC5 | USER32.dll | | | DispatchMessageA | |
| 76667BBB | USER32.dll | | | DispatchMessageA | |
| 00BF1178 | Program.exe | Program.dpr | | | 884 [399] |
---------------------------------------------- -------------------------------------------------- ------

执行的代码没有什么特别之处。它归结为:

  qry:= TIBOQuery.Create(nil); // IBObjects 
qry.SQL:='SELECT COUNT(IDX)FROM TABLE';
qry.Prepare;

创建表单和

  qry.Open; //<  -  Exception 
TotalCount:= qry.Fields [0] .AsVariant;
qry.Close;在MDI窗体的OnTimer事件中,



  raise EIBO_ISCError.CreateISC(...); 

底层异常很可能是由于在qry.Open中丢失的数据库连接造成的。我想知道的是,哪些情况(在我的代码中读取缺陷)可能导致行为,有时这个异常按预期(Eurekalog中的EIBO_ISCError)进行处理,有时相同的异常会导致RtlLeaveCriticalSection中的访问冲突。 p>

解决方案

看起来你有堆腐败。在某个地方,你的程序已经写入了你不应该写的内存。



这可能意味着你已经写到属于堆,但这可能意味着你写的其他地方导致内存管理器认为有一个关键部分的对象,其中真的没有一个。



堆栈跟踪表明您仍然会收到您期望获得的通常异常,但是在尝试处理该异常时出现问题。



您可以尝试使用调试器检查发生无效读取附近的其他内存。看看你的程序中是否有任何字符串或数字。他们可以指出哪段代码写在哪里不应该。


I have an application that requests data from a database triggered by a timer on a form. If there is an error (the connection to the database is lost), I sometimes I get the expected exception (EIBO_ISCError) and sometimes I get an access violation in RtlLeaveCriticalSection of ntdll.dll. Here is the corresponing Eurekalog stack:

------------------------------------------------------------------------------------------------------
|Adresse |Modul         |Unit               |Klasse             |Prozedur/Methode          |Zeile    |
------------------------------------------------------------------------------------------------------
|Laufender Thread: ID=1320; Priorität=0; Klasse=; [Haupt Thread]                                     |
|----------------------------------------------------------------------------------------------------|
|76FD2280|ntdll.dll     |                   |                   |RtlLeaveCriticalSection   |         |
|76FDE0ED|ntdll.dll     |                   |                   |RtlAllocateHeap           |         |
|76FE6CC5|ntdll.dll     |                   |                   |LdrUnlockLoaderLock       |         |
|7552EF19|KERNELBASE.dll|                   |                   |VirtualQueryEx            |         |
|7552EF02|KERNELBASE.dll|                   |                   |VirtualQueryEx            |         |
|7552EFE6|KERNELBASE.dll|                   |                   |VirtualQuery              |         |
|76FC012E|ntdll.dll     |                   |                   |KiUserExceptionDispatcher |         |
|0069D997|Program.exe   |IBODataset.pas     |TIBOInternalDataset|DoHandleError             |8407[23] |
|0063B3F7|Program.exe   |IB_Components.pas  |TIB_Session        |DoHandleError             |13181[2] |
|0068B36C|Program.exe   |IB_Session.pas     |TIB_SessionBase    |HandleException           |1442[58] |
|0068B03C|Program.exe   |IB_Session.pas     |TIB_SessionBase    |HandleException           |1384[0]  |
|0064EE74|Program.exe   |IB_Components.pas  |TIB_Statement      |API_Execute               |22927[14]|
|0064EE10|Program.exe   |IB_Components.pas  |TIB_Statement      |API_Execute               |22913[0] |
|00655D1D|Program.exe   |IB_Components.pas  |TIB_Dataset        |SysExecSelect             |26432[1] |
|0064DA60|Program.exe   |IB_Components.pas  |TIB_Statement      |SysExecStatement          |22259[9] |
|0064D7A1|Program.exe   |IB_Components.pas  |TIB_Statement      |SysExecute                |22173[12]|
|0064D708|Program.exe   |IB_Components.pas  |TIB_Statement      |SysExecute                |22161[0] |
|00655A9F|Program.exe   |IB_Components.pas  |TIB_Dataset        |SysExecute                |26373[7] |
|00655210|Program.exe   |IB_Components.pas  |TIB_Dataset        |SysOpen                   |26160[23]|
|006550F8|Program.exe   |IB_Components.pas  |TIB_Dataset        |SysOpen                   |26137[0] |
|006994E5|Program.exe   |IBODataset.pas     |TIBODataset        |DoBeforeOpen              |6312[17] |
|0061FBEA|Program.exe   |mvdb.pas           |TImvDatabase       |QueryRun                  |1393[10] |
...
|00B1D440|Program.exe   |StartDialogForm.pas|TFormStartDialog   |UpdateStartBar            |494[0]   |
|00B1D4C3|Program.exe   |StartDialogForm.pas|TFormStartDialog   |TimerExBarTimer           |521[6]   |
|76667BC5|USER32.dll    |                   |                   |DispatchMessageA          |         |
|76667BBB|USER32.dll    |                   |                   |DispatchMessageA          |         |
|00BF1178|Program.exe   |Program.dpr        |                   |                          |884[399] |
------------------------------------------------------------------------------------------------------

The code, which is executed, is nothing special. It boils down to:

qry := TIBOQuery.Create(nil);      //IBObjects
qry.SQL := 'SELECT COUNT(IDX) FROM TABLE';
qry.Prepare;

when creating the form and

qry.Open;       //<-- Exception
TotalCount := qry.Fields[0].AsVariant;
qry.Close;

in the OnTimer event of the MDI form.

The code line in IBObjects that is called in DoHandleError is

raise EIBO_ISCError.CreateISC( ... );

The underlaying exception is likely to be caused by a lost database connection in qry.Open. What I want to know is, which circumstances (read defects in my code) can lead to the behaviour, that sometimes this exception is handled as expected (EIBO_ISCError in Eurekalog) and sometimes the same exception leads to an access violation in RtlLeaveCriticalSection.

解决方案

It looks like you have heap corruption. Somewhere, your program has written to memory that you're not supposed to write to.

That might mean you've written to a critical-section data structure belonging to the heap, but it might mean you've written somewhere else that caused the memory manager to think there's a critical-section object where there really isn't one.

The stack trace suggests you're still getting the usual exception you expected to get, but in attempting to handle that exception, something goes wrong.

You could try using the debugger to inspect other memory near where the invalid read occurs. See whether there are any strings or numbers you recognize from your program. They could indicate which section of code is writing where it shouldn't.

这篇关于如何解释RtlLeaveCriticalSection中的访问冲突的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆