Profanity: Roster assertion failure kills profanity with SIGABRT

Created on 2 May 2019  路  10Comments  路  Source: profanity-im/profanity

Built profanity from commit 722cb5fdc3ced8b76b58992326c8761227240202

Program received signal SIGABRT, Aborted.
__GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:51
51      ../sysdeps/unix/sysv/linux/raise.c: No such file or directory.
(gdb) bt
#0  __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:51
#1  0x00007f65eb48fff0 in __GI_abort () at abort.c:79
#2  0x00007f65eb4864ea in __assert_fail_base (fmt=0x7f65eb5ebf18 "%s%s%s:%u: %s%sAssertion `%s' failed.\n%n", assertion=assertion@entry=0x55e4f9083994 "roster != NULL",     
    file=file@entry=0x55e4f908397d "src/xmpp/roster_list.c", line=line@entry=158, function=function@entry=0x55e4f9083c20 <__PRETTY_FUNCTION__.12916> "roster_get_contact")   
    at assert.c:92
#3  0x00007f65eb48656a in __GI___assert_fail (assertion=assertion@entry=0x55e4f9083994 "roster != NULL", file=file@entry=0x55e4f908397d "src/xmpp/roster_list.c",            
    line=line@entry=158, function=function@entry=0x55e4f9083c20 <__PRETTY_FUNCTION__.12916> "roster_get_contact") at assert.c:101                                            
#4  0x000055e4f8fdd4b5 in roster_get_contact (barejid=<optimized out>) at src/xmpp/roster_list.c:158                                                                         
#5  roster_get_contact (barejid=<optimized out>) at src/xmpp/roster_list.c:156
#6  0x000055e4f8ff9860 in _display_name (tab=<optimized out>, tab=<optimized out>) at src/ui/statusbar.c:523                                                                 
#7  0x000055e4f8ff9ff3 in _tabs_width () at src/ui/statusbar.c:481
#8  status_bar_draw () at src/ui/statusbar.c:265
#9  0x000055e4f8ff658d in ui_update () at src/ui/core.c:140
#10 0x000055e4f8fdaa94 in prof_run (log_level=<optimized out>, account_name=<optimized out>) at src/profanity.c:129                                                          
#11 0x000055e4f8fd71df in main (argc=<optimized out>, argv=<optimized out>) at src/main.c:170                                                                                

This happens randomly with no activity from user by just being connected to several active MUCs.

bug

All 10 comments

Custom theme that I run Profanity with can be found at: https://gist.github.com/ccxcz/100c5fbbadba6ecaba2feb6f1c0f7465

Looks like this is use after free issue. Roster is freed on connection loss and ui_update() tries to read it.

Didnt check the ui_update(). Did some related chagnes however. @ccxcz maybe you can test with latest master (https://github.com/profanity-im/profanity/commit/9ecc14c95dbd90f22e2e9b4f73cd6d1ba1e61d0d) and see if this still happens there. And then give feedback here?

I've tested with c94f3d0b4ad3dbad3f33cbe0d7c19c6cd41e7aea and the problem I get now is that on reconnect the rooms now don't get rejoined properly and if I try to join a room manually I get a crash that seems to indicate it tries to switch to the window without checking it exists:

49      abort.c: No such file or directory.
(gdb) bt  
#0  __GI_abort () at abort.c:49                                     
#1  0x00007fd2ce6064ea in __assert_fail_base (fmt=0x7fd2ce76bf18 "%s%s%s:%u: %s%sAssertion `%s' failed.\n%n", assertion=assertion@entry=0x559d1fe3e67a "window != NULL",
    file=file@entry=0x559d1fe3e5e3 "src/ui/core.c", line=line@entry=647, function=function@entry=0x559d1fe3ebd8 <__PRETTY_FUNCTION__.25017> "ui_focus_win") at assert.c:92
#2  0x00007fd2ce60656a in __GI___assert_fail (assertion=0x559d1fe3e67a "window != NULL", file=0x559d1fe3e5e3 "src/ui/core.c", line=647,
    function=0x559d1fe3ebd8 <__PRETTY_FUNCTION__.25017> "ui_focus_win") at assert.c:101                                                                                      
#3  0x0000559d1fd94518 in ui_focus_win (window=0x0) at src/ui/core.c:647               
#4  0x0000559d1fd94a77 in ui_switch_to_room (roomjid=0x559d54cb6b60 "<redacted>@conference.blesmrt.net") at src/ui/core.c:808
#5  0x0000559d1fdb8468 in cmd_join (window=0x559d216d6640, command=0x559d5417f7e0 "/join", args=0x559d222ef350) at src/command/cmd_funcs.c:3634
#6  0x0000559d1fdc3a2a in _cmd_execute (window=0x559d216d6640, command=0x559d5417f7e0 "/join", inp=0x559d6c790970 "/join <redacted>@conference.blesmrt.net")
    at src/command/cmd_funcs.c:7857
