vivier / qemu-m68k

Other
40 stars 6 forks source link

Regression: Segfaults when running sbuild #20

Closed glaubitz closed 7 years ago

glaubitz commented 7 years ago

This crash occurs in m68k-dev, but not 680x0-master-dev:

Merged Build-Depends: dose-distcheck
Filtered Build-Depends: dose-distcheck
dpkg-deb: building package 'sbuild-build-depends-dose3-dummy' in '/<<BUILDDIR>>/resolver-q0pK4D/apt_archive/sbuild-build-depends-dose3-dummy.deb'.
dpkg-scanpackages: warning: Packages in archive but missing from override file:
dpkg-scanpackages: warning:   sbuild-build-depends-core-dummy sbuild-build-depends-dose3-dummy
dpkg-scanpackages: info: Wrote 2 entries to output Packages file.
qemu: uncaught target signal 11 (Segmentation fault) - core dumped
E: cannot create dummy archiveFailed to run apt-ftparchive.
E: Setting up apt archive failedE: Failed to explain bd-uninstallable

It should be possible to reproduce when following the sbuild setup guide and building any package: https://wiki.debian.org/M68k/sbuildQEMU

glaubitz commented 7 years ago

So, a first indicator is actually this:

Unsupported ioctl: cmd=0x40049409

This normally shows up at the exact same place where the m68k-dev branch crashes.

Could it be possible that the m68k-dev branch implements this ioctl but it's broken?

glaubitz commented 7 years ago

Alright, after digging for some time, I finally was able to track down the culprit.

So, what happens is that sbuild has its own embedded version of the apt-ftparchive command in the form of a Perl script:

use strict;
use warnings;

use IO::Compress::Gzip qw(gzip $GzipError);
use Digest::MD5;
use Digest::SHA;
use POSIX qw(strftime);
use POSIX qw(locale_h);

# Execute a command without /bin/sh but plain execvp while redirecting its
# standard output to a file given as the first argument.
# Using "print $fh `my_command`" has the disadvantage that "my_command" might
# be executed through /bin/sh (depending on the characters used) or that the
# output of "my_command" is very long.
sub system_redir_stdout
{
        my ($filename, @args) = @_;

        open(my $saved_stdout, ">&STDOUT") or die "cannot save stdout: $!";
        open(my $packages, '>', $filename) or die "cannot open Packages for writing: $!";
        open(STDOUT, '>&', $packages) or die "cannot redirect stdout: $!";

        system(@args) == 0 or die "system @args failed: $?";

        open(STDOUT, '>&', $saved_stdout) or die "cannot restore stdout: $!";
        close $saved_stdout;
        close $packages;
}

sub hash_file($$)
{
        my ($filename, $hashobj) = @_;
        open (my $handle, '<', $filename) or die "cannot open $filename for reading: $!";
        my $hash = $hashobj->addfile($handle)->hexdigest;
        close $handle;
        return $hash;
}

system_redir_stdout('Packages', 'dpkg-scanpackages', '.', '/dev/null');
system_redir_stdout('Sources', 'dpkg-scansources', '.', '/dev/null');

gzip 'Packages' => 'Packages.gz' or die "gzip failed: $GzipError\n";
gzip 'Sources' => 'Sources.gz' or die "gzip failed: $GzipError\n";

my $packages_md5 = hash_file('Packages', Digest::MD5->new);
my $sources_md5 = hash_file('Sources', Digest::MD5->new);
my $packagesgz_md5 = hash_file('Packages.gz', Digest::MD5->new);
my $sourcesgz_md5 = hash_file('Sources.gz', Digest::MD5->new);

my $packages_sha1 = hash_file('Packages', Digest::SHA->new(1));
my $sources_sha1 = hash_file('Sources', Digest::SHA->new(1));
my $packagesgz_sha1 = hash_file('Packages.gz', Digest::SHA->new(1));
my $sourcesgz_sha1 = hash_file('Sources.gz', Digest::SHA->new(1));

my $packages_sha256 = hash_file('Packages', Digest::SHA->new(256));
my $sources_sha256 = hash_file('Sources', Digest::SHA->new(256));
my $packagesgz_sha256 = hash_file('Packages.gz', Digest::SHA->new(256));
my $sourcesgz_sha256 = hash_file('Sources.gz', Digest::SHA->new(256));

