Note: This bug is displayed in read-only format because
the product is no longer active in Red Hat Bugzilla.
RHEL Engineering is moving the tracking of its product development work on RHEL 6 through RHEL 9 to Red Hat Jira (issues.redhat.com). If you're a Red Hat customer, please continue to file support cases via the Red Hat customer portal. If you're not, please head to the "RHEL project" in Red Hat Jira and file new tickets here. Individual Bugzilla bugs in the statuses "NEW", "ASSIGNED", and "POST" are being migrated throughout September 2023. Bugs of Red Hat partners with an assigned Engineering Partner Manager (EPM) are migrated in late September as per pre-agreed dates. Bugs against components "kernel", "kernel-rt", and "kpatch" are only migrated if still in "NEW" or "ASSIGNED". If you cannot log in to RH Jira, please consult article #7032570. That failing, please send an e-mail to the RH Jira admins at rh-issues@redhat.com to troubleshoot your issue as a user management inquiry. The email creates a ServiceNow ticket with Red Hat. Individual Bugzilla bugs that are migrated will be moved to status "CLOSED", resolution "MIGRATED", and set with "MigratedToJIRA" in "Keywords". The link to the successor Jira issue will be found under "Links", have a little "two-footprint" icon next to it, and direct you to the "RHEL project" in Red Hat Jira (issue links are of type "https://issues.redhat.com/browse/RHEL-XXXX", where "X" is a digit). This same link will be available in a blue banner at the top of the page informing you that that bug has been migrated.
Description of problem:
Compiling a program with Clang that uses DTRACE_PROBE4() fails on a ppc64le host. Same program compiles fine with gcc on ppc64le or with Clang on a x86 host.
Version-Release number of selected component (if applicable):
systemtap-sdt-devel-4.4-10.el8.ppc64le
clang-11.0.0-1.module+el8.4.0+8598+a071fcd5.ppc64le
How reproducible:
100%
Steps to Reproduce:
1. cat > /tmp/probetest.c << EOF
#include <sys/sdt.h>
void func(int a, int b, int c, int d)
{
DTRACE_PROBE4(my_provider, my_probe, a, b, c, d);
}
int main(int argc, char **argv)
{
func(0, 1, 2, 3);
return 0;
}
EOF
2. clang -c /tmp/probetest.c
Actual results:
/tmp/probetest.c:5:5: error: invalid operand in inline asm: '990: nop.pushsection .note.stapsdt,"?","note".balign 4.4byte 992f-991f,994f-993f,3991: .asciz "stapsdt"992: .balign 4993: .8byte 990b.8byte _.stapsdt.base.8byte 0.asciz "my_provider".asciz "my_probe".asciz "${0:n}@${1:I}$1 ${2:n}@${3:I}$3 ${4:n}@${5:I}$5 ${6:n}@${7:I}$7"994: .balign 4.popsection'
DTRACE_PROBE4(my_provider, my_probe, a, b, c, d);
^
/usr/include/sys/sdt.h:437:3: note: expanded from macro 'DTRACE_PROBE4'
STAP_PROBE4(provider,probe,parm1,parm2,parm3,parm4)
^
/usr/include/sys/sdt.h:329:3: note: expanded from macro 'STAP_PROBE4'
_SDT_PROBE(provider, name, 4, (arg1, arg2, arg3, arg4))
^
/usr/include/sys/sdt.h:77:27: note: expanded from macro '_SDT_PROBE'
__asm__ __volatile__ (_SDT_ASM_BODY(provider, name, _SDT_ASM_ARGS, (n)) \
^
note: (skipping 1 expansions in backtrace; use -fmacro-backtrace-limit=0 to see all)
/usr/include/sys/sdt.h:82:26: note: expanded from macro '_SDT_ASM_1'
# define _SDT_ASM_1(x) _SDT_S(x) "\n"
^
/usr/include/sys/sdt.h:81:22: note: expanded from macro '_SDT_S'
# define _SDT_S(x) #x
^
<scratch space>:2:1: note: expanded from here
"990: nop"
^
Expected results:
Example program should get compiled successfully.
Additional info:
Same problem exists in the current version for RHEL9, so please clone this BZ to RHEL9 if necessary.
"invalid operand in inline asm" type errors tend to be consequences of compiler optimizations fighting with the STAP_SDT_ARG_CONSTRAINT parameter for governing the inline-assembler operands. These tend not to be bugs either in llvm, the instrumented application, nor in systemtap, but just an unlucky integration difficulty.
See /usr/include/sys/sdt.h for a brief blurb on the phenomenon. Consider a #define'ing a different STAP_SDT_ARG_CONSTRAINT.
It seems to work indeed if I set STAP_SDT_ARG_CONSTRAINT to either "nr" or "r" instead of "nor", so seems like Clang does not like the "o" constraint on ppc64.
Now I don't think it makes sense to clutter userspace programs with STAP_SDT_ARG_CONSTRAINT depending on the architecture and compiler that is getting used.
So how could we proceed here in a more generic way? Should this BZ get re-assigned to the clang component, so they could fix the problem with the "o" constraint? Or would it make more sense to include a "#if defined(__clang__) && defined(__ppc64__)" section in sys/sdt.h to define a differnt default value for STAP_SDT_ARG_CONSTRAINT in that case?
(In reply to Thomas Huth from comment #2)
> It seems to work indeed if I set STAP_SDT_ARG_CONSTRAINT to either "nr" or
> "r" instead of "nor", so seems like Clang does not like the "o" constraint
> on ppc64.
Doesn't like it as in doesn't support it at all, or that particular point of code with that particular constraint generates an error? Note that on __powerpc__, the sys/sdt.h file uses nZr as the default (line 100ish).
> Now I don't think it makes sense to clutter userspace programs with
> STAP_SDT_ARG_CONSTRAINT depending on the architecture and compiler that is
> getting used.
The problem is that the constraints represent a tradeoff that systemtap is not well positioned to impose. An "r" constraint forces the compiler to load all the parameters into registers, even if they didn't otherwise need to be there. That means increasing register pressure, which if in some tight loop could hit performance. For a given region of code, there might simply not be enough free registers, and we get an error anyway.
This parameter gives developers some power to choose, and the occasional necessity.
(In reply to Frank Ch. Eigler from comment #4)
> Doesn't like it as in doesn't support it at all, or that particular point of
> code with that particular constraint generates an error? Note that on
> __powerpc__, the sys/sdt.h file uses nZr as the default (line 100ish).
[...]
> This parameter gives developers some power to choose, and the occasional
> necessity.
The code works perfectly fine when using gcc on that ppc64le machine. So I think the constraint should normally not be an issue here. It's just that Clang does not like it at all...
(In reply to Tom Stellard from comment #7)
> Does someone have a reduced test case with the failing inline asm statement?
If I preprocess the above example and strip down the result to the bare minimum, I end up with:
void func(int myarg)
{
asm volatile(" .asciz \"%n[S1]@%I[A1]%[A1]\" "
:: [S1] "n" (1), [A1] "nZr" ((myarg)));
}
int main(int argc, char **argv)
{
func(0);
return 0;
}
... which still compiles fine with gcc on ppc64le and still produces the "invalid operand in inline asm" with clang.
Since the problem described in this bug report should be
resolved in a recent advisory, it has been closed with a
resolution of ERRATA.
For information on the advisory (llvm-toolset:rhel8 bug fix and enhancement update), and where to find the updated
files, follow the link below.
If the solution does not work for you, open a new bug report.
https://access.redhat.com/errata/RHEA-2021:4233
Description of problem: Compiling a program with Clang that uses DTRACE_PROBE4() fails on a ppc64le host. Same program compiles fine with gcc on ppc64le or with Clang on a x86 host. Version-Release number of selected component (if applicable): systemtap-sdt-devel-4.4-10.el8.ppc64le clang-11.0.0-1.module+el8.4.0+8598+a071fcd5.ppc64le How reproducible: 100% Steps to Reproduce: 1. cat > /tmp/probetest.c << EOF #include <sys/sdt.h> void func(int a, int b, int c, int d) { DTRACE_PROBE4(my_provider, my_probe, a, b, c, d); } int main(int argc, char **argv) { func(0, 1, 2, 3); return 0; } EOF 2. clang -c /tmp/probetest.c Actual results: /tmp/probetest.c:5:5: error: invalid operand in inline asm: '990: nop.pushsection .note.stapsdt,"?","note".balign 4.4byte 992f-991f,994f-993f,3991: .asciz "stapsdt"992: .balign 4993: .8byte 990b.8byte _.stapsdt.base.8byte 0.asciz "my_provider".asciz "my_probe".asciz "${0:n}@${1:I}$1 ${2:n}@${3:I}$3 ${4:n}@${5:I}$5 ${6:n}@${7:I}$7"994: .balign 4.popsection' DTRACE_PROBE4(my_provider, my_probe, a, b, c, d); ^ /usr/include/sys/sdt.h:437:3: note: expanded from macro 'DTRACE_PROBE4' STAP_PROBE4(provider,probe,parm1,parm2,parm3,parm4) ^ /usr/include/sys/sdt.h:329:3: note: expanded from macro 'STAP_PROBE4' _SDT_PROBE(provider, name, 4, (arg1, arg2, arg3, arg4)) ^ /usr/include/sys/sdt.h:77:27: note: expanded from macro '_SDT_PROBE' __asm__ __volatile__ (_SDT_ASM_BODY(provider, name, _SDT_ASM_ARGS, (n)) \ ^ note: (skipping 1 expansions in backtrace; use -fmacro-backtrace-limit=0 to see all) /usr/include/sys/sdt.h:82:26: note: expanded from macro '_SDT_ASM_1' # define _SDT_ASM_1(x) _SDT_S(x) "\n" ^ /usr/include/sys/sdt.h:81:22: note: expanded from macro '_SDT_S' # define _SDT_S(x) #x ^ <scratch space>:2:1: note: expanded from here "990: nop" ^ Expected results: Example program should get compiled successfully. Additional info: Same problem exists in the current version for RHEL9, so please clone this BZ to RHEL9 if necessary.