Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Add pmalloc API #19675

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

Draft
iluuu1994 wants to merge 6 commits into php:master
base: master
Choose a base branch
Loading
from iluuu1994:pmalloc
Draft

Add pmalloc API #19675

iluuu1994 wants to merge 6 commits into php:master from iluuu1994:pmalloc

Conversation

Copy link
Member

@iluuu1994 iluuu1994 commented Sep 2, 2025

See GH-19633. Not sure if this is worth the code churn.

@@ -191,7 +191,7 @@ static void fpm_stdio_child_said(struct fpm_event_s *ev, short which, void *arg)

create_log_stream = !child->log_stream;
if (create_log_stream) {
log_stream = child->log_stream = malloc(sizeof(struct zlog_stream));
log_stream = child->log_stream = pmalloc(sizeof(struct zlog_stream));
Copy link
Member

Choose a reason for hiding this comment

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

This is master process code and should not use exit on malloc failure. This actually shows issue that the return value is not checked. Basically the idea is that in such situation we prefer OS to kill one of the children.

Copy link
Member Author

@iluuu1994 iluuu1994 Sep 2, 2025
edited
Loading

Choose a reason for hiding this comment

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

Right, I added this only to code that doesn't already check for NULL, i.e. to abort gracefully rather than crash with a NULL pointer access. This is an issue that should be solved separately then.

@@ -140,7 +140,7 @@ static bool should_overwrite_per_dir_entry(HashTable *target_ht, zval *zv, zend_
void config_entry_ctor(zval *zv)
{
php_dir_entry *pe = (php_dir_entry*)Z_PTR_P(zv);
php_dir_entry *npe = malloc(sizeof(php_dir_entry));
php_dir_entry *npe = pmalloc(sizeof(php_dir_entry));
Copy link
Member

Choose a reason for hiding this comment

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

This might be also worth checking if exit would make sense here. I haven't checked it out.

Copy link
Member

bwoebi commented Sep 2, 2025

We probably should then, at the same time change all occurrences of pemalloc(..., 1) to pmalloc() too.

@@ -1323,7 +1323,7 @@ static const maker_note_type maker_note_array[] = {

static HashTable *exif_make_tag_ht(tag_info_type *tag_table)
{
HashTable *ht = malloc(sizeof(HashTable));
HashTable *ht = pmalloc(sizeof(HashTable));
Copy link
Member

@TimWolla TimWolla Sep 2, 2025

Choose a reason for hiding this comment

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

Can we take the opportunity of the churn to also avoid repeating the type unnecessarily?

Suggested change
HashTable *ht = pmalloc(sizeof(HashTable));
HashTable *ht = pmalloc(sizeof(*ht));

see: https://github.com/haproxy/haproxy/blob/master/dev/coccinelle/xalloc_size.cocci

Copy link
Member Author

@iluuu1994 iluuu1994 Sep 2, 2025

Choose a reason for hiding this comment

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

I don't usually use the sizeof(*ht) style, and I don't think most people do. I don't particularly care, but I think moving towards one style only makes sense if it becomes policy. Maybe suggest it on Slack first?

Copy link
Member

Choose a reason for hiding this comment

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

We are not going to change all such usage so I would prefer to stick with full types. I find it also more readable.

Copy link
Member

@TimWolla TimWolla Sep 3, 2025

Choose a reason for hiding this comment

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

We are not going to change all such usage

What do you mean by "we are not going to"?

Copy link
Member

Choose a reason for hiding this comment

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

I'm not sure if you meant doing just for pmalloc of changing every single sizeof.

If former, then I don't think there is much point in creating inconsistency that is less readable. If latter, you don't get full agreement as it would be a big churn so you would probably have to go through RFC which is not exactly meant for internal changes like this. It reminds me those header includes refactoring where we ended up not having any process to decide it.

Copy link
Member Author

@iluuu1994 iluuu1994 Sep 3, 2025

Choose a reason for hiding this comment

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

It can also be used as some kind of static analyzer to find incorrect constructs (e.g. cases where the types already differ).

This is what I'm most interested in. It's hard to remember rules, and it's even harder for everyone to remember all rules. IMO, guidelines are most useful when they are enforced, even if only for the 95% cases. At least that helps you internalize the rules.

Regardless, I think such a decision would need discussion, though I fully acknowledge there's no good channel to do so. I think Slack (e.g. #php-src) would make the most sense.

Copy link
Member

Choose a reason for hiding this comment

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

This kind of conflict is the easiest possible conflict to resolve: It affects a single line that doesn't require much thought.

But it's a still delay to check it, edit and commit for something that has no value and is not even an improvement.

Copy link
Member Author

@iluuu1994 iluuu1994 Sep 3, 2025

Choose a reason for hiding this comment

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

It depends on the change. There's a non-trivial amount of time spent in PRs discussing the same nits (e.g. prefer /* */ over //, though I have no idea whether these kinds of things are solvable with Coccinelle).

Copy link
Member

@TimWolla TimWolla Sep 3, 2025
edited
Loading

Choose a reason for hiding this comment

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

There's a non-trivial amount of time spent in PRs discussing the same nits (e.g. prefer /* */ over //, though I have no idea whether these kinds of things are solvable with Coccinelle).

That example would probably rather be clang-format. I believe Coccinelle can also deal with comments, but the intended use case is making changes to the code based on type and control-flow information with a convenient syntax that resembles a patch file and thus is easy to grok even for less experienced users.

To use malloc() as an example:

@@
type T;
T *x;
@@
 x = malloc(
- sizeof(T)
+ sizeof(*x)
 )

This defines placeholders of an arbitrary type T and a variable x that is a pointer to T. It then searches for constructs x = malloc(sizeof(T)) and replaces the sizeof(T) by sizeof(*x).

For a C program:

#include <stdlib.h>
int
main(void) {
	int *foo = malloc(sizeof(int));
	int *bar = malloc(sizeof(double));
}

running that Coccinelle patch would make the following changes:

$ spatch -sp_file example.cocci test.c 
init_defs_builtins: /usr/lib/coccinelle/standard.h
HANDLING: test.c
diff = 
--- test.c
+++ /tmp/cocci-output-4310-cbc9b9-test.c
@@ -2,6 +2,6 @@
 
 int
 main(void) {
-	int *foo = malloc(sizeof(int));
+	int *foo = malloc(sizeof(*foo));
 	int *bar = malloc(sizeof(double));
 }

If we now wanted to find places where the types differ, we could use the following patch:

@@
type T;
type U;
T *x;
@@
 x = malloc(
(
 sizeof(T)
|
 sizeof(*x)
|
* sizeof(U)
)
 )

The * is an indicator to just "highlight" the match and not perform any replacement. We define an additional type U and then define multiple alternatives. For the correct variants sizeof(T) and sizeof(*x) nothing is reported. For sizeof(U) (where U != T, since T was already handled), a report is created:

$ spatch -sp_file example.cocci test.c 
init_defs_builtins: /usr/lib/coccinelle/standard.h
HANDLING: test.c
diff = 
--- test.c
+++ /tmp/cocci-output-4315-fa4dae-test.c
@@ -3,5 +3,4 @@
 int
 main(void) {
 	int *foo = malloc(sizeof(int));
-	int *bar = malloc(sizeof(double));
 }

iluuu1994 reacted with thumbs up emoji
Copy link
Member

@nielsdos nielsdos Sep 7, 2025

Choose a reason for hiding this comment

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

Coccinelle works very well and is easy to use. I've used it a few times and it's been battle tested against the Linux kernel, which isn't particularly known for it's consistent coding style and is known for it's complex macros etc.
I'm in favor to use the malloc sizeof pattern Tim proposes, and if we don't want to convert existing code (which I think we should), we should at least use that pattern for new code.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Reviewers

@bukka bukka bukka requested changes

@TimWolla TimWolla TimWolla left review comments

@nielsdos nielsdos nielsdos left review comments

@dstogov dstogov Awaiting requested review from dstogov dstogov will be requested when the pull request is marked ready for review dstogov is a code owner

@arnaud-lb arnaud-lb Awaiting requested review from arnaud-lb arnaud-lb will be requested when the pull request is marked ready for review arnaud-lb is a code owner

@kamil-tekiela kamil-tekiela Awaiting requested review from kamil-tekiela kamil-tekiela will be requested when the pull request is marked ready for review kamil-tekiela is a code owner

@SakiTakamachi SakiTakamachi Awaiting requested review from SakiTakamachi SakiTakamachi will be requested when the pull request is marked ready for review SakiTakamachi is a code owner

@kocsismate kocsismate Awaiting requested review from kocsismate kocsismate will be requested when the pull request is marked ready for review kocsismate is a code owner

Assignees
No one assigned
Projects
None yet
Milestone
No milestone
Development

Successfully merging this pull request may close these issues.

AltStyle によって変換されたページ (->オリジナル) /