1
0
mirror of https://git.FreeBSD.org/ports.git synced 2024-12-23 04:23:08 +00:00

databases/libcouchbase: tentatively attempt to unbreak parallel builds.

The problem was not immediately obvious to me: after eliminating dtrace(1)
output filename clash and forcibly serializing two normally concurrent in
parallel mode linking stages, the problem did not go away.  In fact, while
the port was building seemingly fine in a single-thread (unsafe) mode, the
messages "No probe sites found for declared provider" were still sometimes
present in the log, as well as "target object (...) already exists. Please
remove the target object and rebuild all the source objects if you wish to
run the DTrace".

Running dtrace(1) via truss(1) revealed something odd: it was opening the
substrate object files in read-write mode!  Further tests and studying its
code (/usr/src/cddl/contrib/opensolaris/lib/libdtrace/common/dt_link.c;
see process_obj() and dt_modtext() functions) had confirmed that it is not
idempotent, and under certain circumstances would actually modify object
files passed to it.

Address the problem in the following ways: 1) append PID number to the
output file name to reduce the chances of clash; 2) most importantly, copy
the object files to a temporary location before allowing dtrace(1) to mess
with them.

This is rather ugly and far from robust solution; however, even that the
port does not break in single-thread build mode for some reason, dtrace(1)
rightfully generates errors (ir)regardless.  Ultimately, I'd rather see
dtrace(1) fixed properly instead so this work-around could be dropped.
This commit is contained in:
Alexey Dokuchaev 2017-04-24 08:50:21 +00:00
parent 28621dd53a
commit c69ae5b9d2
Notes: svn2git 2021-03-31 03:12:20 +00:00
svn path=/head/; revision=439270

View File

@ -0,0 +1,51 @@
--- cmake/dtrace-instr-link.pl.orig 2016-08-05 21:38:44 UTC
+++ cmake/dtrace-instr-link.pl
@@ -3,7 +3,7 @@ use strict;
use warnings;
use Digest::MD5 qw(md5_hex);
-my $HDR = "** $0:";
+my $HDR = "** $0 ($$):";
$\="\n";
my $DT_SRC = shift @ARGV;
@@ -16,23 +16,36 @@ if (!scalar @O_FILES) {
exec($CMD,@ARGV);
}
+# Copy .o files to a temporary location before DTrace messes with them
+chomp(my $tmpdir = `mktemp -d -t $$`);
+if (system("tar cf - @O_FILES | tar xf - -C $tmpdir") != 0) {
+ system("rm -rf $tmpdir");
+ exit(1);
+}
+
my $ss = join('_', @O_FILES);
my $hexstr = md5_hex($ss);
-my $INSTRUMENTED = "generated/probes_${hexstr}.o";
+# From now, we work with files in the temporary location, update @ARGV
+map { $_ =~ s,.+\.o$,$tmpdir/$&, } @ARGV;
+
+my $INSTRUMENTED = "generated/probes_${hexstr}_$$.o";
# Run DTrace instrumentation. Assuming running from build directory:
my @args = (
'dtrace', '-C', '-G',
'-s', $DT_SRC,
'-o', $INSTRUMENTED,
- @O_FILES);
+ grep { $_ =~ /\.o$/ } @ARGV);
print "$HDR: Creating instrumented DTrace object: @args";
if (system(@args) != 0) {
+ system("rm -rf $tmpdir");
exit(1);
}
unshift @ARGV, $CMD;
push @ARGV, $INSTRUMENTED;
print "$HDR: Linking with instrumented DTrace object: @ARGV";
-exit(system(@ARGV));
+my $rc = system(@ARGV);
+system("rm -rf $tmpdir");
+exit($rc);