XylemFlow 8 Posted October 24, 2022 (edited) A small proportion of users are reporting an Access Violation error during startup of my FMX Windows application. I've not been able to replicate it myself, but I have determined a number of things by sending variations to the users. Here are the facts. The vast majority of users do not have the issue All users with the issue have what looks like a normal Windows 10 setup The error occurs after the forms have been created but before the OnCreate events for each form start to get called. Perhaps somewhere early in Application.Run. The error does not occur with earlier version of my app built in Delphi 10.4. The error does not occur when I build the latest version of my app in Delphi 10.4. The error does not occur when run using Windows XP compatibility mode. This is strange since I didn't think FMX apps could run at all in Windows XP. I'm using one 3rd party component (FFVCL) but another app using that component and built in Delphi 11 does not cause the error. Does anyone know of a Delphi 11.0 issue that could be causing this? Would it help for me to upgrade to 11.2? If not, can anyone suggest ideas for further investigation? Why would some apps work when built in the same version and this one doesn't? Why would it work in Windows XP compatibility mode? Edited October 24, 2022 by XylemFlow Share this post Link to post
Keesver 23 Posted October 24, 2022 The first step would be to get more detailed 'crash' information. We use madExcept in all our software to do this (there are others too) which provides a solid stack trace when an exception occurs. Without such info you don't know what to look for.... 2 Share this post Link to post
XylemFlow 8 Posted October 24, 2022 (edited) 25 minutes ago, Keesver said: The first step would be to get more detailed 'crash' information. We use madExcept in all our software to do this (there are others too) which provides a solid stack trace when an exception occurs. Without such info you don't know what to look for.... Thanks. I was hoping there was a chance that someone else had a similar issue based on the info I gave. It seems to me that this is a Delphi 11 issue rather than anything in my code, but I don't know for sure. MadExcept looks great, but it's a VCL component. Can I use it in FMX applications as long as I'm building for Windows? Edited October 24, 2022 by XylemFlow Share this post Link to post
Lajos Juhász 293 Posted October 24, 2022 I don't use fmx but https://github.com/project-jedi/jcl should work. 1 Share this post Link to post
Keesver 23 Posted October 24, 2022 Yes, works with FMX and VCL, but Windows only. Share this post Link to post
XylemFlow 8 Posted October 24, 2022 (edited) 2 hours ago, Lajos Juhász said: I don't use fmx but https://github.com/project-jedi/jcl should work. Thanks. There's not much information there about how to do that, or on the JEDI wiki site. I did find the following blog post though. Can I assume that this is still relevant, or is it out of date? https://blog.dummzeuch.de/2014/03/08/using-jcldebug/ @dummzeuch Edited October 24, 2022 by XylemFlow Share this post Link to post
dummzeuch 1505 Posted October 24, 2022 3 hours ago, XylemFlow said: Thanks. There's not much information there about how to do that, or on the JEDI wiki site. I did find the following blog post though. Can I assume that this is still relevant, or is it out of date? https://blog.dummzeuch.de/2014/03/08/using-jcldebug/ As far as I know everything in that blog post still applies. But beware: This is for Win32 programs. I have no idea whether Win64 or other platforms are supported and whether any changes are necessary there. 1 Share this post Link to post
Brian Evans 105 Posted October 25, 2022 Only thing I can think of is in regards to 64bit applications: Delphi 11.2 64 bit apps make more use of ASLR. Pointers are now less likely to have the top 32bits all zero so any use of an integer to hold them will now cause problems. Loading a 32bit value into a 64bit register on x64 clears the top bits so bad code could squeak by before if the top 32 bits of the real address were all zero. Delphi Compiler Enhancements As part of the RAD Studio 11.2 Delphi compiler improvements, Delphi further expands Address Space Layout Randomization (ASLR) support for the Win64 platform by supporting High Entropy ASLR (HE ASLR) by adding the ability to randomize memory addresses at high locations. Share this post Link to post
Fr0sT.Brutal 900 Posted October 25, 2022 19 hours ago, XylemFlow said: Thanks. There's not much information there about how to do that, or on the JEDI wiki site. I did find the following blog post though. Can I assume that this is still relevant, or is it out of date? Also could be useful: https://en.delphipraxis.net/topic/7363-exception-call-stacks-on-windows-with-only-a-few-locs/ Share this post Link to post
XylemFlow 8 Posted October 25, 2022 (edited) 14 hours ago, Brian Evans said: Only thing I can think of is in regards to 64bit applications: Delphi 11.2 64 bit apps make more use of ASLR. Pointers are now less likely to have the top 32bits all zero so any use of an integer to hold them will now cause problems. Loading a 32bit value into a 64bit register on x64 clears the top bits so bad code could squeak by before if the top 32 bits of the real address were all zero. Delphi Compiler Enhancements As part of the RAD Studio 11.2 Delphi compiler improvements, Delphi further expands Address Space Layout Randomization (ASLR) support for the Win64 platform by supporting High Entropy ASLR (HE ASLR) by adding the ability to randomize memory addresses at high locations. Thanks. However, I was using 11.0 when the problem first appeared and that doesn't have the ASLR updates. I've now updated to 11.2 and the issue is still there. My application is 32 bit. What are the chances that the issue is display related? I know that there were some changes to support high DPI scaling in D11. Maybe I should ask the users about their display settings? Edited October 25, 2022 by XylemFlow Share this post Link to post
XylemFlow 8 Posted October 26, 2022 After adding call stack logging I have determined that the error occurs in FMX.Forms TFormBorder.GetSupported. The issue may be related to custom styles, which I am using on some forms. A similar question was asked previously. App produces an exception on target computers 1 Share this post Link to post
XylemFlow 8 Posted October 27, 2022 (edited) That doesn't get me much closer to solving this though. Now all I know is that it's the fault of something in Delphi styles. I'm not even sure which form is causing the issue, although I could work that out by trial and error. I still don't understand what's different about the users' setup that causes the error with styles when most others do not? Also, what changed in Delphi 11 to cause this issue, which does not happen in Delphi 10? I'm using custom styles to adjust the look of some of the controls. For example, the TSpinBox has big arrow buttons on each side. I used styles to make the buttons smaller so that the control takes up less space. Does anyone know how I can do that without using styles and without building my own TSpinBox component? Could I create a class deriving from TSpinBox and then override some of the functionality perhaps? The other annoying thing with styles is that I have to create the style for each platform, including each Windows version. I think that the reason the exception didn't happen in Windows XP compatibility mode is because there was no style for it. Edited October 27, 2022 by XylemFlow Share this post Link to post
Serge_G 87 Posted October 28, 2022 (edited) Hi, 22 hours ago, XylemFlow said: Could I create a class deriving from TSpinBox and then override some of the functionality perhaps? No, this new TSpinBox should use the same style. 22 hours ago, XylemFlow said: The other annoying thing with styles is that I have to create the style for each platform, including each Windows version. Except if you put this style in the default collection. As I remember when style is to be applied, "delphi" look for platform style and then default style if stylelookup is not found. 22 hours ago, XylemFlow said: I think that the reason the exception didn't happen in Windows XP compatibility mode is because there was no style for it. Ah, this should be a possibility Another solution is to change the style of the component during runtime (I found this trick some month ago, but I don't remember where I save this one) [EDIT] Finally, found. If you read French it's in my blog I explain 2 methods, I think second one "modify the style directly" could apply. If you can screenshot what you expect I will take this like a challenge 😉 Edited October 28, 2022 by Serge_G found it Share this post Link to post
XylemFlow 8 Posted October 28, 2022 (edited) Thanks for your suggestions @Serge_G . Here is a colour selector form that I designed for my app with the modified TSpinBoxes bottom right (the default style takes up far too much space). A further update on my Access violation issue though, the styles may not be an issue as I previously thought. I'm now in communication with Embarcadero support and they pointed out that an error is shown earlier in the call stack. The issue may be related to the images in the main menu. I have confirmed that this is the issue by creating a version without the TImageList linked to the main menu. The user has said that the error is gone. Any idea why Delphi 11 would cause an access violation for a main menu linked to an image list on some computers? Here's the full stack trace. main thread ($21b0): 0069e7e3 +003 myapp.exe FMX.Forms TFormBorder.GetSupported 0069e8b5 +005 myapp.exe FMX.Forms TFormBorder.StyleChanged 006aafb5 +00d myapp.exe FMX.Forms TCommonCustomForm.UpdateStyleBook 006ac5e3 +05f myapp.exe FMX.Forms TCustomForm.UpdateStyleBook 006ab222 +092 myapp.exe FMX.Forms TCommonCustomForm.SetStyleBook 006a3946 +03e myapp.exe FMX.Forms TCommonCustomForm.Notification 006ac47a +016 myapp.exe FMX.Forms TCustomForm.Notification 002762b5 +035 myapp.exe System.Classes TComponent.RemoveFreeNotifications 002760dc +014 myapp.exe System.Classes TComponent.Destroy 00670e20 +098 myapp.exe FMX.Types TFmxObject.Destroy 0046bb47 +077 myapp.exe FMX.Controls TStyleBook.Destroy 00139030 +008 myapp.exe System 34 +0 TObject.Free 00671c6e +056 myapp.exe FMX.Types TFmxObject.DoDeleteChildren 00139030 +008 myapp.exe System 34 +0 TObject.Free 002a4c99 +071 myapp.exe System.Messaging TFixedMessageManager.SendMessage 00671d0a +002 myapp.exe FMX.Types TFmxObject.DeleteChildren 00670df2 +06a myapp.exe FMX.Types TFmxObject.Destroy 006a020f +2eb myapp.exe FMX.Forms TCommonCustomForm.Destroy 006ab31f +04b myapp.exe FMX.Forms TCustomForm.Destroy 7725ad8a +00a ntdll.dll KiUserExceptionDispatcher 746541ef +06f KERNELBASE.dll RaiseException 0013918a +032 myapp.exe System 34 +0 TObject.GetInterface 00277838 +018 myapp.exe System.Classes TComponent.QueryInterface 00633c47 +0df myapp.exe FMX.Platform.Menu.Win TWinMenuService.UpdateMenuItem 004164e1 +045 myapp.exe FMX.Menus TMenuItem.DoBitmapChanged 00418641 +049 myapp.exe FMX.Menus TMenuItem.ImagesChanged 0040361d +011 myapp.exe FMX.ImgList TGlyphImageLink.Change 002c1d0b +02f myapp.exe System.ImageList TImageLink.SetImageList 00418682 +006 myapp.exe FMX.Menus TMenuItem.SetImages 00418634 +03c myapp.exe FMX.Menus TMenuItem.ImagesChanged 0040361d +011 myapp.exe FMX.ImgList TGlyphImageLink.Change 002c1d0b +02f myapp.exe System.ImageList TImageLink.SetImageList 00418682 +006 myapp.exe FMX.Menus TMenuItem.SetImages 0041c61f +06b myapp.exe FMX.Menus TMainMenu.ImagesChanged 0041c5aa +00e myapp.exe FMX.Menus TMainMenu.Loaded 0025c4b9 +02d myapp.exe System.Classes NotifyGlobalLoading 0025c654 +07c myapp.exe System.Classes InitInheritedComponent 0069eeac +1a8 myapp.exe FMX.Forms TCommonCustomForm.Create 006ab34a +016 myapp.exe FMX.Forms TCustomForm.Create 0069aeb6 +05a myapp.exe FMX.Forms TApplication.CreateForm 0069b0a9 +075 myapp.exe FMX.Forms TApplication.RealCreateForms 0064283c +018 myapp.exe FMX.Platform.Win TPlatformWin.Run 0069e35f +03f myapp.exe FMX.Forms TApplication.Run 00a4aab3 +3c7 myapp.exe myapp 126 +64 initialization 766b3742 +022 KERNEL32.DLL BaseThreadInitThunk Edited October 28, 2022 by XylemFlow Share this post Link to post
XylemFlow 8 Posted November 3, 2022 Another update on this issue. I have created a minimal application in D11 with just a TMainMenu linked to a TImageList. The main menu has a single item with an image. This still causes the error for the user, which confirms that the issue is related to main menu linked to an image list. Still no progress on working out how the user's computer is different from mine and most other users. Share this post Link to post
Brian Evans 105 Posted November 3, 2022 Old/corrupt/problematic graphics drivers that have errors on some code paths might be something to look at. Some graphics drivers have a clean install option (clears out old drivers or parts of old drivers before installing the latest drivers) which might help. This is fairly rare these days however. Share this post Link to post
XylemFlow 8 Posted November 7, 2022 This issue is now solved thanks to the support team at Embarcadero. The issue was happening for users who had an old version of Windows 10. The users who reported the error had not installed any Windows 10 updates in years! New DPI code added in Delphi 11 related to menu items was calling a Windows 10 function that did not exist in early versions of Windows 10 and so was causing the error. The fix was to modify line 297 of FMX.Helpers.Win.pas to the following. if (TOSVersion.Major >= 10) and (TOSVersion.Build >= 14393) then The issue has been reported so that it can be fixed permanently in future updates. Thanks for everyone's help. The extra debug info from the callstack made the difference. 1 Share this post Link to post
Brian Evans 105 Posted November 7, 2022 Thanks for posting about the resolution to the problem. It is documented as the GetSystemMetricsForDpi does say: Minimum supported client Windows 10, version 1607 [desktop apps only] and that is build 14393. It is a LTSC release supported until October 13, 2026 so can't really be ignored. Share this post Link to post