Crashing PanX way too often

I have spent months trying to eliminate crashes in several procedures, which operate in a similar fashion, in a shared database. The crashes come in waves: once the procedure crashes, it will crash several times in a row. Then it may work 10, 20, or more times without a problem. The code first defines and assigns values to several variables, then adds a record and assigns the variable values to various fields in the newly added record.

/* Code first defines and assigns values to the variables. Never had a crash here.
 Then does this: */

 addrecord
 DT="B" //DT is a field name. Each subsequent begins with a field name
 Matterno=fgmatter 
 Invoice=fginv
 Date=fginvdate
 HCDebit=val(fghc)
 Field HCDebit runfieldcalculations
 SCDebit=val(fgsc)
 Field SCDebit runfieldcalculations
 Initials="SD"
 Billno=lvbillnum
 DateCreated=today()
 ShortName=fgShortName

Based on logging statements, it appears the program fails when the first assignment is reached, in this case, DT=“B”. Upon restarting, typically I find one empty row has been added.

My most recent effort at a fix is to insert an Alertsheet statement immediately after the Addrecord. This introduces a pause. After ten tests, the procedure has run without a failure. But I am not ready to declare success yet. In any event, introducing the requirement would be a partial success at best; there is no good reason for the user to have to intervene.

My procedure also goes on to add more records, but I have never had a failure anywhere but around the first addrecord; assignment statements.

I will also add that I previously used console statements to show the progress of the procedure. At first I believed that the code failed exactly where the console statements suggested: after the last console state that appeared in the console, and before the next one. But at some point I began to doubt that; the code may have gone on for many rows and then failed, and also failed to post/send the message from several rows earlier to the console. So I am not sure this will actually pinpoint the problem code.

Any solutions or ideas would be welcome.

When I ran the procedure and crashed under the Terminal, I got these messages:

2021-02-06 16:14:08.190 PanoramaX[4366:57771] ERROR: Can’t have a toolbar in a window with <NSNextStepFrame: 0x7ff125269ff0> as it’s borderview
zsh: segmentation fault /Applications/PanoramaX.app/Contents/MacOS/PanoramaX

This indicates that the error comes from Apple’s code. I’ve never heard of the NSNextStepFrame class before – by doing a google search I learned that it is a private Apple class (private means it’s not documented), it is apparently one of the classes Apple uses to construct windows, which seems to make sense considering this error message. That said, I have absolutely no idea what that error message means, or why running Panorama code would cause a problem related to the toolbar. I know you generally keep the toolbar hidden, so maybe that causes a problem since Panorama sometimes tries to update items in the toolbar, for example the record count.

Your code invokes the runfieldcalculations statement twice, which means it’s running a bunch of other code not shown here. What do the field calculations for HCDebit and SCDebit do?

The runfieldcalculations update the value of other fields in the same row which have HCDebit or SCDebit in their formulas. I will try showing the toolbar and see if the crashing recurs.

I have managed to get a similar procedure to crash five times in a row and then to run once successfully. (I’ll come back to that.) I had server logging turned on, and I see one difference might be a clue to this failure, but it’s beyond my knowledge.

I am going to email the logs to Jim.

When the code ran successfully, it added 8 records to the DB and for reach record assigned values to several fields. When it failed, it added one blank record then crashed. No fields had assigned data.

The log for the successful attempt has blocks of log info info for each record that was added like this:

[_serverADDRECORD]
[_serverLOCKRECORD]
[_serverCOMMITRECORD]

These three blocks of information repeated in the log for each record that was added.

After the last record was added, another block appeared:

[BACKGROUNDWEBSAVE]

Every time the procedure failed, the log showed this:

[_serverADDRECORD]
[BACKGROUNDWEBSAVE]

These look just like the successful log, but there was no data added and saved to each record after it was added, and the program crashed after adding the first record.

What I did differently when the procedure ran successfully:

(1) I deleted the five blank rows that had been added, one for each failure.

(2) I clicked on a cell in the data sheet, and then clicked away without making any changes. [This activity was reflected in the log.]

I have noticed before that the failure usually occurs if I open the database and immediately run the procedure. I have also noticed that if it runs once successfully, it will continue to run successfully many time in a row.

The code involved in this testing was slightly different than what is posted above:

