Jump to content
Lars Fosdal

Read of address DEADBEE7. - Source of this raise?

Recommended Posts

Does anyone recognize that seemingly hardcoded address?

The call stack indicates that it happens in Rio 10.3.1 source - but searching the source does not yield anything.
Can it be Eurekalog that tries to tell me something about referencing a deleted or inaccessible piece of memory?

 

#BAD: EAccessViolation: Access violation at address 0040CEEC in module 'MyApp.exe'. Read of address DEADBEE7.
DBServer\INDUSTRIELL\DBName # 3017235 20.03.2019 13:23:06 (Brukerinterface, CRITICAL)
MyApp_ClientId @ [0040CEEC] System._UStrAsg
__________ CallStack
[0040CEEC] System._UStrAsg
[01561AF4] System.Generics.Collections.pas.{GridSet}TGridSet.TFieldValue<System.string>.SetValue (Line 4745, "System.Generics.Collections.pas")
[0156241F] System.Generics.Collections.pas.{GridSet}TGridSet.TFieldValue<System.string>.CopyRow (Line 4745, "System.Generics.Collections.pas")
[01558452] GridSet.TGridSet.CopyRow (Line 1002, "GridSet.pas")
[01B92885] frmPSDExpeditionDeliveries2.TDeliverySet.UpdateFromDeliverySet (Line 4108, "frmPSDExpeditionDeliveries2.pas")
[01B8F919] frmPSDExpeditionDeliveries2.TDeliveryGrid.RefreshByRouteList (Line 3671, "frmPSDExpeditionDeliveries2.pas")

 

Share this post


Link to post

Also spotted: Read of address DEADC00B.

Normally I'd expect to see things like this
EUseAfterFreeError: Application made attempt to call method of already deleted object: $071EC5A0 OBJECT [TMyClass] 404 bytes.

Share this post


Link to post
Posted (edited)

Programmers jokes, there exist a couple of these "HEX speak" or "magic number" addresses: DEADC0DE, DEADBEEF...

https://en.wikipedia.org/wiki/Hexspeak

 

I use them as constraints in unittesting to check that a peer or protocol is using the expected values.

 

So the programmer wants to tell you something...

Edited by GPRSNerd

Share this post


Link to post

In such situation I usually try other debugging tools and compare results. In my list I have FastMM4 in FullDebugMode and SafeMM: https://stackoverflow.com/questions/1039646/trying-to-locate-safemm-for-delphi The last one is especially useful when you want to see precise line of code with the bug. If nothing helps, then I read this article: https://www.eurekalog.com/help/eurekalog/eaccessviolation.php

And especially list of mistakes that can cause AV. Usually it is one of them.

Share this post


Link to post
Posted (edited)
2 hours ago, Lars Fosdal said:

BAD: EAccessViolation: Access violation at address 0040CEEC in module 'MyApp.exe'. Read of address DEADBEE7. DBServer\INDUSTRIELL\DBName # 3017235 20.03.2019 13:23:06 (Brukerinterface, CRITICAL) MyApp_ClientId @ [0040CEEC] System._UStrAsg

In some piece of code somewhere, a pointer was set to $DEADBEEF, most likely after the object it was pointing to had been freed, and then that same pointer was used afterwards by code running at address $0040CEEC trying to access a data member at offset -8 ($DEADBEE7) via that pointer.  Magic addresses like $DEADBEEF are commonly used for debugging such mistakes.

 

In this case, the code at address $0040CEEC is the System._UStrAsg() function, which is used to assign a UnicodeString to another UnicodeString.  Offset -8 is the StrRec.refCount field in the UnicodeString data header, which makes sense as UStrAsg() does increment that field.

 

In other words, some piece of code tried to assign a UnicodeString value to a dead UnicodeString variable.  UStrAsg() was called by TFieldValue.SetValue(), so SetValue() was likely called on an invalid TFieldValue object inside of TGridSet.CopyRow(), which was called by TDeliverySet.UpdateFromDeliverySet() inside of TDeliveryGrid.RefreshByRouteList().  So, start in RefreshByRouteList() and work your way into UpdateFromDeliverySet() and try to figure out how it may be accessing an invalid TFieldValue object.

1 hour ago, Lars Fosdal said:

What raises the AV?

The Operation System, when the invalid memory address $DEADBEE7 is accessed.  Delphi's RTL catches that error from the OS, creates an EAccessViolation object for it, and then raises it.

Edited by Remy Lebeau
  • Like 4
  • Thanks 1

Share this post


Link to post
2 hours ago, Lars Fosdal said:

Also spotted: Read of address DEADC00B.

Normally I'd expect to see things like this
EUseAfterFreeError: Application made attempt to call method of already deleted object: $071EC5A0 OBJECT [TMyClass] 404 bytes.

It is not so easy to detect, that current AV really is a usage of freed object. Especially if you have multiple DLLs, compiled in different versions of Delphi, or something like that. SafeMM can shed some light even in such situation, but at a cost of big memory leak.

Share this post


Link to post
17 hours ago, Remy Lebeau said:

In some piece of code somewhere, a pointer was set to $DEADBEEF, most likely after the object it was pointing to had been freed, and then that same pointer was used afterwards by code running at address $0040CEEC trying to access a data member at offset -8 ($DEADBEE7) via that pointer.  Magic addresses like $DEADBEEF are commonly used for debugging such mistakes.

[deletia]

1

Excellent analysis, Remy. 

As I often do, I did not ask the right question - which should have been: What sets dead memory references to $DEADxxxx?  RTL? EurekaLog? OS?

Share this post


Link to post

Typically debug-enabled version of memory manager. 

 

On Phone now, so can’t check, but I think FastMM4 uses a different pattern (all $80, IIRC)

  • Like 1

Share this post


Link to post
Posted (edited)
6 minutes ago, Hallvard Vassbotn said:

I think FastMM4 uses a different pattern (all $80, IIRC)

Correct - it seems to be EurekaLog (see point 3. "When memory is released": https://www.eurekalog.com/help/eurekalog/index.php?memory_leaks_page.php)

 

I would say its that a destroyed TFieldValue was not removed from the list inside the TGridSet - so locate where those are destroyed and check if they are properly removed from that list when in it.

Edited by Stefan Glienke
  • Like 3

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×