my $packages_size = -s 'Packages';
my $sources_size = -s 'Sources';
my $packagesgz_size = -s 'Packages.gz';
my $sourcesgz_size = -s 'Sources.gz';

# The timestamp format of release files is documented here:
#   https://wiki.debian.org/RepositoryFormat#Date.2CValid-Until
# It is specified to be the same format as described in Debian Policy §4.4
#   https://www.debian.org/doc/debian-policy/ch-source.html#s-dpkgchangelog
# or the same as in debian/changelog or the Date field in .changes files.
# or the same format as `date -R`
# To adhere to the specified format, the C or C.UTF-8 locale must be used.
my $old_locale = setlocale(LC_TIME);
setlocale(LC_TIME, "C.UTF-8");
my $datestring = strftime "%a, %d %b %Y %H:%M:%S +0000", gmtime();
setlocale(LC_TIME, $old_locale);

open(my $releasefh, '>', 'Release') or die "cannot open Release for writing: $!";

print $releasefh <<"END";
Codename: invalid
Date: $datestring
Description: Sbuild Build Dependency Temporary Archive
Label: sbuild-build-depends-archive
Origin: sbuild-build-depends-archive
Suite: invalid
MD5Sum:
 $packages_md5 $packages_size Packages
 $sources_md5 $sources_size Sources
 $packagesgz_md5 $packagesgz_size Packages.gz
 $sourcesgz_md5 $sourcesgz_size Sources.gz
SHA1:
 $packages_sha1 $packages_size Packages
 $sources_sha1 $sources_size Sources
 $packagesgz_sha1 $packagesgz_size Packages.gz
 $sourcesgz_sha1 $sourcesgz_size Sources.gz
SHA256:
 $packages_sha256 $packages_size Packages
 $sources_sha256 $sources_size Sources
 $packagesgz_sha256 $packagesgz_size Packages.gz
 $sourcesgz_sha256 $sourcesgz_size Sources.gz
END

close $releasefh;

Running this Perl script, causes the crash:

(sid-m68k-sbuild)root@ikarus:~# perl apt-ftp.pl
perl: warning: Setting locale failed.
perl: warning: Please check that your locale settings:
        LANGUAGE = "en_US:en",
        LC_ALL = (unset),
        LANG = "en_US.UTF-8"
    are supported and installed on your system.
perl: warning: Falling back to the standard locale ("C").
perl: warning: Setting locale failed.
perl: warning: Please check that your locale settings:
        LANGUAGE = "en_US:en",
        LC_ALL = (unset),
        LANG = "en_US.UTF-8"
    are supported and installed on your system.
perl: warning: Falling back to the standard locale ("C").
dpkg-scanpackages: info: Wrote 0 entries to output Packages file.
perl: warning: Setting locale failed.
perl: warning: Please check that your locale settings:
        LANGUAGE = "en_US:en",
        LC_ALL = (unset),
        LANG = "en_US.UTF-8"
    are supported and installed on your system.
perl: warning: Falling back to the standard locale ("C").
qemu: uncaught target signal 11 (Segmentation fault) - core dumped
Segmentation fault
(sid-m68k-sbuild)root@ikarus:~#
vivier commented 7 years ago

Simplified to:

gmtime();

Execute:

# LANG=C perl apt-ftp.pl
qemu: uncaught target signal 11 (Segmentation fault) - core dumped
Segmentation fault (core dumped)
glaubitz commented 7 years ago

I just verified that this is fixed by e9f4459f0f23c790b3e5320c6743768f5affcc4d.

glaubitz commented 7 years ago

Shouldn't this actually be implemented for the different CAS2 instructions as well? There still seem to be some rare and random parse errors when building Haskell programs. I will open a new issue once I know more.

vivier commented 7 years ago

No, CAS2 doesn't manage several addressing modes.

vivier commented 7 years ago

To be clear:

this issue is not fixed by commit e9f4459. This is a fix I've added while I was reviewing the code trying to fix this issue.

For this issue, the problem was in the instruction "fmod":

HELPER(mod_FP0_FP1) calls make_quotient(), and make_quotient() was calling floatx80_to_int32() with an uninitialiazed "float_status localstatus". As local status was taken in the stack, its value can be anything, and can trigger the abort() in roundAndPackInt32().

I've merged the fix with the commit adding the fmod instruction.