Skip to content
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

Fix compilation error with 'use=dtrace' for FreeBSD 11 #2343

Merged
merged 2 commits into from
Nov 21, 2017

Conversation

slfritchie
Copy link
Contributor

The current build procedure for 'make use=dtrace' is working
correctly for OS X and Linux+SystemTap because both are hybrids
compared to the original Solaris implementation. FreeBSD's
implementation is very close to Solaris's.

The original implemntation requires a two-stage process for compiling
the USDT probe specification file, e.g., src/common/dtrace_probes.d).
The first stage, dtrace -h, creates the C header file prerequisite
for compilation. The second stage, dtrace -G, analyzes the object
files for DTrace probe data and creates a new object file that must
also be linked into the executable.

The Makefile procedure for the second stage for Linux is apparently
sufficient for Linux+SystemTap but isn't sufficient for FreeBSD.
The FreeBSD linker does not automatically add the dtrace_probes.o
object file to its workflow. (Presumably Linux's linker does.) The
result are these errors at linking time, using the command
gmake use=dtrace verbose=true:

Linking ponyc
c++  -o build/release-dtrace/ponyc build/release-dtrace/obj/ponyc/main.o -march=native -mtune=generic -mcx16 -L build/release-dtrace -L /usr/local/lib  -L/usr/local/llvm39/lib  -lponyc -lponyrt -lLLVMLTO -lLLVMObjCARCOpts -lLLVMSymbolize -lLLVMDebugInfoPDB -lLLVMDebugInfoDWARF -lLLVMMIRParser -lLLVMCoverage -lLLVMTableGen -lLLVMOrcJIT -lLLVMXCoreDisassembler -lLLVMXCoreCodeGen -lLLVMXCoreDesc -lLLVMXCoreInfo -lLLVMXCoreAsmPrinter -lLLVMSystemZDisassembler -lLLVMSystemZCodeGen -lLLVMSystemZAsmParser -lLLVMSystemZDesc -lLLVMSystemZInfo -lLLVMSystemZAsmPrinter -lLLVMSparcDisassembler -lLLVMSparcCodeGen -lLLVMSparcAsmParser -lLLVMSparcDesc -lLLVMSparcInfo -lLLVMSparcAsmPrinter -lLLVMPowerPCDisassembler -lLLVMPowerPCCodeGen -lLLVMPowerPCAsmParser -lLLVMPowerPCDesc -lLLVMPowerPCInfo -lLLVMPowerPCAsmPrinter -lLLVMNVPTXCodeGen -lLLVMNVPTXDesc -lLLVMNVPTXInfo -lLLVMNVPTXAsmPrinter -lLLVMMSP430CodeGen -lLLVMMSP430Desc -lLLVMMSP430Info -lLLVMMSP430AsmPrinter -lLLVMMipsDisassembler -lLLVMMipsCodeGen -lLLVMMipsAsmParser -lLLVMMipsDesc -lLLVMMipsInfo -lLLVMMipsAsmPrinter -lLLVMHexagonDisassembler -lLLVMHexagonCodeGen -lLLVMHexagonAsmParser -lLLVMHexagonDesc -lLLVMHexagonInfo -lLLVMBPFCodeGen -lLLVMBPFDesc -lLLVMBPFInfo -lLLVMBPFAsmPrinter -lLLVMARMDisassembler -lLLVMARMCodeGen -lLLVMARMAsmParser -lLLVMARMDesc -lLLVMARMInfo -lLLVMARMAsmPrinter -lLLVMAMDGPUDisassembler -lLLVMAMDGPUCodeGen -lLLVMAMDGPUAsmParser -lLLVMAMDGPUDesc -lLLVMAMDGPUInfo -lLLVMAMDGPUAsmPrinter -lLLVMAMDGPUUtils -lLLVMAArch64Disassembler -lLLVMAArch64CodeGen -lLLVMGlobalISel -lLLVMAArch64AsmParser -lLLVMAArch64Desc -lLLVMAArch64Info -lLLVMAArch64AsmPrinter -lLLVMAArch64Utils -lLLVMObjectYAML -lLLVMLibDriver -lLLVMOption -lLLVMX86Disassembler -lLLVMX86AsmParser -lLLVMX86CodeGen -lLLVMSelectionDAG -lLLVMAsmPrinter -lLLVMDebugInfoCodeView -lLLVMX86Desc -lLLVMMCDisassembler -lLLVMX86Info -lLLVMX86AsmPrinter -lLLVMX86Utils -lLLVMMCJIT -lLLVMLineEditor -lLLVMPasses -lLLVMipo -lLLVMVectorize -lLLVMLinker -lLLVMIRReader -lLLVMAsmParser -lLLVMInterpreter -lLLVMExecutionEngine -lLLVMRuntimeDyld -lLLVMObject -lLLVMMCParser -lLLVMCodeGen -lLLVMTarget -lLLVMScalarOpts -lLLVMInstCombine -lLLVMInstrumentation -lLLVMTransformUtils -lLLVMMC -lLLVMBitWriter -lLLVMBitReader -lLLVMAnalysis -lLLVMProfileData -lLLVMCore -lLLVMSupport -lz -lncurses -lpthread -lexecinfo -lblake2 -rdynamic
build/release-dtrace/libponyrt.a(trace.o): In function `pony_gc_send':
src/libponyrt/gc/trace.c:(.text+0x19): undefined reference to `__dtrace_pony___gc__send__start'
build/release-dtrace/libponyrt.a(trace.o): In function `pony_gc_recv':
src/libponyrt/gc/trace.c:(.text+0x39): undefined reference to `__dtrace_pony___gc__recv__start'
build/release-dtrace/libponyrt.a(trace.o): In function `pony_send_done':
src/libponyrt/gc/trace.c:(.text+0xd1): undefined reference to `__dtrace_pony___gc__send__end'
build/release-dtrace/libponyrt.a(trace.o): In function `pony_recv_done':
src/libponyrt/gc/trace.c:(.text+0x109): undefined reference to `__dtrace_pony___gc__recv__end'
build/release-dtrace/libponyrt.a(heap.o): In function `ponyint_heap_setnextgcfactor':
src/libponyrt/mem/heap.c:(.text+0x5a): undefined reference to `__dtrace_pony___gc__threshold'
[... 54 additional lines of output omitted ...]

AFAICT, the Pony compiler gives the linker several -L flags in to
specify where libponyrt.a and perhaps other library files may
be stored: in the ponyc repo, or in the make install destination
directory. If we tell the linker to link dtrace_probes.o
directly, then we need to give a correct, full path to it.
However, if we put dtrace_probes.o into a library, then we can
let the linker search its list of directories (one of them will be
good).

To force the linker to read & use the data in the new shared
library, libdtrace_probes.a, I've also added the flag
-Wl,--whole-archive to the linker's command line. (NOTE: using
the --whole-archive trick on the entire libponyrt.a library
had some side effects that IMHO makes it worthwhile to put the
DTrace stuff into a new library file. If PR review really does
not like the new library file, please say so.)

