mirror of
https://github.com/hanzoai/node-dtrace-provider.git
synced 2026-09-23 23:48:45 +00:00
chrisa/node-dtrace-provider#96 Improving compilation failure behaviour
Reviewed by: Julien Gilli <[email protected]>
This commit is contained in:
@@ -5,3 +5,5 @@
|
||||
*#
|
||||
build
|
||||
*.log
|
||||
test
|
||||
TODO.md
|
||||
|
||||
@@ -3,6 +3,9 @@ dtrace-provider - Changes
|
||||
|
||||
## HISTORY
|
||||
|
||||
* 0.8.6:
|
||||
Improved compilation failure behaviour (#96)
|
||||
|
||||
* 0.8.5:
|
||||
Reverted "Install fails on Debian due to differently named node binary" for
|
||||
now
|
||||
|
||||
@@ -174,6 +174,31 @@ npm modules to embed probes and include a dependency on this module.
|
||||
GNU Make is required to build libusdt; the build scripts will look for
|
||||
gmake in `PATH` first, and then for make.
|
||||
|
||||
### TROUBLESHOOTING BUILD ISSUES
|
||||
|
||||
If compilation fails during installation on platforms with DTrace, then
|
||||
the library will fall back to the stub implementation that does nothing.
|
||||
To force an installation failure when compiling fails, set the environment
|
||||
variable `NODE_DTRACE_PROVIDER_REQUIRE` to `hard`:
|
||||
|
||||
```shell
|
||||
$ NODE_DTRACE_PROVIDER_REQUIRE=hard npm install
|
||||
```
|
||||
|
||||
This will then show you the output of the build process so you can see at
|
||||
which point it's having an issue. Common issues are:
|
||||
|
||||
- Missing a C/C++ compiler toolchain for your platform.
|
||||
- `python` is Python 3 instead of Python 2; run `npm config set python python2.7`
|
||||
(or similar) to set the Python binary npm uses.
|
||||
- On OS X you may need to agree to the XCode license if that's the compiler
|
||||
toolchain you're using. This will usually manifest with an error like
|
||||
`Agreeing to the Xcode/iOS license requires admin privileges, please re-run as root via sudo.`
|
||||
To accept the license, you can run `sudo xcodebuild -license`.
|
||||
|
||||
Once you've found and fixed the issue, you can run `npm rebuild` to rerun
|
||||
the lifecycle scripts.
|
||||
|
||||
## CAVEATS
|
||||
|
||||
There is some overhead to probes, even when disabled. Probes are
|
||||
@@ -184,12 +209,12 @@ unless probes are placed in particularly hot code paths.
|
||||
|
||||
## CONTRIBUTING
|
||||
|
||||
The source is available at:
|
||||
To clone the project's source code:
|
||||
|
||||
https://github.com/chrisa/node-dtrace-provider
|
||||
$ git clone --recursive https://github.com/chrisa/node-dtrace-provider.git
|
||||
|
||||
For issues, please use the GitHub issue tracker linked to the
|
||||
repository. GitHub pull requests are very welcome.
|
||||
For issues, please use the [GitHub issue tracker](https://github.com/chrisa/node-dtrace-provider/issues)
|
||||
linked to the repository. GitHub pull requests are very welcome.
|
||||
|
||||
## RUNNING THE TESTS
|
||||
|
||||
|
||||
+35
@@ -0,0 +1,35 @@
|
||||
{
|
||||
'conditions': [
|
||||
# If we are on Mac OS X, FreeBSD, or a Solarish system, attempt
|
||||
# to build the DTrace provider extension.
|
||||
['OS=="mac" or OS=="solaris" or OS=="freebsd"', {
|
||||
'targets': [
|
||||
{
|
||||
'target_name': 'ndtp',
|
||||
'type': 'none',
|
||||
'actions': [{
|
||||
'inputs': [''],
|
||||
'outputs': [''],
|
||||
'action_name': 'build_ndtp',
|
||||
'action': [
|
||||
'bash', 'build.sh'
|
||||
]
|
||||
}]
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
# If we are on another system (like Windows or Linux), then DTrace is
|
||||
# unavailable. This target is necessary because GYP requires at least
|
||||
# one target to exist. We end up building nothing, and fall back to the
|
||||
# stub implementation when the package is loaded.
|
||||
{
|
||||
'targets': [
|
||||
{
|
||||
'target_name': 'DTraceProviderStub',
|
||||
'type': 'none'
|
||||
}
|
||||
]
|
||||
}]
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -o pipefail
|
||||
|
||||
if [[ -n "$V" ]]; then
|
||||
set -o xtrace
|
||||
fi
|
||||
|
||||
fail() {
|
||||
if [[ -z "$NODE_DTRACE_PROVIDER_REQUIRE" && -z "$V" ]]; then
|
||||
echo "-----------------------------------------------------------------"
|
||||
echo "Building dtrace-provider failed with exit code $1, falling back"
|
||||
echo "on stub implementation."
|
||||
echo ""
|
||||
echo "Re-run install with V set in your environment to see the build"
|
||||
echo "output, or NODE_DTRACE_PROVIDER_REQUIRE=hard to force an"
|
||||
echo "installation failure."
|
||||
echo "-----------------------------------------------------------------"
|
||||
fi
|
||||
|
||||
if [[ "$NODE_DTRACE_PROVIDER_REQUIRE" == "hard" ]]; then
|
||||
exit 1
|
||||
else
|
||||
exit 0
|
||||
fi
|
||||
}
|
||||
|
||||
buildUSDT() {
|
||||
if [[ -z "$NODE_DTRACE_PROVIDER_REQUIRE" && -z "$V" ]]; then
|
||||
exec 1> /dev/null
|
||||
exec 2> /dev/null
|
||||
fi
|
||||
|
||||
# GYP's MAKEFLAGS confuses libusdt's Makefile
|
||||
unset MAKEFLAGS
|
||||
|
||||
# Ask node what architecture it's been built for ("target_arch" in
|
||||
# config.gypi), and build libusdt to match.
|
||||
#
|
||||
# We use node from the path; npm will have adjusted PATH for us if
|
||||
# necessary, otherwise we assume the user did so when building by
|
||||
# hand.
|
||||
#
|
||||
# (This will need to change at the point that GYP is able to build
|
||||
# node extensions universal on the Mac - for now we'll go with x86_64
|
||||
# on a 64 bit Mac, because that's the default architecture in that
|
||||
# situation.)
|
||||
export ARCH=`node -e "console.log(process.arch === 'x64' ? 'x86_64' : 'i386')"`
|
||||
echo "Building libusdt for ${ARCH}"
|
||||
|
||||
# Respect a MAKE variable if set
|
||||
if [[ -z $MAKE ]]; then
|
||||
# Default to `gmake` first if available, because we require GNU make
|
||||
# and `make` isn't GNU make on some plats.
|
||||
MAKE=`which gmake`
|
||||
if [[ -z $MAKE ]]; then
|
||||
MAKE=make
|
||||
fi
|
||||
fi
|
||||
|
||||
# Build libusdt.
|
||||
$MAKE -C libusdt clean all
|
||||
}
|
||||
|
||||
buildNDTP() {
|
||||
if [[ -z "$NODE_DTRACE_PROVIDER_REQUIRE" && -z "$V" ]]; then
|
||||
exec 1> /dev/null
|
||||
exec 2> /dev/null
|
||||
fi
|
||||
|
||||
node-gyp rebuild -C src
|
||||
}
|
||||
|
||||
(buildUSDT)
|
||||
LIBUSDT_STATUS=$?
|
||||
if [[ "$LIBUSDT_STATUS" -ne 0 ]]; then
|
||||
fail $LIBUSDT_STATUS
|
||||
fi
|
||||
|
||||
(buildNDTP)
|
||||
NODE_GYP_STATUS=$?
|
||||
if [[ "$NODE_GYP_STATUS" -ne 0 ]]; then
|
||||
fail $NODE_GYP_STATUS
|
||||
fi
|
||||
|
||||
exit 0
|
||||
-82
@@ -1,82 +0,0 @@
|
||||
{
|
||||
'conditions': [
|
||||
['OS=="mac" or OS=="solaris" or OS=="freebsd"', {
|
||||
'conditions' : [
|
||||
['OS=="mac" or OS=="solaris"', {
|
||||
'variables': {
|
||||
'escaped_root': '<!(printf %q "<(module_root_dir)")',
|
||||
}
|
||||
}],
|
||||
['OS=="freebsd"', {
|
||||
'variables' : {
|
||||
'escaped_root': '<!(printf %s "<(module_root_dir)")'
|
||||
}
|
||||
}]
|
||||
],
|
||||
|
||||
# If we are on Mac OS X, FreeBSD, or a Solarish system, attempt
|
||||
# to build the DTrace provider extension.
|
||||
|
||||
'targets': [
|
||||
{
|
||||
'target_name': 'DTraceProviderBindings',
|
||||
'sources': [
|
||||
'dtrace_provider.cc',
|
||||
'dtrace_probe.cc',
|
||||
'dtrace_argument.cc'
|
||||
],
|
||||
'conditions': [
|
||||
['OS=="mac" or OS=="solaris"',
|
||||
{ 'include_dirs': [
|
||||
'libusdt',
|
||||
'<!(node -e "require(\'nan\')")',
|
||||
]
|
||||
}
|
||||
],
|
||||
['OS=="freebsd"',
|
||||
{ 'include_dirs': [
|
||||
'/usr/src/cddl/compat/opensolaris/',
|
||||
'/usr/src/sys/cddl/compat/opensolaris',
|
||||
'/usr/src/sys/cddl/contrib/opensolaris/uts/common/',
|
||||
'libusdt',
|
||||
'<!(node -e "require(\'nan\')")'
|
||||
]
|
||||
}
|
||||
]
|
||||
],
|
||||
'dependencies': [
|
||||
'libusdt'
|
||||
],
|
||||
'libraries': [
|
||||
'-L<(escaped_root)/libusdt -l usdt'
|
||||
]
|
||||
},
|
||||
{
|
||||
'target_name': 'libusdt',
|
||||
'type': 'none',
|
||||
'actions': [{
|
||||
'inputs': [''],
|
||||
'outputs': [''],
|
||||
'action_name': 'build_libusdt',
|
||||
'action': [
|
||||
'sh', 'libusdt-build.sh'
|
||||
]
|
||||
}]
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
# If we are not on Mac OS X, FreeBSD or a Solarish system, DTrace is
|
||||
# unavailable. This target is necessary because GYP requires at least
|
||||
# one target to exist.
|
||||
|
||||
{
|
||||
'targets': [
|
||||
{
|
||||
'target_name': 'DTraceProviderStub',
|
||||
'type': 'none'
|
||||
}
|
||||
]
|
||||
}],
|
||||
]
|
||||
}
|
||||
+6
-12
@@ -13,9 +13,9 @@ DTraceProviderStub.prototype.disable = function() {};
|
||||
var builds = ['Release', 'default', 'Debug'];
|
||||
var err = null;
|
||||
|
||||
for (var i in builds) {
|
||||
for (var i = 0; i < builds.length; i++) {
|
||||
try {
|
||||
var binding = require('./build/' + builds[i] + '/DTraceProviderBindings');
|
||||
var binding = require('./src/build/' + builds[i] + '/DTraceProviderBindings');
|
||||
DTraceProvider = binding.DTraceProvider;
|
||||
break;
|
||||
} catch (e) {
|
||||
@@ -26,17 +26,11 @@ for (var i in builds) {
|
||||
}
|
||||
|
||||
if (!DTraceProvider) {
|
||||
/*
|
||||
* If the platform looks like it _should_ have DTrace
|
||||
* available, log a failure to load the bindings.
|
||||
*/
|
||||
if (process.platform === 'darwin' ||
|
||||
process.platform === 'sunos' ||
|
||||
process.platform === 'freebsd') {
|
||||
console.error(err);
|
||||
if (process.env.NODE_DTRACE_PROVIDER_REQUIRE === 'hard') {
|
||||
throw err;
|
||||
} else {
|
||||
DTraceProvider = DTraceProviderStub;
|
||||
}
|
||||
|
||||
DTraceProvider = DTraceProviderStub;
|
||||
}
|
||||
|
||||
exports.DTraceProvider = DTraceProvider;
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
// Output the architecture of this node build, either 'i386' or
|
||||
// 'x86_64'
|
||||
//
|
||||
// This copes with both node 0.6.x and 0.8.x.
|
||||
|
||||
try {
|
||||
// node 0.8
|
||||
console.log(process.config.variables.target_arch == 'x64' ? 'x86_64' : 'i386')
|
||||
}
|
||||
catch (TypeError) {
|
||||
// node 0.6
|
||||
console.log(process.arch == 'x64' ? 'x86_64' : 'i386')
|
||||
};
|
||||
@@ -1,34 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
# GYP's MAKEFLAGS confuses libusdt's Makefile
|
||||
#
|
||||
unset MAKEFLAGS
|
||||
|
||||
# Ask node what arch it's been built for, and build libusdt to match.
|
||||
#
|
||||
# We use node from the path; npm will have adjusted PATH for us if
|
||||
# necessary, otherwise we assume the user did so when building by
|
||||
# hand.
|
||||
#
|
||||
# (this will need to change at the point that GYP is able to build
|
||||
# node extensions universal on the Mac - for now we'll go with x86_64
|
||||
# on a 64 bit Mac, because that's the default architecture in that
|
||||
# situation).
|
||||
#
|
||||
ARCH=`node libusdt-arch.js`
|
||||
echo "Building libusdt for ${ARCH}"
|
||||
export ARCH
|
||||
|
||||
# Respect a MAKE variable if set
|
||||
if [ -z $MAKE ]; then
|
||||
# Default to `gmake` first if available, because we require GNU make
|
||||
# and `make` isn't GNU make on some plats.
|
||||
MAKE=`which gmake`
|
||||
if [ -z $MAKE ]; then
|
||||
MAKE=make
|
||||
fi
|
||||
fi
|
||||
|
||||
# Build.
|
||||
#
|
||||
$MAKE -C libusdt clean all
|
||||
+4
-4
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "dtrace-provider",
|
||||
"version": "0.8.5",
|
||||
"version": "0.8.6",
|
||||
"description": "Native DTrace providers for node.js applications",
|
||||
"keywords": [
|
||||
"dtrace",
|
||||
@@ -23,11 +23,11 @@
|
||||
"nan": "^2.3.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"tap": "^0.2.0"
|
||||
"tap": "0.7.1"
|
||||
},
|
||||
"scripts": {
|
||||
"install": "node scripts/install.js",
|
||||
"test": "tap test/*test.js"
|
||||
"install": "node-gyp rebuild || node suppress-error.js",
|
||||
"test": "tap test/*.test.js"
|
||||
},
|
||||
"main": "./dtrace-provider.js"
|
||||
}
|
||||
|
||||
@@ -1,57 +0,0 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
var movedFile = false;
|
||||
|
||||
if (["linux", "win32"].indexOf(process.platform) !== -1)
|
||||
return;
|
||||
|
||||
var fs = require('fs');
|
||||
var path = require('path');
|
||||
|
||||
var src = path.join(__dirname, '..', 'compile.py');
|
||||
var dst = path.join(__dirname, '..', 'binding.gyp');
|
||||
|
||||
fs.renameSync(src, dst);
|
||||
|
||||
movedFile = true;
|
||||
|
||||
var spawn = require('child_process').spawn;
|
||||
|
||||
var stdio = 'ignore';
|
||||
|
||||
if (process.env.V) {
|
||||
stdio = 'inherit';
|
||||
}
|
||||
|
||||
var options = {
|
||||
cwd: path.join(__dirname, '..'),
|
||||
stdio: stdio
|
||||
};
|
||||
|
||||
var child = spawn('node-gyp', [ 'rebuild' ], options);
|
||||
|
||||
child.on('error', function (err) {
|
||||
if (err.code === 'ENOENT') {
|
||||
console.error('cannot locate node-gyp');
|
||||
} else {
|
||||
console.error(err);
|
||||
}
|
||||
|
||||
process.exit(0);
|
||||
});
|
||||
|
||||
child.on('close', function(code, signal) {
|
||||
if ((code || signal) && process.env.V === undefined) {
|
||||
console.error('---------------');
|
||||
console.error('Building dtrace-provider failed with exit code %d and signal %d',
|
||||
code, signal);
|
||||
console.error('re-run install with environment variable V set to see the build output');
|
||||
console.error('---------------');
|
||||
}
|
||||
process.exit(0);
|
||||
});
|
||||
|
||||
process.on('exit', function() {
|
||||
if (movedFile)
|
||||
fs.renameSync(dst, src);
|
||||
});
|
||||
@@ -0,0 +1,47 @@
|
||||
{
|
||||
'conditions' : [
|
||||
['OS=="mac" or OS=="solaris"', {
|
||||
'variables': {
|
||||
'escaped_root': '<!(printf %q "<(module_root_dir)")',
|
||||
}
|
||||
}],
|
||||
['OS=="freebsd"', {
|
||||
'variables' : {
|
||||
'escaped_root': '<!(printf %s "<(module_root_dir)")'
|
||||
}
|
||||
}]
|
||||
],
|
||||
|
||||
'targets': [
|
||||
{
|
||||
'target_name': 'DTraceProviderBindings',
|
||||
'sources': [
|
||||
'dtrace_provider.cc',
|
||||
'dtrace_probe.cc',
|
||||
'dtrace_argument.cc'
|
||||
],
|
||||
'conditions': [
|
||||
['OS=="mac" or OS=="solaris"',
|
||||
{ 'include_dirs': [
|
||||
'../libusdt',
|
||||
'<!(node -e "require(\'nan\')")',
|
||||
]
|
||||
}
|
||||
],
|
||||
['OS=="freebsd"',
|
||||
{ 'include_dirs': [
|
||||
'/usr/src/cddl/compat/opensolaris/',
|
||||
'/usr/src/sys/cddl/compat/opensolaris',
|
||||
'/usr/src/sys/cddl/contrib/opensolaris/uts/common/',
|
||||
'../libusdt',
|
||||
'<!(node -e "require(\'nan\')")'
|
||||
]
|
||||
}
|
||||
]
|
||||
],
|
||||
'libraries': [
|
||||
'-L<(escaped_root)/../libusdt -l usdt'
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
/**
|
||||
* During `npm install`, we run:
|
||||
*
|
||||
* node-gyp rebuild || node suppress-error.js
|
||||
*
|
||||
* (Note that this expression is written to work on *nix and Windows.)
|
||||
*
|
||||
* When we run node-gyp, we detect whether or not we're on a supported platform,
|
||||
* and either compile the node addon or exit having done nothing. It's possible
|
||||
* for the platform to lack the requirements to run node-gyp though (such as
|
||||
* Python 2, make, Visual C++ Build Tools, and so on), in which case we fall
|
||||
* back onto this script.
|
||||
*
|
||||
* If NODE_DTRACE_PROVIDER_REQUIRE is set to "hard", then we want to propagate
|
||||
* the failure and stop the install. Otherwise, we want to suppress it and
|
||||
* allow the program to fall back onto the stub code.
|
||||
*
|
||||
* There is one case where we might stop an install and not want to: on Debian
|
||||
* and Ubuntu, where the binary is named "nodejs" instead of "node", the
|
||||
* fallback will fail to run. There doesn't really seem to be a great way to
|
||||
* handle this scenario, so users on those systems will need to either install
|
||||
* node-gyp's requirements or set up a "node" symbolic link.
|
||||
*/
|
||||
if (process.env.NODE_DTRACE_PROVIDER_REQUIRE === 'hard') {
|
||||
process.exit(1);
|
||||
} else {
|
||||
process.exit(0);
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
import Options, Utils, sys
|
||||
from os import unlink, symlink, popen
|
||||
from os.path import exists, islink
|
||||
|
||||
srcdir = '.'
|
||||
blddir = 'build'
|
||||
VERSION = '0.2.8'
|
||||
|
||||
libusdtdir = 'libusdt'
|
||||
|
||||
def set_options(ctx):
|
||||
ctx.tool_options('compiler_cxx')
|
||||
|
||||
def configure(ctx):
|
||||
ctx.check_tool('compiler_cxx')
|
||||
ctx.check_tool('node_addon')
|
||||
|
||||
def build(ctx):
|
||||
if sys.platform.startswith("sunos") or sys.platform.startswith("darwin") or sys.platform.startswith("freebsd"):
|
||||
ctx.new_task_gen(
|
||||
rule = "cd ../" + libusdtdir + " && ARCH=i386 make clean all && cd -",
|
||||
shell = True
|
||||
)
|
||||
|
||||
t = ctx.new_task_gen('cxx', 'shlib', 'node_addon')
|
||||
t.target = 'DTraceProviderBindings'
|
||||
t.source = ['dtrace_provider.cc', 'dtrace_probe.cc', 'dtrace_argument.cc']
|
||||
t.includes = [libusdtdir]
|
||||
t.staticlib = 'usdt'
|
||||
t.libpath = "../" + libusdtdir
|
||||
Reference in New Issue
Block a user