[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: Bug#313094: shared libraries, bug 313094



On Tue, Jun 14, 2005 at 07:28:57PM +1000, Brian May wrote:
> Very recently somebody filled a bug against on of my packages,
> #313094.

> In brief, the library soname changed without me realizing it, and the
> package made in into the sarge release before anyone noticed. This
> means that

> a) (old) packages that linked with the old library won't work with the
> new library.

> b) recent packages that linked with the new library won't work with
> the old library.

> I added to the bug report saying I did not consider it worth fixing,
> because the only breakage occurs if you upload from a version that
> **no longer exists**[1] and was **never distributed in any stable release
> of Debian**.

> However somebody else has upgraded the severity of the bug to serious,
> making it a release critical. The person offered no explanation as to
> why they felt it was serious, or why they disagreed with my
> assessment.

> So what do people think?

> * Is this a bug?

Yes.

> * Does it need fixing?

No.  Rather, it's not fixable; there is no "fix" here that isn't worse than
the current bugginess.  What's done is done, there's no way to take back the
"broken" package name that has already been inflicted on the users of
stable, and all the users of testing/unstable that had upgraded since the
soname changed.

> * Is serious really appropriate?

Not really, though it might have looked that way to Frank at a glance.

> * What is the best way to fix this?

>   - Should I change the name libdar2 to libdar3? Or should I wait
>     until libdar4?

No.  Then you have a libdar3 that Conflicts: with libdar2 and anything
depending on it, and everyone's systems have already been broken if they
were going to break.  What would be the point?

>   - Should I add the (yucky) version dependency as suggested by the
>     bug reporter?

That would be fine, but it's not RC that you do so.

Option #3: future-proof your package so that this never happens again.

I've attached a couple of files that are a snapshot of a more intelligent
solution for library soname/shlibs handling that I'm working on, which I
would like to see widely adopted by library maintainers as early as possible
in the etch cycle.  There are still some unresolved issues, though, and I
haven't gotten a chance to talk to the debhelper maintainer about this at
all yet, so take it with a grain of salt for now. :)

> My personal opinion is that it isn't really a bug, because it only is
> only an issue for people who used the now obsolete version from a
> previous testing/unstable. My understanding is that while Debian
> supports upgrades from stable-->stable, we don't necessarily guarantee
> upgrades from testing will work flawlessly.

We don't *guarantee* it, but it should always be a goal.

-- 
Steve Langasek
postmodern programmer

Attachment: update-manifest.sh
Description: Bourne shell script

--- /usr/bin/dh_makeshlibs	2005-04-22 08:34:24.000000000 -0700
+++ debian/dh_makeshlibs	2005-06-12 01:30:24.000000000 -0700
@@ -114,19 +114,86 @@
 	if (defined($dh{EXCLUDE_FIND}) && $dh{EXCLUDE_FIND} ne '') {
 		$exclude="! \\( $dh{EXCLUDE_FIND} \\) ";
 	}
+	my @manifest;
+	my %shlibsmatch;
+	my $failure;
+	if (-e "debian/$package.manifest") {
+		open (MANIFEST, "debian/$package.manifest");
+		@manifest = <MANIFEST>;
+		close MANIFEST;
+		if ($manifest[0] !~ /^\s+VERSION\s+1$/) {
+			# Wrong version number -- ignore it silently?
+			# throw a warning?
+			undef (@manifest);
+		}
+		my (@shlibslist) = grep(/^\s+SONAME\s+/, @manifest);
+		for (@shlibslist) { s/^\s+SONAME\s+// }
+		foreach my $i (@shlibslist) {
+			my ($name, $version) = split(/\s+/,$i);
+			$shlibsmatch{$name} = [$version, 0];
+		}
+	}
 	open (FIND, "find $tmp -type f \\( -name '*.so' -or -name '*.so.*' \\) $exclude |");
 	while (<FIND>) {
-		my ($library, $major);
+		chomp;
+		my ($library, $major, $soname);
 		my $objdump=`objdump -p $_`;
 		if ($objdump=~m/\s+SONAME\s+(.+)\.so\.(.+)/) {
 			# proper soname format
 			$library=$1;
 			$major=$2;
+			$soname="$1.so.$2";
 		}
 		elsif ($objdump=~m/\s+SONAME\s+(.+)-(.+)\.so/) {
 			# idiotic crap soname format
 			$library=$1;
 			$major=$2;
+			$soname="$1-$2.so";
+		}
+
+		if (@manifest) {
+			$failure = "Error: new library $soname added to package\n"
+			       . "Please update the library manifest"
+			    unless exists($shlibsmatch{$soname});
+ 			$shlibsmatch{$soname}[1] = 1;
+
+			my (@objdump) = `objdump -T $_ | grep '\.text'| cut -b34- | sort`;
+			my $i = 0;
+			# either it finds a match, or it reaches the end
+			# of the file in which case $failure is already set
+			while ($i <= $#manifest
+			       && $manifest[$i] !~ /SONAME\s+$soname\s+/)
+			{
+				$i++;
+			}
+
+			# skip over the soname
+			$i++;
+
+			my $offset = $i;
+			while ($i <= $#manifest && $i - $offset <= $#objdump)
+			{
+				if ($manifest[$i] lt $objdump[$i-$offset])
+				{
+					die "Error: incorrect soname $soname, missing symbol: "
+					    . $manifest[$i];
+				}
+				if ($manifest[$i] gt $objdump[$i-$offset]
+				    || $manifest[$i] =~ /SONAME\s+/)
+				{
+					$failure = "Error: added symbols in $soname: "
+					    . $objdump[$i-$offset]
+					    . "Please update the library manifest";
+					$i--;
+					$offset--;
+				}
+				$i++;
+			}
+			if ($i <= $#manifest && $manifest[$i] !~ /SONAME\s+/)
+			{
+				die "Error: incorrect soname $soname, missing symbol: "
+				    . $manifest[$i];
+			}
 		}
 
 		if (defined($dh{M_PARAMS}) && $dh{M_PARAMS} ne '') {
@@ -155,6 +222,10 @@
 				$deps="$package (>= $version)";
 			}
 		}
+		elsif (%shlibsmatch) {
+			my ($version) = $shlibsmatch{$soname}[0];
+			$deps="$package (>= $version)" if ($version);
+		}
 		if (defined($library) && defined($major) && defined($deps) &&
 		    $library ne '' && $major ne '' && $deps ne '') {
 		    	$need_ldconfig=1;
@@ -167,6 +238,11 @@
 		}
 	}
 	close FIND;
+	foreach my $key (keys %shlibsmatch) {
+		die "Error: library removed from package: $key"
+		    unless ($shlibsmatch{$key}[1]);
+	}
+	die $failure if $failure;
 
 	# New as of dh_v3.
 	if (! compat(2) && ! $dh{NOSCRIPTS} && $need_ldconfig) {

Attachment: signature.asc
Description: Digital signature


Reply to: