-
Notifications
You must be signed in to change notification settings - Fork 7.8k
zend call stack fix freebsd code path. #11766
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
Conversation
Ah, now I understand the comment in #11762... It's a typo and the Then why not just changing the constant name to Edit: This changes the execution of the code then. Now, this code is not executed on any platform... 🤔 |
Not sure I get what you mean this part of the code is exclusive to freebsd. |
Anyway cc @arnaud-lb since he s the author of the FreeBSD's implementation :) |
Yes, but the I've changed my PR now so only one change is done. Then can you remove also pthread_attr_getstack check in Zend.m4? |
ah sure I did not see your PR change. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice catch, thank you!
You also add -lpthread, is this on purpose? Should we avoid linking to pthread when it's not necessary? (in non-ZTS builds) Can it affect SAPIs in any way?
Zend/Zend.m4
Outdated
@@ -212,6 +212,7 @@ AX_CHECK_COMPILE_FLAG([-Wlogical-op], CFLAGS="-Wlogical-op $CFLAGS", , [-Werror] | |||
AX_CHECK_COMPILE_FLAG([-Wformat-truncation], CFLAGS="-Wformat-truncation $CFLAGS", , [-Werror]) | |||
AX_CHECK_COMPILE_FLAG([-Wstrict-prototypes], CFLAGS="-Wstrict-prototypes $CFLAGS", , [-Werror]) | |||
AX_CHECK_COMPILE_FLAG([-fno-common], CFLAGS="-fno-common $CFLAGS", , [-Werror]) | |||
AX_CHECK_COMPILE_FLAG([-pthread], CFLAGS="-pthread $CFLAGS", , [-Werror]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It this change on purpose?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes not much choice.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
oh now I remember why I checked for the availability of both pthread_attr_get_np
and pthread_attr_getstack
: The libc provides a stub for pthread_attr_get_np
, but not for pthread_attr_getstack
, when not linking with pthread.
There are stubs for pthread_attr_getstackaddr
and pthread_attr_getstacksize
though.
We should check for the availability of pthread_attr_getstack
, or switch to pthread_attr_getstackaddr
and pthread_attr_getstacksize
. After that we can avoid explicitly linking to pthread in non-ZTS builds.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since pthread_attr_getstackaddr
and pthread_attr_getstacksize
are deprecated, we should go for checking the availability of pthread_attr_getstack
and use it in zend_call_stack_get_freebsd_pthread
.
We will compile the stub version of zend_call_stack_get_freebsd_pthread
when not linking with pthread, which is fine.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In fact the deprecation warning occured on Linux should I change it too there ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see that you have already done it :) It's better if we can avoid depending on deprecated functions.
bb40c12
to
090ed09
Compare
…_get_np being different from Linux's pthread_getattr_np) led to this code path never get called on FreeBSD.
090ed09
to
a01a43f
Compare
Zend/zend_call_stack.c
Outdated
error = pthread_attr_getguardsize(&attr, &guard_size); | ||
if (error) { | ||
return false; | ||
} | ||
|
||
addr = (char *)addr + guard_size; | ||
max_size -= guard_size; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
From reading the code and testing, addr and size reported by pthread_attr_getstack()
appear to reflect the usable stack, and they are not affected by the guard size. Based on that, we should not adjust addr and max_size here. But you may have a different experience. Is this required on some FreeBSD version? On Linux this is required in Glibc < 2.8.
In 13.1, the stack is allocated here: https://github.com/freebsd/freebsd-src/blob/releng/13.1/lib/libthr/thread/thr_stack.c#L276. As we can see, the map size is computed from stacksize + guardsize
. stacksize
and guardsize
come directly from the pthread_attr
(they are just rounded to the nearest page multiple). pthread_attr_setstack()
does not adjust addr and size with the guardsize, and pthread_attr_setguardsize()
does not adjust addr and size either. The get
versions of these functions also report these values directly.
I verified with this program: https://gist.github.com/arnaud-lb/a53eb410b7c26b38fd01eac2cee0467e. The program starts 3 threads: Thread 1 with the default attrs, thread 2 with the guard size set to 1MiB, and thread 3 with the guard size set to 16MiB (larger than the stack size). Each thread then recurses until it reaches the address reported by pthread_attr_getstack()
. If this address is the actual base of the stack, this should not crash. If this address is in or bellow the guard pages, this should crash. During my tests, this did not crash.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The FreeBSD manpage does not help a lot, but it mentions that these functions conform to POSIX.1. The posix spec about pthread_attr_getstack() says this:
All pages within the stack described by stackaddr and stacksize shall be both readable and writable by the thread.
There could still be a bug or a discrepancy in FreeBSD's implementation, so I wouldn't trust the spec alone, but this matches what I was seeing above.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No my mistake even in old releases the guard size is already.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No my mistake even in old releases the guard size is already.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you!
The typo in HAVE_PTHREAD_ATTR_GET_STACK (might be due to pthread_attr_get_np being different from Linux's pthread_getattr_np) led to this code path never get called on FreeBSD.
The typo in HAVE_PTHREAD_ATTR_GET
_
STACK (might be due to pthread_attr_get_np being different from Linux's pthread_getattr_np) led to this code path never get called on FreeBSD. Anyway, like Linux the first condition alone is enough, pthread_attr_getstack being presenteven in the 9.x release's serie.