baedert / corebird

Native Gtk+ Twitter Client
https://corebird.baedert.org
GNU General Public License v3.0
791 stars 78 forks source link

assertion failed: (amount <= self->tweets->len) #755

Closed EdwardBetts closed 7 years ago

EdwardBetts commented 7 years ago

Backtrace from gdb. Version 1.5.1

#0  0x00007fb441ba6fcf in __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:51
#1  0x00007fb441ba83fa in __GI_abort () at abort.c:89
#2  0x00007fb441f846c5 in g_assertion_message (domain=domain@entry=0x557fe6387ca4 "corebird", file=file@entry=0x557fe6399c22 "CbTweetModel.c", line=line@entry=687, func=func@entry=0x557fe6399ce0 <__func__.27349> "cb_tweet_model_remove_last_n_visible", message=message@entry=0x557fea9a1600 "assertion failed: (amount <= self->tweets->len)")
    at ././glib/gtestutils.c:2433
#3  0x00007fb441f8475a in g_assertion_message_expr (domain=domain@entry=0x557fe6387ca4 "corebird", file=file@entry=0x557fe6399c22 "CbTweetModel.c", line=line@entry=687, func=func@entry=0x557fe6399ce0 <__func__.27349> "cb_tweet_model_remove_last_n_visible", expr=expr@entry=0x557fe6399c7d "amount <= self->tweets->len")
    at ././glib/gtestutils.c:2456
#4  0x0000557fe637a8b6 in cb_tweet_model_remove_last_n_visible (self=self@entry=0x557fea207800 [CbTweetModel], amount=4294967271) at CbTweetModel.c:687
#5  0x0000557fe63155c0 in ___lambda31_ (self=0x557fea2b0390 [HomeTimeline]) at DefaultTimeline.c:930
#6  0x0000557fe63155c0 in ____lambda31__gsource_func (self=0x557fea2b0390, self@entry=<error reading variable: value has been optimized out>) at DefaultTimeline.c:939
#7  0x00007fb441f5e343 in g_timeout_dispatch (source=0x557feadd9750, callback=<optimized out>, user_data=<optimized out>) at ././glib/gmain.c:4715
#8  0x00007fb441f5d8ca in g_main_dispatch (context=0x557fe865ab30) at ././glib/gmain.c:3234
#9  0x00007fb441f5d8ca in g_main_context_dispatch (context=context@entry=0x557fe865ab30) at ././glib/gmain.c:3899
#10 0x00007fb441f5dc80 in g_main_context_iterate (context=context@entry=0x557fe865ab30, block=block@entry=1, dispatch=dispatch@entry=1, self=<optimized out>)
    at ././glib/gmain.c:3972
#11 0x00007fb441f5dd2c in g_main_context_iteration (context=context@entry=0x557fe865ab30, may_block=may_block@entry=1) at ././glib/gmain.c:4033
#12 0x00007fb44251a29d in g_application_run (application=0x557fe8666150 [Corebird], argc=1, argv=0x7ffcb4499008) at ././gio/gapplication.c:2381
#13 0x0000557fe62fe233 in _vala_main (args=<optimized out>, args_length1=<optimized out>) at main.c:49
#14 0x00007fb441b942b1 in __libc_start_main (main=
    0x557fe62fe090 <main>, argc=1, argv=0x7ffcb4499008, init=<optimized out>, fini=<optimized out>, rtld_fini=<optimized out>, stack_end=0x7ffcb4498ff8)
    at ../csu/libc-start.c:291
#15 0x0000557fe62fe0ca in _start ()
Vistaus commented 7 years ago

In what situation do you experience this?

EdwardBetts commented 7 years ago

Running corebird on a Debian laptop with high load average, switching wifi networks.

baedert commented 7 years ago

So the "amount" in

#4  0x0000557fe637a8b6 in cb_tweet_model_remove_last_n_visible (self=self@entry=0x557fea207800 [CbTweetModel], amount=4294967271) at CbTweetModel.c:687

Looks like an underflow with a uint possibly, unless you actually had 4294967271+25 tweets in your timeline.

The code in question checks for that case before though:

    if (tweet_list.model.get_n_items () > DefaultTimeline.REST) {
      tweet_remove_timeout = GLib.Timeout.add (500, () => {
        if (!scrolled_up) {
          tweet_remove_timeout = 0;
          return GLib.Source.REMOVE;
        }

        tweet_list.model.remove_last_n_visible (tweet_list.model.get_n_items () - DefaultTimeline.REST);
        tweet_remove_timeout = 0;
        return GLib.Source.REMOVE;
      });
} 

But only before adding the timeout, so if the system is busy (and the timeout takes a bit longer to get executed than 500ms), there might be a case where we remove something from the model between the if statement before the GLib.Timeout.add call and actually executing the callback. I'm not sure where or why that would happen but we can as well guard against that inside the callback again.