Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Avoid hardly debugable PHP.exe crashes #16

Merged
merged 7 commits into from
Jan 30, 2021
Merged

Avoid hardly debugable PHP.exe crashes #16

merged 7 commits into from
Jan 30, 2021

Conversation

KoudelkaB
Copy link
Contributor

The current code causes hardly debugable PHP.exe crashes in case when PHP developer does not release query or results in proper order.
This is just minimal fix of just one such scenario.
Architectural fix would be better of course i.e. defining supported scenarios and throwing regular PHP exception instead of crashing PHP.exe in unsuported cases.

THE FIX:
Avoids memory overwrites of released query or result (the memory already allocated by somebody else) or in case of more cursors opened for one query at the time of query destruction.

Crash fix:
The current code causes hardly debugable PHP.exe crashes in case when PHP developer does not release query results in time.
This is just minimal fix of just one such a scenario.
Architectural fix would be better of course - like throwing regular PHP exception instead of crashing PHP.exe.

Case FIXED:
Avoid memory overwrites of released query or result (the memory allready allocated by somebody else) or in case of more cursors opened for one query.
Hardly debugable PHP.exe crashes fixed
@MartinKoeditz
Copy link
Collaborator

Looks good. Do you have an example for such crashes? In that case I can implement a test case for the qa.

@MartinKoeditz MartinKoeditz self-requested a review January 8, 2021 14:13
@MartinKoeditz MartinKoeditz added the bug Something isn't working label Jan 8, 2021
@KoudelkaB
Copy link
Contributor Author

KoudelkaB commented Jan 8, 2021

The crashes are hard to simulate because it depend on what exact memory you overwrite.
But you can easily simulate the problem when you execute from PHP the same query more times and never release the query results.
Then after the query is released the results are still hanging there with invalid reference to the same query (except the last lucky one that NULLed the query as expected)
In my case the memory used previously by the query was in the moment of other result destructor occupied by unrelated zend_object and the ib_query->result->query = NULL actualy deleted it's member ce which caused the php.exe crash on ACCESS_VIOLATION when ending the process in zend_objects_store_call_destructors on the expression "obj->ce->destructor".

As you see the code is absolutely not designed to handle more opened query results at the same time and could basicaly fail anywhere when the situation occures. That is why I have added the second commint to this PR where I explicitely forbid this situation to happen.

@KoudelkaB
Copy link
Contributor Author

KoudelkaB commented Jan 8, 2021

I know also about another php.exe crash that I did not investigate precisely. I only know that the first commit here did not help in that case but the proper closing of the query result in PHP code did - so it was most probably a bug of the same origin.

@KoudelkaB
Copy link
Contributor Author

KoudelkaB commented Jan 22, 2021

I am working on better fix by making the query statement reference counted to avoid the problematic week pointers completely.

@KoudelkaB
Copy link
Contributor Author

KoudelkaB commented Jan 25, 2021

I have updated PR with better fix.
I have created resource for reference counting of statement to properly share it between query and result and call destructor after nobody use it.

@MartinKoeditz
Copy link
Collaborator

At first glance it looks good. We have to check whether existing codes can still be run. In particular, when dealing with transactions, there must be no breaks. I don't see this as a problem at the moment.

Do you already have experience regarding code breaks?

@KoudelkaB
Copy link
Contributor Author

Concerning "code breaks" I am not sure if I understand, what do you mean.
The only thing I changed was exchanging the week result/query pointers by reference counts - As you see I did not touch transactions. So if the code worked before with transatrions now it should not be worse...
So far I have tested two scenarios in our PHP code:

  1. queury is destructed before last result - then the statement is destructed during the last result destruction.
  2. query is destructed after all results - then it also destructs the statement pointing to.

@KoudelkaB
Copy link
Contributor Author

KoudelkaB commented Jan 25, 2021

The only thing I am not sure if I handeled it well is the code
ib_query.stmt = 0; /* keep stmt when free query */
on the line 1244 and
result->stmt = 0;
on the line 1884.
I did not touch them because if I nulled "stms" in the shared resource as well then the statement would never be destructed!
But I am not sure why do you null it here and thus what appropriate action should be taken on corresponding ib_query.stmt_res resp. result->stmt_res?
I hope that these two lines only somehow workarouded the original wrong design and now can be deleted?

@MartinKoeditz
Copy link
Collaborator

Hm, we will have to check, if we can delete these lines.

I didn't create the extension. Since nobody wanted to keep on the development I became the maintainer. So I'm still investigating the code.

I will check for errors in our ERP system. But I think it will turn out.

Copy link
Collaborator

@MartinKoeditz MartinKoeditz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good. No problems so far.

@MartinKoeditz MartinKoeditz merged commit 9b6a8e8 into FirebirdSQL:master Jan 30, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants