TObjectList.Clear access violation - delphi

I'm running into a very weird problem with a large application. I make heavy use of TObjectList storing a custom object on them. On large lists im experiencing weird crashes with "Access violation at address.. read of address.. " "privileged instruction" and others, when I use the CLEAR method. I've tracked this to happen exactly when attempting to delete the last item in the list. I've checked this by logging the contained objects deletion from their destroy proc, and also trying to deleting them on my own (for a := olist.count-1 downto 0 do.. debugmsg('deleting '+inttostr(a)).. olist.delete(a) ), both ways I get the access violation right when deleting the LAST remaining item in the list.
This doesnt happen always, cause I use clear in other areas, and also a few different (smaller) lists, but at a very specific point in my app this happens.
I've no clue what might be wrong, there's nothing trying to access the list during the clear, and the cointained objects do not have access to their parent objectlist, there has to be something screwing up in the TObjectList.delete/clear methods when it comes to clearing the last item.
Any suggestions? Using Delphi XE.

That sounds to me like you're freeing objects that have already been freed. To track this down, download the full version of FastMM, add FullDebugMode to the Conditional Defines line under Project Options->Delphi Compiler and the Map File option under Linking set to Detailed, and rebuild. (Build, not Compile.) Then copy the FullDebugMode DLL to the same folder as your EXE and run it. It'll watch your memory as you allocate and free and when you try to free the same object for a second time, it'll catch that and give you some very detailed debug data as to where the problem is coming from.

Are you sure the last object is valid and not already deleted? It could be in the list twice e.g. due to other bugs.

Related

Delphi, When a datamodule loads I like to prevent the TFDConnector from connecting if I mistakenly have the activate set true

It often happens, to me, that after testing and making a build while I forget to check the activate property first. Then when I install the program on a different system an exception occurs due to failed connection. It's really annoying.
I've searched for a solution for a long time but it looks like it is impossible without making a new connection component inherited from TFDConnection. I don't want to do that and maybe someone here knows a simple way to get around this problem.
Check out the property ConnectedStoredUsage in TFDConnection.
That controls how to use the Connected property value saved to the DFM.
So for your need, you can uncheck auRunTime.
For more info on ConnectedStoredUsage, see the DocWiki.

Why do datasource of database-controls dissapear when Delphi crashes

I'm using Delphi 10.4.1 Enterprise and wrote a VCL program using an SQLite database.
As I suspect a OneDrive issue, I mention that the source code folder is part of the zone managed by OneDrive.
At times, whilst debugging, my Delphi program hangs for unknown reasons, and Delphi quits without further notice. Whenever this happens, the connections between the MainForm and the DataModule (DM1) are lost: in the Object Inspector of the MainForm, all DataSource assignments, ie connections to DataSources in the DataModule, are gone. Moreover, when I reload the program, there is the error message
Access violation at address 500C3553 in module 'rtl270.bpl'. Read of address 00000008
Code-checking gives no errors, but when compiling the following message/request appears:
Module 'MainForm' links to module 'DM1' which cannot be found in the current project. Do you wish to remove/redirect the links to another module?
The weird thing is that the DataModule design form in the IDE can no longer be made visible, only its code remains. Therewith, from within the MainForm the DataModule neither is visible, since dropdowns in the DataSource connectors of the DB-controls remain empty. Last, but not least, when I try to save the MainForm, it says:
Module "*MainForm" references another module and cannot be saved until DM1 is loaded
Whatever I tried to get it back to normal, it was unsuccessful.
However, in the OneDrive root folder, I see a file named ".849C9593-D756-4E56-8D6E-..etc..", which seems to be associated with my program, because of its file date. It can only be deleted or modified when I close OneDrive, but it revives after restart.
I am stuck, for many days already.
Does anyone have an idea what is going on, and can give me a hint on how to proceed?
I found out what has caused the Access Violation that showed up after I tried to bring the datasource connections back in place. I did that by editing the DFM-file of the Mainform, rather than direct in the Object Inspector.
I normally do editing in dfm-files, but adding lines with datasource assignments appears not to be allowed. This was quite a tough lesson for me!
I am happy to have the program running again. Thank you all for your time, #Remy in particular.
Thanks,
JGMS

ColdFusion Builder 2 Client Error - Memory Leak/Loop on Edit

I've not found any other resources on this issue, so I figured I would ask the SO community. :)
I currently have an issue with my CFB2 client going into a memory leak about three seconds after I edit a particular file on one of our company webservers. This also occurs when I try and edit a local copy of the file. The leak is slow and would take many many hours to hold up all of my free RAM (~6.5GB/8GB physical). There is also a high CPU usage on the leak (anywhere from 25-45% | 1.8 GHz four-core). The only visual feedback I receive is in the Outline pane, where it extends infinitely into a loop of cfelseif tags. The pane also holds the loop before editing, but does not attempt to extend it.
This error first occurred whilst I was creating a cffile tag and because I could not close it, the conditional statements were mis-highlighted. I believe this is the root cause of the issue, however, I do not know why this occurred.
As I complete typing of this, I will move the file to a simple editor, remove the line that caused the error, and attempt to add it again, however I fear that the addition of the line will end in the same manner.
EDIT: I moved the page source into Notepad and removed the pesky cffile line. Then, I proceeded to delete the file from the webserver, create a new file of the same name, and add the code back. I closed the tag before adding any attributes just to ensure the same issue would not occur, and it did not experience the same loop.