Tested on FreeBSD 11.1-RELEASE, Ubuntu 16.04, and OS X Sierra, all 64 bit, all with & without use=dtrace argument to make.

The current build procedure for 'make use=dtrace' is working
correctly for OS X and Linux+SystemTap because both are hybrids
compared to the original Solaris implementation.  FreeBSD's
implementation is very close to Solaris's.

The original implemntation requires a two-stage process for compiling
the USDT probe specification file, e.g., `src/common/dtrace_probes.d`).
The first stage, `dtrace -h`, creates the C header file prerequisite
for compilation.  The second stage, `dtrace -G`, analyzes the object
files for DTrace probe data and creates a new object file that must
also be linked into the executable.

The `Makefile` procedure for the second stage for Linux is apparently
sufficient for Linux+SystemTap but isn't sufficient for FreeBSD.
The FreeBSD linker does not automatically add the `dtrace_probes.o`
object file to its workflow.  (Presumably Linux's linker does.)  The
result are these errors at linking time, using the command
`gmake use=dtrace verbose=true`:

    Linking ponyc
    c++  -o build/release-dtrace/ponyc build/release-dtrace/obj/ponyc/main.o -march=native -mtune=generic -mcx16 -L build/release-dtrace -L /usr/local/lib  -L/usr/local/llvm39/lib  -lponyc -lponyrt -lLLVMLTO -lLLVMObjCARCOpts -lLLVMSymbolize -lLLVMDebugInfoPDB -lLLVMDebugInfoDWARF -lLLVMMIRParser -lLLVMCoverage -lLLVMTableGen -lLLVMOrcJIT -lLLVMXCoreDisassembler -lLLVMXCoreCodeGen -lLLVMXCoreDesc -lLLVMXCoreInfo -lLLVMXCoreAsmPrinter -lLLVMSystemZDisassembler -lLLVMSystemZCodeGen -lLLVMSystemZAsmParser -lLLVMSystemZDesc -lLLVMSystemZInfo -lLLVMSystemZAsmPrinter -lLLVMSparcDisassembler -lLLVMSparcCodeGen -lLLVMSparcAsmParser -lLLVMSparcDesc -lLLVMSparcInfo -lLLVMSparcAsmPrinter -lLLVMPowerPCDisassembler -lLLVMPowerPCCodeGen -lLLVMPowerPCAsmParser -lLLVMPowerPCDesc -lLLVMPowerPCInfo -lLLVMPowerPCAsmPrinter -lLLVMNVPTXCodeGen -lLLVMNVPTXDesc -lLLVMNVPTXInfo -lLLVMNVPTXAsmPrinter -lLLVMMSP430CodeGen -lLLVMMSP430Desc -lLLVMMSP430Info -lLLVMMSP430AsmPrinter -lLLVMMipsDisassembler -lLLVMMipsCodeGen -lLLVMMipsAsmParser -lLLVMMipsDesc -lLLVMMipsInfo -lLLVMMipsAsmPrinter -lLLVMHexagonDisassembler -lLLVMHexagonCodeGen -lLLVMHexagonAsmParser -lLLVMHexagonDesc -lLLVMHexagonInfo -lLLVMBPFCodeGen -lLLVMBPFDesc -lLLVMBPFInfo -lLLVMBPFAsmPrinter -lLLVMARMDisassembler -lLLVMARMCodeGen -lLLVMARMAsmParser -lLLVMARMDesc -lLLVMARMInfo -lLLVMARMAsmPrinter -lLLVMAMDGPUDisassembler -lLLVMAMDGPUCodeGen -lLLVMAMDGPUAsmParser -lLLVMAMDGPUDesc -lLLVMAMDGPUInfo -lLLVMAMDGPUAsmPrinter -lLLVMAMDGPUUtils -lLLVMAArch64Disassembler -lLLVMAArch64CodeGen -lLLVMGlobalISel -lLLVMAArch64AsmParser -lLLVMAArch64Desc -lLLVMAArch64Info -lLLVMAArch64AsmPrinter -lLLVMAArch64Utils -lLLVMObjectYAML -lLLVMLibDriver -lLLVMOption -lLLVMX86Disassembler -lLLVMX86AsmParser -lLLVMX86CodeGen -lLLVMSelectionDAG -lLLVMAsmPrinter -lLLVMDebugInfoCodeView -lLLVMX86Desc -lLLVMMCDisassembler -lLLVMX86Info -lLLVMX86AsmPrinter -lLLVMX86Utils -lLLVMMCJIT -lLLVMLineEditor -lLLVMPasses -lLLVMipo -lLLVMVectorize -lLLVMLinker -lLLVMIRReader -lLLVMAsmParser -lLLVMInterpreter -lLLVMExecutionEngine -lLLVMRuntimeDyld -lLLVMObject -lLLVMMCParser -lLLVMCodeGen -lLLVMTarget -lLLVMScalarOpts -lLLVMInstCombine -lLLVMInstrumentation -lLLVMTransformUtils -lLLVMMC -lLLVMBitWriter -lLLVMBitReader -lLLVMAnalysis -lLLVMProfileData -lLLVMCore -lLLVMSupport -lz -lncurses -lpthread -lexecinfo -lblake2 -rdynamic
    build/release-dtrace/libponyrt.a(trace.o): In function `pony_gc_send':
    src/libponyrt/gc/trace.c:(.text+0x19): undefined reference to `__dtrace_pony___gc__send__start'
    build/release-dtrace/libponyrt.a(trace.o): In function `pony_gc_recv':
    src/libponyrt/gc/trace.c:(.text+0x39): undefined reference to `__dtrace_pony___gc__recv__start'
    build/release-dtrace/libponyrt.a(trace.o): In function `pony_send_done':
    src/libponyrt/gc/trace.c:(.text+0xd1): undefined reference to `__dtrace_pony___gc__send__end'
    build/release-dtrace/libponyrt.a(trace.o): In function `pony_recv_done':
    src/libponyrt/gc/trace.c:(.text+0x109): undefined reference to `__dtrace_pony___gc__recv__end'
    build/release-dtrace/libponyrt.a(heap.o): In function `ponyint_heap_setnextgcfactor':
    src/libponyrt/mem/heap.c:(.text+0x5a): undefined reference to `__dtrace_pony___gc__threshold'
    [... 54 additional lines of output omitted ...]

AFAICT, the Pony compiler gives the linker several `-L` flags in to
specify where `libponyrt.a` and perhaps other library files may
be stored: in the `ponyc` repo, or in the `make install` destination
directory.  If we tell the linker to link `dtrace_probes.o`
directly, then we need to give a correct, full path to it.
However, if we put `dtrace_probes.o` into a library, then we can
let the linker search its list of directories (one of them will be
good).

To force the linker to read & use the data in the new shared
library, `libdtrace_probes.a`, I've also added the flag
`-Wl,--whole-archive` to the linker's command line.  (NOTE: using
the `--whole-archive` trick on the entire `libponyrt.a` library
had some side effects that IMHO makes it worthwhile to put the
DTrace stuff into a new library file.  If PR review really does
not like the new library file, please say so.)
@SeanTAllen SeanTAllen added the changelog - fixed Automatically add "Fixed" CHANGELOG entry on merge label Nov 15, 2017
Makefile Outdated
ifneq ($(wildcard $(PONY_BUILD_DIR)/libdtrace_probes.a),)
$(SILENT)ln $(symlink.flags) $(destdir)/lib/libdtrace_probes.a $(prefix)/lib/libdtrace_probes.a
else
damnit
Copy link
Member

Choose a reason for hiding this comment

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

?

@slfritchie
Copy link
Contributor Author

Hrrmmm, in build 4149 there was a timeout and a test failure in two different builds. The timeout was running the configure script for compiling LLVM, weird, but seems like a sorry-cannot-help-it-sometime ignorable error?

I don't know if the failure of 4149.9 is something to worry about wrt this PR. https://travis-ci.org/ponylang/ponyc/jobs/303646004#L5963 Intermittent CI failures are something to take seriously, but in the short time I've been playing closer attention to this repo, there seems to be some ongoing work to reduce intermittent CI failures, and I don't know if 4149.9's is currently being studied, sorry.

@slfritchie
Copy link
Contributor Author

I restarted both failed jobs, 4149.7 and 4149.9. Both passed this time.

@SeanTAllen SeanTAllen merged commit 1c4e9de into ponylang:master Nov 21, 2017
ponylang-main added a commit that referenced this pull request Nov 21, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
changelog - fixed Automatically add "Fixed" CHANGELOG entry on merge
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants