Bug 21167 - gurpmi2 segfaults when installing several packages in a transaction (gtk+3.0 regression)
Summary: gurpmi2 segfaults when installing several packages in a transaction (gtk+3.0 ...
Status: NEW
Alias: None
Product: Mageia
Classification: Unclassified
Component: RPM Packages (show other bugs)
Version: Cauldron
Hardware: All Linux
Priority: High major
Target Milestone: Mageia 6
Assignee: GNOME maintainers
QA Contact:
URL:
Whiteboard:
Keywords: 6final
Depends on:
Blocks:
 
Reported: 2017-07-01 04:38 CEST by ben mcmonagle
Modified: 2017-10-28 20:29 CEST (History)
7 users (show)

See Also:
Source RPM: gtk+3.0, urpmi-8.110-1.mga6
CVE:
Status comment:


Attachments

Description ben mcmonagle 2017-07-01 04:38:15 CEST
Description of problem: after a single DE (Mate) from below .iso, installing an application from Mageia Welcome does not refresh the Mageia Welcome window. this leaves the checkbox "checked" and the "install" button, instead of removing the checkbox and changing "install" to "launch". 

Mageia-6-x86_64-DVD
DATE.txt: Fri Jun 30 23:31:00 CEST 2017


Version-Release number of selected component (if applicable):


How reproducible: 


Steps to Reproduce:
1.install a DE from above .iso
2.reboot to desktop, add online media and add an application from Mageia Welcome.
3.at completion of the installation of the application, Mageia Welcome does not refresh.
ben mcmonagle 2017-07-01 04:38:47 CEST

Keywords: (none) => 6final

Marja van Waes 2017-07-01 06:39:02 CEST

CC: (none) => marja11, napcok
Source RPM: (none) => mageiawelcome
Assignee: bugsquad => mageiatools

Comment 1 Lewis Smith 2017-07-01 21:45:53 CEST
Classic ISO final 30 June.
I noticed something similar on a 6-desktop installation. Puzzled by not being offered install buttons for tainted things, I closed Welcome, enabled Tainted, and restarted Welcome; but still no install buttons offered for them.
Could be a different bug, but clearly related.

CC: (none) => lewyssmith

Comment 2 papoteur 2017-07-02 10:45:45 CEST
I confirm.
The command to get the status of an application is:
rpm -q --quiet <application>
I tested with this small Python script:
import os
name = "firefox"
print(os.WEXITSTATUS(os.system('rpm -q --quiet ' + name)))

In Mageia 5 : 
0

In Mageia cauldron :
sh: /bin/rpm: Permission denied
126

Thus, permission on rpm changed between 5 and 6.
Indeed:
Mageia 5
ls /usr/bin/rpm -lsa
16 -rwxr-xr-x 1 rpm rpm 16208 nov.   3  2016 /usr/bin/rpm*
Mageia Cauldron
 ls /usr/bin/rpm -lsa
16 -rwxr-x--- 1 rpm rpm 16112 mars   1 14:46 /usr/bin/rpm*

I think that the bug should reported to rpm.

 Is this wanted?

CC: (none) => yves.brungard_mageia

Comment 3 papoteur 2017-07-02 11:20:26 CEST
Sorry, this is linked to the security mode in msec.
Secure mode is active in my Cauldron, this explaining the execution rights on rpm.
Comment 4 Lewis Smith 2017-07-10 09:10:17 CEST
Confirmation of the problem as described in Comment 0 with probable M6 release Classic ISO of ~8 July. From MageiaWelcome, Applications, install something via its 'install' button which remains thus after the software is installed; rather than changing to 'launch'.
Worth noting that closing & re-starting MageiaWelcome *does* then show the correct button.
Comment 5 papoteur 2017-07-10 19:25:30 CEST
Tested in a real install, i586, upgraded from mga5.
I get the button "Launch" after the installation of Mypaint.
Comment 6 papoteur 2017-07-10 19:54:48 CEST
Tested in Live XFCE.
I reproduce the problem at the first installation.
I get at the end of installation, in ~/.xsession-errors
/usr/bin/gurpmi2 : ligne 5 :  3336 Erreur de segmentation  (core dumped)/usr/bin/pkexec /usr/libexec/gurpmi2 "$@"
Rémi Verschelde 2017-07-10 21:42:13 CEST

Summary: Mageia Welcome : Applications" does not refresh after installing an application. => Mageia Welcome : Applications" does not refresh after installing an application (gurpmi2 segfault)

Rémi Verschelde 2017-07-10 21:43:16 CEST

Target Milestone: --- => Mageia 6
Priority: Normal => High

Comment 7 Rémi Verschelde 2017-07-10 21:56:48 CEST
Did some more debugging, it's not directly related to mageiawelcome which directly calls `gurpmi $package_name`.

- Running `gurpmi supertux` installs supertux and supertux-data, and triggers a segfault:

unlocking urpmi database
unlocking rpm database
/usr/bin/gurpmi2: line 5: 29710 Segmentation fault  (core dumped)/usr/bin/pkexec /usr/libexec/gurpmi2 "$@"

- Running `gurpmi homebank` installs only homebank, and no problem.

So assuming gurpmi has an issue with multiple-packages transactions, though it could be some other factor.

Summary: Mageia Welcome : Applications" does not refresh after installing an application (gurpmi2 segfault) => gurpmi2 segfaults when installing several packages in a transaction
Source RPM: mageiawelcome => urpmi-8.110-1.mga6

Comment 8 Rémi Verschelde 2017-07-10 21:58:57 CEST
It also segfaults when running `gurpmi2 supertux` as root directly. (`gurpmi supertux` as a user triggers calling `/usr/bin/pkexec /usr/libexec/gurpmi2`).

Priority: High => release_blocker
Severity: normal => critical

Comment 9 Rémi Verschelde 2017-07-10 22:04:08 CEST
It can also be reproduced with `/usr/libexec/gurpmi2` called directly as root btw.

And a simpler transaction to reproduce (supertux-data is big): `/usr/libexec/gurpmi2 berusky` (another 2-package transaction with archful + noarch, but smaller).
Comment 10 Rémi Verschelde 2017-07-10 22:21:38 CEST
Apparently gurpmi is not used in the installer as I thought, so it's not a release blocker per se, though a fix before the next ISOs (i.e. now :D) would be welcome.

Priority: release_blocker => High
Severity: critical => major

Comment 11 Pascal Terjan 2017-07-10 23:43:44 CEST
I guess the main difference is the second window confirming the list of auto selected dependencies

The stacktrace is not very helpful:

#0  0x00007fffe89ef068 in emission_find (instance=0x125146d0, detail=0, signal_id=35) at gsignal.c:824
#3  0x00007fffe89f8822 in <emit signal ??? on instance 0x125146d0 [GtkProgressBar]> (instance=instance@entry=0x125146d0, signal_id=<optimized out>, detail=detail@entry=0) at gsignal.c:3447
    #1  0x00007fffe89ef068 in signal_emit_unlocked_R (node=node@entry=0x28366d0, detail=detail@entry=0, instance=instance@entry=0x125146d0, emission_return=emission_return@entry=0x0, instance_and_params=instance_and_params@entry=0x7fffffffd7b0) at gsignal.c:3519
    #2  0x00007fffe89f844a in g_signal_emit_valist (instance=<optimized out>, signal_id=<optimized out>, detail=<optimized out>, var_args=var_args@entry=0x7fffffffd948) at gsignal.c:3391
#4  0x00007fffe6e930aa in gtk_widget_dispose (object=0x125146d0 [GtkProgressBar]) at gtkwidget.c:12069
#5  0x00007fffe89e29a5 in g_object_unref (_object=0x125146d0) at gobject.c:3148
#6  0x00007fffe8c4292a in XS_Glib__Object_DESTROY (my_perl=<optimized out>, cv=<optimized out>) at GObject.xs:1301
#7  0x00007ffff7ad0c1a in Perl_pp_entersub (my_perl=0x603010) at pp_hot.c:3272
#8  0x00007ffff7a4f7e2 in Perl_call_sv (my_perl=my_perl@entry=0x603010, sv=sv@entry=0x1349298, flags=flags@entry=45) at perl.c:2769
#9  0x00007ffff7ad5651 in S_curse (my_perl=my_perl@entry=0x603010, sv=sv@entry=0x15a7ea0, check_refcnt=check_refcnt@entry=true) at sv.c:6950
#10 0x00007ffff7ad6080 in Perl_sv_clear (my_perl=my_perl@entry=0x603010, orig_sv=orig_sv@entry=0x29f4138) at sv.c:6574
#11 0x00007ffff7ad632d in Perl_sv_free2 (my_perl=0x603010, sv=0x29f4138, rc=<optimized out>) at sv.c:7051
#12 0x00007ffff7ad449b in S_visit (my_perl=my_perl@entry=0x603010, f=f@entry=0x7ffff7ad6550 <do_clean_objs>, flags=flags@entry=2048, mask=mask@entry=2048) at sv.c:506
#13 0x00007ffff7ad66e6 in Perl_sv_clean_objs (my_perl=my_perl@entry=0x603010) at sv.c:657
#14 0x00007ffff7a5233a in perl_destruct (my_perl=0x603010) at perl.c:801
#15 0x0000000000400df1 in main (argc=3, argv=0x7fffffffe0b8, env=0x7fffffffe0d8) at perlmain.c:127

CC: (none) => pterjan

Comment 12 Pascal Terjan 2017-07-10 23:52:48 CEST
I could confirm that with --auto it doesn't crash so this is related to the dialog asking for confirmation of the list of packages to install when there is more than one
Comment 13 Pascal Terjan 2017-07-11 00:33:04 CEST
#0  0x00007fffe89ef068 in emission_find (instance=0x1252d6d0, detail=0, signal_id=35) at gsignal.c:824
        emission = 0x7fff00000002
        accumulator = <optimized out>
        emission = 
          {next = 0x2a185e0, instance = 0x1256d430, ihint = {signal_id = 338673440, detail = 0, run_type = (G_SIGNAL_RUN_FIRST | G_SIGNAL_NO_RECURSE | G_SIGNAL_DETAILED | G_SIGNAL_MUST_COLLECT | unknown: 3902678528)}, state = 32767, chain_type = 140737488344912}
        handler_list = 0x0
        return_accu = <optimized out>
        accu = 
              {g_type = 0, data = {{v_int = 0, v_uint = 0, v_long = 0, v_ulong = 0, v_int64 = 0, v_uint64 = 0, v_float = 0, v_double = 0, v_pointer = 0x0}, {v_int = 0, v_uint = 0, v_long = 0, v_ulong = 0, v_int64 = 0, v_uint64 = 0, v_float = 0, v_double = 0, v_pointer = 0x0}}}
        signal_id = 35
        max_sequential_handler_number = <optimized out>
        return_value_altered = 0

(gdb) print g_emissions
$1 = (Emission *) 0x7fffffffc2f0
(gdb) print g_emissions[0]
$2 = {next = 0x7fffffffc770, instance = 0x1252d180, ihint = {signal_id = 205, detail = 0, run_type = G_SIGNAL_RUN_FIRST}, state = EMISSION_RUN, chain_type = 4}
(gdb) print *(Emission *) 0x7fffffffc770
$16 = {next = 0x7fffffffce80, instance = 0x1252d180, ihint = {signal_id = 204, detail = 0, run_type = G_SIGNAL_RUN_FIRST}, state = EMISSION_RUN, chain_type = 21989200}
(gdb) print *(Emission *) 0x7fffffffce80
$17 = {next = 0x7fffffffd1e0, instance = 0x2aa51e0, ihint = {signal_id = 231, detail = 0, run_type = G_SIGNAL_RUN_FIRST}, state = EMISSION_RUN, chain_type = 22335440}
(gdb) print *(Emission *) 0x7fffffffd1e0
$18 = {next = 0x7fffffffd620, instance = 0x2aa51e0, ihint = {signal_id = 226, detail = 0, run_type = G_SIGNAL_RUN_LAST}, state = EMISSION_RUN, chain_type = 22335440}
(gdb) print *(Emission *) 0x7fffffffd620
$19 = {next = 0x7fff00000002, instance = 0x1252d6d0, ihint = {signal_id = 1, detail = 0, 
    run_type = (G_SIGNAL_DETAILED | G_SIGNAL_ACTION | G_SIGNAL_NO_HOOKS | G_SIGNAL_MUST_COLLECT | G_SIGNAL_DEPRECATED | unknown: 300151808)}, state = EMISSION_STOP, chain_type = 0}
(gdb) print *(Emission *) 0x7fff00000002
Cannot access memory at address 0x7fff00000002
Comment 14 Pascal Terjan 2017-07-11 00:37:06 CEST
(gdb) print (GTypeInstance*) 0x2aa51e0
$20 = 0x2aa51e0 [GtkGestureMultiPress]
(gdb) print (GTypeInstance*) 0x1252d180
$21 = 0x1252d180 [GtkButton]
(gdb) print (GTypeInstance*) 0x1252d6d0
$22 = 0x1252d6d0 [GtkProgressBar]
Comment 15 Pascal Terjan 2017-07-11 01:38:33 CEST
As I suspect the problem is that we run everything inside the signal handler fir the press of the "Continue" button, I rewrote the ask_continue function to use a dialog instead and that got rid of the crash (but the UI is ugly, this wa just a test)

sub ask_continue {
    my ($msg, $nextclosure, $o_list, $o_end_msg) = @_;

    my $d = Gtk3::Dialog->new(N("Confirmation"), $mainw, [], N("_Abort") => 0, N("_Ok") => 1);
    my $label = Gtk3::Label->new($msg);
    $label->set_alignment(0.5, 0.5);
    $d->get_child->pack_start($label, 1, 1, 0);
    if ($o_end_msg) {
        $d->get_child->pack_start(new_label($o_list), 1, 1, 0);
        $d->get_child->pack_start(new_label($o_end_msg), 1, 1, 0);
    }
    my $n = 0;
    $d->signal_connect(response => sub {
        $d->destroy;
        if ($_[1] == 0) {
                &quit();
                exit 1;
        }
    });
    $d->set_default_response(1); # defaults to ok
    $d->show_all;
    $d->run;
    goto &$nextclosure;
}
Comment 16 Thierry Vignaud 2017-07-11 11:56:05 CEST
This is a gtk+3.0 regression.
This has worked smoothly for years

Source RPM: urpmi-8.110-1.mga6 => gtk+3.0, urpmi-8.110-1.mga6
CC: (none) => olav, thierry.vignaud

Thierry Vignaud 2017-07-11 12:00:47 CEST

Assignee: mageiatools => olav
Summary: gurpmi2 segfaults when installing several packages in a transaction => gurpmi2 segfaults when installing several packages in a transaction (gtk+3.0 regression)

Samuel Verschelde 2017-07-11 12:06:47 CEST

Assignee: olav => gnome

Comment 17 Olav Vitters 2017-07-11 14:10:07 CEST
Can we have a minimal testcase to file this upstream?
Comment 18 Pascal Terjan 2017-07-11 19:29:31 CEST
So far this is what I have, in perl:

#!/usr/bin/perl

use Gtk3;

Glib->enable_exceptions3;
Gtk3->init;

my $w = Gtk3::Window->new('toplevel');
$w->{mainbox} = Gtk3::VBox->new(0, 5);
$w->add($w->{mainbox});

my $vbox = Gtk3::VBox->new(0, 5);
my $continue_button = Gtk3::Button->new("Ok");
$continue_button->signal_connect(clicked => sub {
        my $vb = Gtk3::VBox->new(0, 5);
        $vb->pack_start($w->{progresslabel} = Gtk3::Label->new("-"), 1, 1, 0);
        $w->remove($w->{mainbox});
        $w->add($w->{mainbox} = $vb);
        my $vb2 = Gtk3::VBox->new(0, 5);
        $w->remove($w->{mainbox});
        $w->add($w->{mainbox} = $vb2);
        exit 0;
});
my $hbox = Gtk3::HButtonBox->new;
$vbox->pack_start($hbox, 0, 0, 0);
$hbox->add($continue_button);
$w->remove($w->{mainbox});
$w->add($w->{mainbox} = $vbox);

$w->show_all;
Gtk3->main;

END {
        system("echo Crash?");
}
Comment 19 Pascal Terjan 2017-07-11 19:32:08 CEST
Actually, slightly shorter:

#!/usr/bin/perl

use Gtk3;
Gtk3->init;

my $w = Gtk3::Window->new('toplevel');
my $vbox = Gtk3::VBox->new(0, 5);
my $continue_button = Gtk3::Button->new("Ok");
$continue_button->signal_connect(clicked => sub {
        my $vb = Gtk3::VBox->new(0, 5);
        $vb->pack_start($w->{progresslabel} = Gtk3::Label->new("-"), 1, 1, 0);
        $w->remove($w->{mainbox});
        $w->add($w->{mainbox} = $vb);
        my $vb2 = Gtk3::VBox->new(0, 5);
        $w->remove($w->{mainbox});
        $w->add($w->{mainbox} = $vb2);
        exit 0;
});
my $hbox = Gtk3::HButtonBox->new;
$vbox->pack_start($hbox, 0, 0, 0);
$hbox->add($continue_button);
$w->add($w->{mainbox} = $vbox);
$w->show_all;
Gtk3->main;

END {
        system("echo Crash?");
}
Comment 20 Pascal Terjan 2017-07-11 19:57:08 CEST
Even shorter:

#!/usr/bin/perl

use Gtk3;
Gtk3->init;

my $w = Gtk3::Window->new('toplevel');
my $continue_button = Gtk3::Button->new("Ok");
$continue_button->signal_connect(clicked => sub {
        $w->{progresslabel} = Gtk3::Label->new("-");
        $w->remove($w->{mainbox});
        $w->add($w->{mainbox} = $w->{progresslabel});
        my $vb = Gtk3::VBox->new(0, 5);
        $w->remove($w->{mainbox});
        $w->add($w->{mainbox} = $vb);
        exit 0;
});
$w->add($w->{mainbox} = $continue_button);
$w->show_all;
Gtk3->main;

END {
        system("echo Crash?");
}
Comment 21 Pascal Terjan 2017-07-11 20:00:41 CEST
OK the shortest I could get to is this:

#!/usr/bin/perl

use Gtk3;
Gtk3->init;

my $w = Gtk3::Window->new('toplevel');
my $continue_button = Gtk3::Button->new("Ok");
$continue_button->signal_connect(clicked => sub {
        $w->{progresslabel} = Gtk3::Label->new("-");
        exit 0;
});
$w->add($continue_button);
$w->show_all;
Gtk3->main;

END {
        system("echo Crash?");
}
Comment 22 Pascal Terjan 2017-07-11 20:35:56 CEST
A similar C program does not crash, but that's not surprising given that the crash happens in the cleanup code and C doesn't destroy objects magically.

#include <gtk/gtk.h>
#include <stdlib.h>
#include <unistd.h>

void crash(void) {
  system("echo Crash?");
}

GtkWidget *window;
GtkWidget *button;
GtkWidget *label;

void foo(void) {
  label = gtk_label_new("-");
  exit(0);
}

int
main(int argc, char *argv[]) {
  gtk_init (&argc, &argv);

  window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
  button = gtk_button_new_with_label("Ok");

  g_signal_connect(G_OBJECT (button), "clicked",
                     G_CALLBACK (foo), NULL);
  gtk_container_add(GTK_CONTAINER (window), button);
  gtk_widget_show(button);
  gtk_widget_show(window);
  atexit(crash);
  gtk_main();

  return 0;
}
Comment 23 Pascal Terjan 2017-07-11 21:10:04 CEST
Note that the type does not matter, using a Button instead of the Label is the same. Also not creating the object inside that block.

This crashes:
===========
use Gtk3;
Gtk3->init;

my $w = Gtk3::Window->new('toplevel');
$::foo = Gtk3::Label->new("foo");
my $continue_button = Gtk3::Button->new("Ok");
$continue_button->signal_connect(clicked => sub {
        exit 0;
});
$w->add($continue_button);
$w->show_all;
Gtk3->main;

END {
        system("echo Crash?");
}
===========

This does not:
===========
use Gtk3;
Gtk3->init;

my $w = Gtk3::Window->new('toplevel');
$::foo = Gtk3::Label->new("foo");
my $continue_button = Gtk3::Button->new("Ok");
$continue_button->signal_connect(clicked => sub {
        exit 0;
});
$w->add($continue_button);
$w->show_all;
Gtk3->main;

END {
        system("echo Crash?");
}
===========
Lewis Smith 2017-07-11 21:24:06 CEST

CC: lewyssmith => (none)

Comment 24 Pascal Terjan 2017-07-11 22:25:58 CEST
Oops, this does not:
===========
use Gtk3;
Gtk3->init;

my $w = Gtk3::Window->new('toplevel');
my $foo = Gtk3::Label->new("foo");
my $continue_button = Gtk3::Button->new("Ok");
$continue_button->signal_connect(clicked => sub {
        exit 0;
});
$w->add($continue_button);
$w->show_all;
Gtk3->main;

END {
        system("echo Crash?");
}
===========
Comment 25 Pascal Terjan 2017-07-11 22:32:43 CEST
OK, this gave me a workaround which seems to avoid that crash :)

diff --git a/gurpmi2 b/gurpmi2
index 50726071..f450b578 100755
--- a/gurpmi2
+++ b/gurpmi2
@@ -373,6 +373,7 @@ return_with_exit_code:
     # Show postponed message before exiting
     $urpm->{error}->($urpm::postponed_msg) if $urpm::postponed_code != 0;
 
+    undef $mainw;
     exit $exit_code;
 }
Comment 26 Mageia Robot 2017-07-11 22:44:46 CEST
commit 5e65bc97384f4b48bb01f4f5d81c1b698756e520
Author: Pascal Terjan <pterjan@...>
Date:   Tue Jul 11 21:42:27 2017 +0100

    Workaround a segfault in gurpmi (mga#21167)
---
 Commit Link:
   http://gitweb.mageia.org/software/rpm/urpmi/commit/?id=5e65bc97384f4b48bb01f4f5d81c1b698756e520
Comment 27 Nicolas Lécureuil 2017-10-28 20:29:50 CEST
can we close this bugreport ?

CC: (none) => mageia


Note You need to log in before you can comment on or make changes to this bug.