How to disable TAction.Shortcut or TMenuItem.Shortcut?

I'm developing a Word addin, and somehow the shortcuts defined in TAction.ShortCut are always trigged more than one time, and this is tricky to me and hard to solve, so I resort to TForm.OnKeyDown event and cleared all TAction.ShortCut properties, this approach works well, except that the shortcuts are not shown on the corresponding menu items, but I want them to be displayed on those menu items.
So I come up this idea: Set values for TMenuItem.Shortcut so that the program can show the shortcut hint to the end user, and does not allow VCL to handle these shortcuts, instead, handle them in TForm.OnKeyDown. So my question is how to disable TAction.Shortcut or TMenuItem.Shortcut? Thank you in advance.
For a start, you have an Enabled property on both TAction and TMenuItem. Just set it to False.
Next, one of the possible causes of your event being triggered more than once is that you may be using Application.ProcessMessages; or at least a badly written component that you're using is doing so. One should be very wary of using that Delphi feature because it can cause 're-entrant' code (unintentional recursion).
The root cause of your problem is the events being triggered more than one time. You could try to workaround this problem offcourse but I would suggest to:
Place a breakpoint in your eventhandler.
Copy the Call Stack's content [CTRL+ALT+S] to whatever editor you like for every time you hit the breakpoint.
Start brainstorming as to why the calls lead to hitting the event multiple times.
Fix your code if it is your code to fix.
Hacker way (usually not recommended):
copy unit that contain TAction in separate folder, modify source of TAction that makes ShortCut method do nothing. Put this folder to search path as first item.
rebuild your app.
I use this technique to fix bugs in VCL, but after installing Delphi patches you should not forget to update 'hacked' version of modified units.

Log File Monitor

Is is possible to open a text file and read the contents while another application is updating the file, in such a way that it does not cause a lock conflict?
I need to monitor a log file from one application which is updated by another application each time an event occurs.
I do check if the file is in use before I try to read it, but that does not seem to work in all cases.
Thanks, Pieter
it depends on how the first app open that file.
i.e when calling CreateFile API to open a file, there is dwShareMode param which tells the api how to open it (if this was given 0, it can't be accessed from other applications IIRC).
otherwise there should be no problem with reading from that file.
if im not mistaken, to check if that file is being opened read only u can call
something like
CreateFile(pchar(fName), GENERIC_READ or GENERIC_WRITE, 0, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0) ;
Download Process Monitor from Sysinternals.
Open the filter dialog and add a "path" filter for your log file.
Start the log-writing application (I'll call this "logwriter").
Look for and click on the event where logwriter does a CreateFile.
Under "Detail", it should have "Desired Access: Generic Write". And it should have "ShareMode: Read", which corresponds to FILE_SHARE_READ in the call to CreateFile. What it means is, "I, logwriter, permit others to read my file".
Now run your log-reading application ("logreader"), and do the same exercise.
The Detail should have "Desired Access: Generic Read". And it should have "ShareMode: Read, Write", which means, "I, logreader, permit others, including logwriter, to read and write to the log file".
Those are the most sensible values, I think, and they will prevent locking. Other combinations may be permissible. There is a table here.
Now, you haven't said what happens when it "does not seem to work in all cases". What to do next will really depend on the details. Hopefully the above will give you enough information to work out what is going wrong.
You won't get a lock conflict because the writing application is very unlikely to have locked the file. Doing what you suggest generally works without problems (it's what the UNIX tail -f command does) and those minor glitches that do occur can be ignored. I've written a couple of log monitoring apps in te past that worked like this, with no problems.
Try using FileSystemWatcher to get events when a file is updated.
A more delphi friendly link
Quite apart from getting the file sharing to work right which may be impossible depending on what the other program requests, some programs will close the file between accesses.
I have had success in the past with my program waiting for the file to become available, then quickly opening it, grabbing the needed data and closing it. At least in DOS an attempt to access a locked file caused a few retries, and I bumped up this setting, so that if the other program tried for the file while I had it they would simply be delayed and never see an error.
I was even able to update the file (I made sure NOT to close it in between!) without the other program ever knowing a thing.
Ugly as sin but we couldn't change the other program so it was the only way to get the job done. It was deployed in-house for years, I never heard a peep from the users of that system. It finally went away when the machinery the other program controlled was retired.
XpoLog will do the trick without changing your env or code, XpoLog log monitor
Avar is right - you are at the mercy of the writing program here. If they are locking the file, then there are a couple of things you can do:
1 - Check for a change in the "last modified" date time - if that changes, then you know something has happened.
2 - If the mod datetime did change, then (depending on the size of the file) it might be good enough to create a copy of the file and check that.
we use "Tail for win32",
i know its not delphi but it might be useful
http://tailforwin32.sourceforge.net/

Resources