A simple sdt test with clang fails to build: $ cat foosdt.c #include <sys/sdt.h> void foo(void) { STAP_PROBE(foo, foo); } $ clang -c foosdt.c foosdt.c:4:6: error: unknown flag STAP_PROBE(foo, foo); ^ In file included from foosdt.c:1: /usr/local/include/sys/sdt.h:254:3: note: instantiated from: _SDT_PROBE(provider, name, 0, ()) ^ /usr/local/include/sys/sdt.h:36:27: note: instantiated from: __asm__ __volatile__ (_SDT_ASM_BODY(provider, name, _SDT_ASM_ARGS, (n)) \ ^ /usr/local/include/sys/sdt.h:176:3: note: instantiated from: _SDT_ASM_3( .pushsection .note.stapsdt,_SDT_ASM_AUTOGROUP,"note") \ ^ /usr/local/include/sys/sdt.h:43:31: note: instantiated from: # define _SDT_ASM_3(a, b, c) _SDT_S(a) "," _SDT_S(b) "," \ ^ <scratch space>:4:2: note: instantiated from: ".pushsection .note.stapsdt" ^ <inline asm>:2:31: note: instantiated into assembly here .pushsection .note.stapsdt,"?","note" ^ foosdt.c:4:6: error: .popsection without corresponding .pushsection STAP_PROBE(foo, foo); ^ In file included from foosdt.c:1: /usr/local/include/sys/sdt.h:254:3: note: instantiated from: _SDT_PROBE(provider, name, 0, ()) ^ /usr/local/include/sys/sdt.h:36:27: note: instantiated from: __asm__ __volatile__ (_SDT_ASM_BODY(provider, name, _SDT_ASM_ARGS, (n)) \ ^ /usr/local/include/sys/sdt.h:188:3: note: instantiated from: _SDT_ASM_1( .popsection) ^ /usr/local/include/sys/sdt.h:41:26: note: instantiated from: # define _SDT_ASM_1(x) _SDT_S(x) "\n" ^ <scratch space>:24:2: note: instantiated from: ".popsection" ^ <inline asm>:14:12: note: instantiated into assembly here .popsection ^ foosdt.c:4:6: error: expected '@' or '%' before type STAP_PROBE(foo, foo); ^ In file included from foosdt.c:1: /usr/local/include/sys/sdt.h:254:3: note: instantiated from: _SDT_PROBE(provider, name, 0, ()) ^ /usr/local/include/sys/sdt.h:38:27: note: instantiated from: __asm__ __volatile__ (_SDT_ASM_BASE); \ ^ /usr/local/include/sys/sdt.h:192:3: note: instantiated from: _SDT_ASM_5( .pushsection .stapsdt.base,"aG","progbits", \ ^ /usr/local/include/sys/sdt.h:45:36: note: instantiated from: # define _SDT_ASM_5(a, b, c, d, e) _SDT_S(a) "," _SDT_S(b) "," \ ^ <scratch space>:27:2: note: instantiated from: ".pushsection .stapsdt.base" ^ <inline asm>:2:33: note: instantiated into assembly here .pushsection .stapsdt.base,"aG","progbits",.stapsdt.base,comdat ^ foosdt.c:4:6: error: .popsection without corresponding .pushsection STAP_PROBE(foo, foo); ^ In file included from foosdt.c:1: /usr/local/include/sys/sdt.h:254:3: note: instantiated from: _SDT_PROBE(provider, name, 0, ()) ^ /usr/local/include/sys/sdt.h:38:27: note: instantiated from: __asm__ __volatile__ (_SDT_ASM_BASE); \ ^ /usr/local/include/sys/sdt.h:198:3: note: instantiated from: _SDT_ASM_1( .popsection) \ ^ /usr/local/include/sys/sdt.h:41:26: note: instantiated from: # define _SDT_ASM_1(x) _SDT_S(x) "\n" ^ <scratch space>:37:2: note: instantiated from: ".popsection" ^ <inline asm>:7:12: note: instantiated into assembly here .popsection ^ 4 errors generated.
(In reply to comment #0) > foosdt.c:4:6: error: unknown flag [...] > <inline asm>:2:31: note: instantiated into assembly here > .pushsection .note.stapsdt,"?","note" > ^ This error is due to our compiler-dependent test for sdt-config.h: > /* includes/sys/sdt-config.h. Generated from sdt-config.h.in by configure. > > This file just defines _SDT_ASM_SECTION_AUTOGROUP_SUPPORT to 0 or 1 to > indicate whether the assembler supports "?" in .pushsection directives. */ > > #define _SDT_ASM_SECTION_AUTOGROUP_SUPPORT 1 My installed header was created for gcc, which does support this flag, but clearly clang does not. I'm not sure how we could deal with multiple system compilers in general. Perhaps we'd have to add #ifdef to sdt-config.h to match the compiler which was tested, and assume 0 if encountering something else? With sdt-config.h configured directly with clang, there's a different error at the same place, and the rest of the errors are still the same. > foosdt.c:4:6: error: expected '@' or '%' before type [...] > <inline asm>:2:31: note: instantiated into assembly here > .pushsection .note.stapsdt,"","note" > ^
BTW. It might a good idea to add some configure check before using a feature like SDT probes. Even really old g++ versions have been observed to have trouble with using probe macros in C++ contructors or destructors for example. This configure snippet seems to find all troubling C++ compilers (for C any gcc version seems to be fine, only clang seems to have issues): dnl =================================================================== dnl Check if SDT probes (for systemtap, gdb, dtrace) are available dnl =================================================================== # We need at least the sys/sdt.h include header. AC_CHECK_HEADER([sys/sdt.h], [SDT_H_FOUND='TRUE'], [SDT_H_FOUND='FALSE']) if test "$SDT_H_FOUND" = "TRUE"; then # Found sys/sdt.h header, now make sure the c++ compiler works. # Old g++ versions had problems with probes in constructors/destructors. AC_MSG_CHECKING([working sys/sdt.h and c++ support]) AC_LANG_PUSH([C++]) AC_LINK_IFELSE([AC_LANG_PROGRAM([[ #include <sys/sdt.h> class ProbeClass { private: int& ref; const char *name; public: ProbeClass(int& v, const char *n) : ref(v), name(n) { DTRACE_PROBE2(_test_, cons, name, ref); } void method(int min) { DTRACE_PROBE3(_test_, meth, name, ref, min); ref -= min; } ~ProbeClass() { DTRACE_PROBE2(_test_, dest, name, ref); } }; ]],[[ int i = 64; DTRACE_PROBE1(_test_, call, i); ProbeClass inst = ProbeClass(i, "call"); inst.method(24); ]])], [AC_MSG_RESULT([yes]); AC_DEFINE([USE_SDT_PROBES])], [AC_MSG_RESULT([no, sdt.h or c++ compiler too old])]) AC_LANG_POP([C++]) fi AC_CONFIG_HEADERS([config_probes.h]) Where config_probes.h.in might be something like: #ifndef CONFIG_PROBES_H #define CONFIG_PROBES_H /* Whether we have and can use sys/sdt.h for probes. */ #define USE_SDT_PROBES 0 #endif
Martin C. Martin filed a couple bugs with LLVM: http://llvm.org/bugs/show_bug.cgi?id=17198 http://llvm.org/bugs/show_bug.cgi?id=17270 The first is now fixed with llvm-mc gaining support for the "?" flag. The second gave us a hint that led me to use %note instead of "note", with %%-quoting as needed for operand expansion. This is pushed in commit a31190f5. So I think we can call this FIXED, but let's keep a careful eye on that %note form to make sure it doesn't create problems anywhere else...
(In reply to Josh Stone from comment #3) > The second gave us a hint that led me to use %note instead of "note", with > %%-quoting as needed for operand expansion. This is pushed in commit > a31190f5. I'm actually going to revert this. The difficulty of '%' is that it must be escaped for asm() blocks that have operands, but must not be escaped in asm() blocks without operands, nor for pure ASM source files. But we have a SDT_PROBE_ASM construct available for others to use in their own asm(), where we have no idea if escaping is needed. It turns out glibc uses this, and we broke their build on Fedora rawhide due to bad %-escaping. We can't use @note because GAS says that's a comment on ARM, so we're left back at "note" being the most straightforward. I'll revert the change, but at least now we have some documented justification for the chosen syntax. Besides, LLVM finished up 17270 with support for the "note" syntax, so anyone interested in SDT there can use an LLVM snapshot or wait for their next release.
*** Bug 260998 has been marked as a duplicate of this bug. *** Seen from the domain http://volichat.com Page where seen: http://volichat.com/adult-chat-rooms Marked for reference. Resolved as fixed @bugzilla.