loop
Addrecord
Initials=array(lvorig,a,“;”)
OrigDebit=val(fgtfees)*val(array(lvorig,a+1,“;”))*val(fgreduction)
a=a+2
Invoice=fginv
zlog a+" "+Invoice
DT=“B”
Matterno=fgmatter
Date=fginvdate
Field OrigDebit runfieldcalculations
ShortName=lvshortname
DateCreated=today()
Billno=lvbillnum
lvO=lvO-1

until lvO=0

In my testing, this loop should run twice, but failed the first time through when it failed.

I’ve looked at the logs you sent me, and I have an educated guess. Try putting an unlockrecord statement either at the end of the loop, right above the until statement, or at the top of the loop, right above the addrecord statement. Actually, maybe at the top is the better bet, in case something above the loop had locked the record. See if that makes any difference.

This might be a good clue. Any chance you are running the procedure before the database is finished synchronizing? That probably shouldn’t be possible, but I think it is possible.

That is not possible. The user must open a window by clicking a button, click a second button, then fill out enter data in 8 to 10 text editors, then click a button to initiate the procedure at issue. Tom

Well, then I am back to having no clue. Still it is good that this issue has come to my attention, it should be fixed. I’m still not 100% convinced that this might not be related to the problem – maybe it is the fact that they are doing anything before the synchronization is finished. For most users this probably isn’t likely for two reasons – 1) there files are smaller, 2) the toolbar shows that it is synchronizing. But you have quite large files that might take a few seconds to synchronize, and you hide the toolbar so it’s not obvious to the user what is going on.

I’m going to change my advice here. I think the unlockrecord statement should go at the bottom. This would actually be a good practice here no matter what. Otherwise, the last record added is going to remain locked for an indeterminate time, and no one else will be able to edit it. I’m guessing that’s not what you want.

I put the unlockrecord statement at the end of the loop. The procedure worked correctly four times, then crashed on the fifth. I am sending the log from the server and the client at the time of the crash. I used the link you sent to set up the client Instrumentation settings.

Hi Jim,

I added the unlock statement at the end of the loop right before the until statement. I quit PanX. I opened Panorama, then opened BP (the problem DB)(allowed plenty of time for starting up and syncing), started the procedure to add an invoice, filled out the dialog with several variables, then pressed the button that initiates the problem procedure. PanX crashed.

I repeated the steps, and the procedure did not crash. (This has happened several times. The procedure crashed, the worked after re-opening. Is that weird or what!)

Here are logs from the server and from the client, each showing the two attempts, one failed and one succeeded.

Client log (TGC PanX M1 Log 022721.with unlock.txt)
lines 1 - 32. It didn’t take long to crash. Added a blank row (ID 58092).
lines 33 - Added 7 records. IDs 58093 to 58099. (I checked the IDs of records in the data sheet.)

At least I can say it fails the same way every time: it adds a record but never completes the first assignment and no data is added, no Commit record log block is found.

Server log (PanX Server Log 022721.1.txt)
lines 86 - 98. (Shows record 58092 being added; also shows another locked record, which happens to be blank also (this was left over from last night crash).

lines 99 to 460 (Shows the record being added and committed. (That means saving a change I think).

Comment: When I started this morning, there was a locked empty record left over from yesterday. After the first crash, there were two locked empty records. In the past, we have tried be sure to delete any empty records before running the procedure, but that has not stopped the crashes.

Good luck! You might need it.

Tom

(Attachment PanX Server Log 022721.1.txt is missing)

(Attachment TGC PanX M1 Log 022721.with unlock.txt is missing)

Jim, I resent the attachments directly to your email.

Today I disconnected the problem DB from the server. It appears that Panorama crashes in exactly the same way as a stand-alone database. Perhaps the problem is unrelated to the server connection.

Sounds like it for sure is unrelated to the server connection. It also sounds like you can make this problem happen on demand. If that is true, and if there is any way you can get a copy to me, that is probably the best way to make progress. I realize that may not be possible due to confidentiality issues.

If it is not an issue with the sharing code, turning on logging is less likely to be helpful. I have not retrofitted most single user code with zlog statements.

If this is a single user problem, keep in mind that the problem may not be rooted in the procedure code. It could be a side effect, for example something happening on a form in response to your procedure code. I know you have complicated forms with lots of formulas, triggered code, etc.

I will check with the firm and see if they will agree to my sending the files to you. I have to do some things to make them accessible; they need three files to run these procedures; two are used for lookups.

The procedures, I think, avoid anything that could involve a screen redraw, a form, a save, until the end, when they display some result.

Jim, just want to make sure that you saw the email I sent earlier today.