-
Notifications
You must be signed in to change notification settings - Fork 7.8k
Fix DTrace build with SystemTap and GCC defaults #11858
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
This looks ok, yes. I've checked it (only quickly though) with few preprocessors and it seems to be building fine now. However, the CPP will be still default And the Edit: Ah, yes, there is explanation in the comments regarding the Edit 2: It is possible though to check if preprocessor supports certain set of flags though with AC_PREPROC_IFELSE: |
Maybe adding this to check for the AC_CACHE_CHECK([whether _AC_LANG preprocessor accepts -xc],php_cv_c_preproc_x_flag_ok,[
save_CPPFLAGS=$CPPFLAGS
CPPFLAGS="$CPPFLAGS -xc"
AC_PREPROC_IFELSE(
[AC_LANG_PROGRAM()],
[php_cv_c_preproc_x_flag_ok=yes],
[php_cv_c_preproc_x_flag_ok=no])
CPPFLAGS=$save_CPPFLAGS
])
AS_IF([test "$php_cv_c_preproc_x_flag_ok" = "yes"],[DTRACE_CPP_FLAGS=" -xc"]) And then in the first changed line in the PR: $ac_bdir[$]ac_hdrobj: $abs_srcdir/$ac_provsrc
- CPP="\$(CPP)" CC="\$(CC)" CFLAGS="\$(CFLAGS_CLEAN)" dtrace -h -C -s $ac_srcdir[$]ac_provsrc -o \$[]@.bak && \$(SED) -e 's,PHP_,DTRACE_,g' \$[]@.bak > \$[]@
+ CPP="\$(CPP)$DTRACE_CPP_FLAGS" dtrace -h -C -s $ac_srcdir[$]ac_provsrc -o \$[]@.bak && \$(SED) -e 's,PHP_,DTRACE_,g' \$[]@.bak > \$[]@
\$(PHP_DTRACE_OBJS): $ac_bdir[$]ac_hdrobj Patchdiff --git a/build/php.m4 b/build/php.m4
index 921a78eb78..26b564309e 100644
--- a/build/php.m4
+++ b/build/php.m4
@@ -2381,6 +2381,17 @@ dnl DTrace objects.
;;
esac
+AC_CACHE_CHECK([whether _AC_LANG preprocessor accepts -xc],php_cv_c_preproc_x_flag_ok,[
+save_CPPFLAGS=$CPPFLAGS
+CPPFLAGS="$CPPFLAGS -xc"
+AC_PREPROC_IFELSE(
+ [AC_LANG_PROGRAM()],
+ [php_cv_c_preproc_x_flag_ok=yes],
+ [php_cv_c_preproc_x_flag_ok=no])
+CPPFLAGS=$save_CPPFLAGS
+])
+AS_IF([test "$php_cv_c_preproc_x_flag_ok" = "yes"],[DTRACE_CPP_FLAGS=" -xc"])
+
dnl Generate Makefile.objects entries. The empty $ac_provsrc command stops an
dnl implicit circular dependency in GNU Make which causes the .d file to be
dnl overwritten (Bug 61268).
@@ -2389,7 +2400,7 @@ dnl overwritten (Bug 61268).
$abs_srcdir/$ac_provsrc:;
$ac_bdir[$]ac_hdrobj: $abs_srcdir/$ac_provsrc
- CPP="\$(CPP)" CC="\$(CC)" CFLAGS="\$(CFLAGS_CLEAN)" dtrace -h -C -s $ac_srcdir[$]ac_provsrc -o \$[]@.bak && \$(SED) -e 's,PHP_,DTRACE_,g' \$[]@.bak > \$[]@
+ CPP="\$(CPP)$DTRACE_CPP_FLAGS" dtrace -h -C -s $ac_srcdir[$]ac_provsrc -o \$[]@.bak && \$(SED) -e 's,PHP_,DTRACE_,g' \$[]@.bak > \$[]@
\$(PHP_DTRACE_OBJS): $ac_bdir[$]ac_hdrobj |
Other
No it is not. But it does not matter. Other operating system and DTrace implementation do not care. The fact we set I can definitely imagine someone building PHP with DTrace enabled using SystemTap and wanting to use compiler suite or preprocessor which is different from what they used to build SystemTap itself or their Linux kernel and which does not recognize -x option. However, I don't think it is reasonable to accommodate for such use case. Especially not by introducing another variable, macro etc. unless properly abstracted. Properly solving this would require implementing non-trivial m4 macros, which I don't believe is not warranted given this affects 2 lines of make commands… The problem here isn't C preprocessor. It's SystemTap’s Why no one? This would be for people who compile PHP on Linux with SystemTap with DTrace enabled using different compiler suite than the one used to compile their kernel and SystemTap and that different compiler suite or specifically its preprocessor does not recognize GCC-style From another point, I was apparently the first person in a decade who cared enough about cross-compilation on Linux and DTrace to look into it. And that's orders of magnitude more common use case. I suspect many Linux distribution disable DTrace in PHP on some machine architectures because of lack of cross-compilation and even their maintainers and communities didn't care enough. And the issue is really there since introduction of DTrace to PHP… In summary, I don't agree with any proposed modifications. I see your point, but I believe they don’t go the necessary length to actually bring the value you are probably looking for. On the contrary, I believe they introduce bloat at best and mislead reader of the code that there's some sophistication around DTrace while there’s none. Last, oversimplified recap: |
Given what has been said so far, I actually see only one other possible change I would be willing to put my name under. That is removal of By the way, use of these environment variables is undocumented SystemTap behavior anyway. But I have chosen to still include |
What I'm not willing to put my name under is additional code which hides intentions, is half-baked or introduces unnecessary indirection or bloat. If anyone feels neither this PR as-is is good, nor the removal |
Other than @petk I don't think any of us are very familiar with the build system soooooooooo |
@f4z4on ok, then let's do that what is in the PR. If the need comes to change it further, we can adapt it later on more. No, worries. Because DTrace should kind of target more architectures later on also. Using DTrace on Windows, for example, seems to be possible, so I'm guessing DTrace goal is to be kind of ubiquitous at some point (just as a theoretic example). Well, build system is just like a configuration. It needs to change and adapt as the code changes so it compiles and runs properly. Yes, exactly. The build system needs to prepare the invocation of DTrace. That's why that additional check was suggested - preparing the DTrace invocation step by step. And user input kind of can't be blindly trusted it is correct. :) |
I appreciate your understanding! We may never fully agree on this, because we are looking at this from very different perspectives. Text is not good for this. I'll try one more time though. I think you're seeing the I’m seeing
That’s actually kind of my point. DTrace on Windows is (already) based on Open DTrace and follows referential behavior (that is as described in Oracle documentation)… If Microsoft introduces support for statically-defined tracing (SDT), I bet it’s going to work the same. Every other DTrace implementation follows what I would call, a referential implementation—Oracle DTrace. DTrace on macOS is still a fork from Oracle I think. I’m not sure what the situation is on BSDs nowadays. One thing is clear though, everyone is shifting to Open DTrace. For the purpose of the issue at hand, there’s no difference between Open DTrace, Oracle DTrace, nor any of their forks. The only outlier here is Linux with SystemTap. If someone on Linux integrated Open DTrace, all would be fine as-is. It is unlikely given the rise of eBPF, I’m just saying… It’s actually more likely Linux is going to drift away even further in case Red Hat finds another shiny new idea philosophically closer to eBPF and abandons SystemTap and its SDT compatibility with DTrace. As far as I'm concerned, Given this, someone could say: “OK, there are more DTrace implementations much like there are more compiler suites. Let’s create Autoconf macros to properly detect them…” And I would be all for that. However, that should be contributed to Autoconf or SystemTap or some other place, not to PHP… Somewhere in those macros, GNU Build System magicians can think of interoperable way of invoking C preprocessor… I think focusing on @petk, even your suggestion to add new Autoconf macro which could kind of be okay. But it is not a proper way to do things with GNU Build System. That Autoconf macro should be linked to Automake macro, so that there’s a new resulting Make macro. Still not that much of a code, but it’s another variable, which is another cost, another cognitive load, etc. Even if you thought about it as a compromise, I don't think it’s worth it given the oversimplification of |
I’m sorry. The If anything, this realization shows me the need for some sort of Autoconf macros for To recap: My original issue from #11643 was that I could not cross-compile on Linux with SystemTap. We solved it by introducing additional SystemTap-specific environment variables. This broke the defaults on Linux with SystemTap as described in #11847. I propose we fix it just by fixing SystemTap on Linux (which practically also implies GCC) and do nothing else. Because anything else that has been proposed so far does not even scratch the complexity of the issue and IMHO does not move in the right direction. I hope I may find some time to properly address |
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.
Allrighty then. Sounds good. I understand. Thanks for the explanations, @f4z4on
The preprocessor is otherwise also checked at the beginning of configure run (using the AC_PROG_CPP
), so that calms me a bit more if something exotic will be inserted into CPP variable. :)
I've checked this on few build cases and looks ok to me.
I'm adding also @remicollet to reviewers to add it to the master branch for the next PHP-8.3 release then.
cb22f22
to
1b092c6
Compare
Sorry for the close… A have changed commit messages based on the discussion above and some realizations, rebased the commits, but accidentally pushed origin master |
With DTrace support enabled during ./configure, our custom Autoconf macro PHP_INIT_DTRACE creates make rules to generate header and object files using dtrace utility. SystemTap† implementation of dtrace relies on other utilities to provide header preprocessing and final object file compilation. These utilities are configured by common environment variables with common defaults:‡ * preprocessor from CPP defaults to “cpp” * compiler from CC defaults to “gcc” * compiler arguments can be expanded with CFLAGS This has been in SystemTap since version 1.5 released on 2011-05-23. We have been setting CFLAGS for dtrace since 717b367 released in versions 5.4.20 and 5.5.4 on 2013-09-18. This change fixed build against SystemTap. It fixes majority of cases since practically all free Linux distributions use SystemTap for DTrace-like dynamic tracing and practically all of them use GCC or compatible compiler suite. However, this becomes an issue when cross-compiling using GCC because utility names contain target triplets. Autoconf already handles cross-compilation well —setting correct CC and CPP make macros (variables). Therefore, we simply set CC and CPP environment variables using respective macros when executing dtrace. Although SystemTap dtrace does not always use CC nor CPP, we set it every time. SystemTap documentation does not talk about this at all¶, so it is safer to always set it. We also follow how we set CFLAGS every time in the past. Original (or ported) DTrace mainly used on Oracle Linux, Solaris and macOS ignores these and does not support cross compilation.§ † Well-known dynamic tracing infrastructure for Linux compatible with statically-defined tracing from DTrace. ‡ https://sourceware.org/git/?p=systemtap.git;a=blob;f=dtrace.in;h=73a6f22e2de072773c692e3fea05c4b8cf814e43;hb=ebb424eee5599fcc131901c0d82d0bfc0d2f57ab ¶ https://sourceware.org/systemtap/man/dtrace.1.html § https://docs.oracle.com/cd/E88353_01/html/E72487/dtrace-8.html Closes GH-11643
@f4z4on what if we also remove the CPP variable entirely from the header invocation? This would work ok with chosen compiler? Because on Debian where cc -E is used, the -xc option doesn't work (it is configured differently via configure) and some other options should be then appended. It would be quite challenging to discover the proper -xc for every case out there otherwise. |
@petk Strange… Out of curiosity, are you talking about typical Debian installation with Nevertheless, it is a real issue and your proposal would work. SystemTap and other DTrace implementations default to I wasn’t in a rush to change anything as I’m quite busy with other stuff and @remicollet seems under a barrage of other issue too. But I’ll change the PR and rebase it shortly… |
We are experiencing an issue when building PHP with DTrace enabled with SystemTap (see phpGH-11847).† The issue is caused by inappropriate use C preprocessor detected by GNU Autoconf in our “configure” script. C preprocessor configuration found by AC_PROG_CPP macro is portable only to run on files with “.c” extension.‡ However, statically-defined tracing is described by D programs with “.d” extension which causes the issue. We experience this even on typical Linux distribution with GNU Compiler Collection (GCC) unless we override the defaults detected by our “configure” script. Many major Linux distributions use SystemTap to provide “dtrace” utility. It relies on both external C preprocessor and external C compiler. C preprocessor can be customized via CPP environment variable. Similarly, C compiler can be customized via CC environment variable. It also allows customization of C compiler flags via CFLAGS environment variable. We have recently aligned both CPP and CC environment variable with C preprocessor and C compiler we use to build regular C source code as provided by our “configure” script (see phpGH-11643).* We wanted to allow cross-compilation on Linux for which this was the only blocker. C compiler flags from CFLAGS_CLEAN macro have already been in place since versions 5.4.20 and 5.5.4 from 2013-09-18. We had modified all “dtrace” invocations in the same way to make it look consistent. However, only the C compiler (CC environment variable) is necessary to for cross-compilation. There have never been any reported issue with the C preprocessor. We acknowledge it would be great to allow C preprocessor customization as well. However, the implementation would require a lot of effort to do correctly given the limitations of AC_PROG_CPP macro from GNU Autoconf. This would be further complicated by the fact that all DTrace implementations, not just SystemTap, allow C preprocessor customization but Oracle DTrace, Open DTrace, and their forks do it differently. Nevertheless, they all default to “cpp” utility and they all have or had been working fine. Therefore, we believe simply removing CPP stabilizes “dtrace” invocation on Linux systems with SystemTap and aligns it with other system configurations on other platforms, until someone comes with complete solution with custom “m4” and “make” macros, while our build system on Linux with SystemTap supports cross-compilation. Fixes phpGH-11847 † php#11847 ‡ https://www.gnu.org/savannah-checkouts/gnu/autoconf/manual/autoconf-2.71/autoconf.html#index-AC_005fPROG_005fCPP-1 * php#11643
I have read through all of this and agree that custom |
I think if it really needs some customization, then a new variable as proposed by @petk in other PR, should be used instead as this is a special case where extra |
0522d84
to
8463cc8
Compare
Because it is effectively a different approach I opened a new PR #12083. |
Consistency and, in a way, premature optimization (a.k.a. the root of all evil 😅). I found out |
@f4z4on it is Debian Bullseye. I've checked using the Docker image debian:bullseye-slim and installed gcc g++ from default APT packages. Otherwise, there is this recommendation to do something like this in such cases: /* zend_drace_d.c */
#include "zend_dtrace.d" But it also didn't work with the |
We are experiencing an issue when building PHP with DTrace enabled with SystemTap (see #11847).† SystemTap, unlike Oracle DTrace, Open DTrace or their forks, relies on both external C compiler and external preprocessor. We have recently aligned both of these with compiler and preprocessor we use to build regular C source code (see #11643).‡ We set
CPP
environment variable to the value of ourCPP
macro which defaults to C preprocessor detected byconfigure
script. Similarly, we setCC
environment variable to the value of ourCC
macro which defaults to C compiler detected byconfigure
script. C compiler flags fromCFLAGS_CLEAN
macro have already been in place since versions 5.4.20 and 5.5.4 from 2013-09-18.We had modified all
dtrace
invocations in the same way to make it look consistent. However, SystemTap dtrace needs C preprocessor only when it generates header files (-h
option) with preprocessing (-C
option). Similarly, it needs C compiler only when it generates object files with probe definitions (-G
option). External C preprocessor use via the-C
option is actually common todtrace
implementations other than SystemTap even for actions other than generating header files. However, customization of C preprocessor differs widely between SystemTap and the rest of DTrace ecosystem (for example, no other implementation uses environment variables). Therefore, we have recently stopped setting all these environment variables when invokingdtrace
. We set only what is necessary for particular action. We hope it makes this fix simpler and clearer without introducing additional complexity to our build system.The cause of our issue is the fact that GCC preprocessor, when invoked via
gcc
binary, detects the language for preprocessing from source file extensions. Because DTrace probes and providers for statically-defined tracing are in files with.d
extension, GCC detection fails because it probably thinks it is processing proper D programing language source code (somewhat different from what DTrace uses) which has no C-style preprocessing macros. People have noticed, becauseconfigure
script on systems with GCC setsCPP
make macro togcc -E
. Therefore practically everyone, who does not override C preprocessor tocpp,
who is building PHP with DTrace enabled on Linux with SystemTap, experiences this issue.We force C language when passing C preprocessor as set by the user or detected by the
configure
script. D programs for DTrace commonly use C language preprocessor. This includes statically-defined tracing probes which can contain the same#pragma
directives known from C and similar languages.We use
-x
option from GCC to force C. Other compilers suites and their preprocessors may recognize this option too (most notably Clang). Many probably do not. However, this issue is specific to SystemTap, which is itself specific to Linux and has to be build using the same compiler as Linux kernel, which only supports building using GCC-compatible compilers. This limitation of using only GCC-compatible compiler suite does not apply to applications with statically-defined tracing. We can definitely imagine someone building PHP with DTrace enabled using SystemTap and wanting to use compiler suite or preprocessor which is different from what they used to build SystemTap itself or their Linux kernel and which does not recognize the-x
option. However, we do not think it is reasonable to accommodate for such use case. Properly solving this would require implementing non-trivial m4 macros, which is probably not warranted given this affects 8 lines of make commands… Moreover, such macros probably belong to a project like GNU Autoconf rather than to PHP.This has no effect on Oracle DTrace, Open DTrace or any of their forks because they do not allow customization of preprocessor nor compiler via environment variables. They simply ignore
CPP
,CC
, andCFLAGS
environment variables, so it does not matter what values we set there.