#7  0x0000559d1fdaf0f0 in cmd_process_input (window=0x559d216d6640, inp=0x559d6c790970 "/join <redacted>@conference.blesmrt.net") at src/command/cmd_funcs.c:139
#8  0x0000559d1fd6e2a7 in prof_run (log_level=0x559d1fe5f3d0 "INFO", account_name=0x0) at src/profanity.c:115                                                                
#9  0x0000559d1fdf9d13 in main (argc=1, argv=0x7ffc2dd37268) at src/main.c:170

--

#3  0x0000559d1fd94518 in ui_focus_win (window=0x0) at src/ui/core.c:647
647         assert(window != NULL);
(gdb) i
642     }
643
644     void                              
645     ui_focus_win(ProfWin *window)
646     {                                                                                                                                  
647         assert(window != NULL);
648
649         if (wins_is_current(window)) {                                                                                                 
650             return;
651         }                                                                                                                                                                
#3  0x0000559d1fd94518 in ui_focus_win (window=0x0) at src/ui/core.c:647
647         assert(window != NULL);                                                   
window = 0x0                                                    
__PRETTY_FUNCTION__ = "ui_focus_win"                                                   
old_current = 0x0                                                 
i = 21917                                                                                
identifier = 0x0                                                            

--

#4  0x0000559d1fd94a77 in ui_switch_to_room (roomjid=0x559d54cb6b60 "<redacted>@conference.blesmrt.net") at src/ui/core.c:808                                             
808         ui_focus_win(window);                                             
(gdb) i                                                                                                                                                                      
803                      
804     void
805     ui_switch_to_room(const char *const roomjid)                                                                                                                    
806     {                                                                                                                                                                 
807         ProfWin *window = (ProfWin*)wins_get_muc(roomjid);
808         ui_focus_win(window);
809     }                                                                                                                              
810                                                                                    
811     void       
812     ui_room_destroy(const char *const roomjid)
#4  0x0000559d1fd94a77 in ui_switch_to_room (roomjid=0x559d54cb6b60 "<redacted>@conference.blesmrt.net") at src/ui/core.c:808
808         ui_focus_win(window);  
roomjid = 0x559d54cb6b60 "<redacted>@conference.blesmrt.net"
window = 0x0

--

#5  0x0000559d1fdb8468 in cmd_join (window=0x559d216d6640, command=0x559d5417f7e0 "/join", args=0x559d222ef350) at src/command/cmd_funcs.c:3634
3634            ui_switch_to_room(room);                                                                                                                                     
(gdb) i                                                                                                                                                                      
3629               
3630        if (!muc_active(room)) {                            
3631            presence_join_room(room, nick, passwd);
3632            muc_join(room, nick, passwd, FALSE);
3633        } else if (muc_roster_complete(room)) {
3634            ui_switch_to_room(room);                            
3635        }                                                                                                                                                           
3636                                                                                                                                                                      
3637        jid_destroy(room_arg);                                                                                                     
3638        account_free(account);                                                                                                                                           
#5  0x0000559d1fdb8468 in cmd_join (window=0x559d216d6640, command=0x559d5417f7e0 "/join", args=0x559d222ef350) at src/command/cmd_funcs.c:3634
3634            ui_switch_to_room(room);                                                                                        
window = 0x559d216d6640                                                                                                                        
command = 0x559d5417f7e0 "/join"                                                                                                                               
args = 0x559d222ef350              
conn_status = JABBER_CONNECTED                                                                                                                                     
room_arg = 0x559d222e91f0                                                                                                                                                    
room = 0x559d54cb6b60 "<redacted>@conference.blesmrt.net"                  
nick = 0x559d222ef740 "ccx"                                                                                                                                                  
passwd = 0x0             
account_name = 0x559d21ddf440 "[email protected]"
account = 0x559d6387cf90                                                                                                                                                
opt_keys = {0x559d1fe5246d "nick", 0x559d1fe52452 "password", 0x0}                                                                                                        
parsed = 1                                                    
options = 0x559d5ee80a40         

From usability perspective I find closing the windows on connection drop rather inconvenient, especially if they are to be rejoined after reconnect. It means all the conversations get purged on every network hiccup. Sure, I still get logs (if I enable them), but it definitely worsens usability of running Profanity in the background and then coming back to read the backlog.

To reproduce this bug, change preferences:

/statusbar show name
/statusbar hide number

and cause a connection loss (autoping or broken connection). After the connection loss roster is destroyed, but it is accessed during rewriting UI to calculate width for statusbar.

To solve this we must not take window's name from the roster. Rather save it in the window object.

With https://github.com/profanity-im/profanity/commit/48013f8d4368a81596cff42b5697a6f49a29865e I changed the statusbar setting. Closed my Laptops lid, opened it after a while and got this:
Error from [email protected]/jubalh: You must join the room before sending presence updates
No crash though. But I guess we need to fix this to check if we joined already/rejoin MUCs when we regain connection.

@ccxcz can you please test the new PR?

Some people tested the PR and said it worked. However I'll leave this open for @ccxcz to reply.

The crashes are gone indeed. There is ongoing problem with MUCs not getting reconnected properly, but that's deserving of it's own issue.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

nexustwo picture nexustwo  路  3Comments

boothj5 picture boothj5  路  4Comments

Ubiquitous picture Ubiquitous  路  3Comments

mdosch picture mdosch  路  9Comments

moppman picture moppman  路  3Comments