aqbanking5 and ofxdc can crash gnucash trunk

John Ralls jralls at ceridwen.us
Sat Aug 28 01:23:43 EDT 2010


On Aug 27, 2010, at 6:18 PM, David Reiser wrote:

> 
> On Aug 26, 2010, at 11:30 PM, John Ralls wrote:
> 
>> 
>> On Aug 26, 2010, at 8:08 PM, David Reiser wrote:
>> 
>>> Using gwen r1983, aqbanking r2095, and gnucash r19465, if I
>>> Use gnucash to get transactions via ofxDC
>>> Then go to Tools>Online Banking Setup and launch the the Aqbanking wizard,
>>> gnucash crashes with the console reading:
>>> 
>>> * 12:15:31  WARN <gwenhywfar> inherit.c:  180: Type "5f47140b" not derived from this base type
>>> Assertion failed: (xgui), function AB_Gui_ReadDialogPrefs, file abgui.c, line 246.
>>> Abort trap
>>> 
>>> and the top of the backtrace:
>>> 
>>> Exception Type:  EXC_CRASH (SIGABRT)
>>> Exception Codes: 0x0000000000000000, 0x0000000000000000
>>> Crashed Thread:  0  Dispatch queue: com.apple.main-thread
>>> 
>>> Application Specific Information:
>>> Assertion failed: (xgui), function AB_Gui_ReadDialogPrefs, file abgui.c, line 246.
>>> 
>>> 
>>> Thread 0 Crashed:  Dispatch queue: com.apple.main-thread
>>> 0   libSystem.B.dylib             	0x00007fff872913d6 __kill + 10
>>> 1   libSystem.B.dylib             	0x00007fff87331972 abort + 83
>>> 2   libSystem.B.dylib             	0x00007fff8731e9b4 __pthread_markcancel + 0
>>> 3   libaqbanking.32.dylib         	0x0000000108573cf3 AB_Gui_ReadDialogPrefs + 196
>>> 4   libgwenhywfar.59.dylib        	0x0000000108af17b1 GWEN_Gui_ReadDialogPrefs + 86
>>> 5   libgwenhywfar.59.dylib        	0x0000000108aec7de GWEN_Dialog_new + 395
>>> 6   libaqbanking.32.dylib         	0x0000000108578e0a AB_SetupDialog_new + 46
>>> 7   libgncmod-aqbanking.dylib     	0x00000001080b2c51 dai_wizard_button_clicked_cb + 266 (druid-ab-initial.c:241)
>>> 
>>> On relaunching gnucash, getting into the wizard works, and retrieving transactions works, but if I again try to open the setup wizard after having retrieved transactions, I get the same crash.
>>> 
>>> Martin thinks that it's related to gnucash still using multiple GWEN_GUI objects: 
>>> "Only one of those objects is derived from AB_GUI, and for reasons unknown to me at some times a false GUI object is chosen by Gnucash ...   I recommended multiple times to really, really create the GUI object and init AqBanking once only (!), preferably upon plugin init."
>> 
>> So do a debug build and find out for sure.
>> 
>> Regards,
>> John Ralls
>> 
> Well, I can do the first half of that, but not the second. Can you provide some guidance about what to do once the crash drops me into gdb?

Well, the assert that's causing the trouble is the second one below:
int AB_Gui_ReadDialogPrefs(GWEN_GUI *gui,                                       
                           const char *groupName,                               
                           const char *altName,                                 
                           GWEN_DB_NODE **pDb) {                                
  AB_GUI *xgui;                                                                 
                                                                                
  assert(gui);                                                                  
  xgui=GWEN_INHERIT_GETDATA(GWEN_GUI, AB_GUI, gui);                             
  assert(xgui);                                                                 
                                                                                
  if (groupName && *groupName) {                                                
 
Which means that the macro is producing a null result and Martin has wisely asserted it to prevent a protection crash later.

Debugging macros is often painful, but in this case it's pretty straightforward: It's essentially a C++ template that wraps this function in gwenhywfar/src/base/inherit.c:

void *GWEN_Inherit_FindData(GWEN_INHERITDATA_LIST *l,
                            uint32_t id,
                            int wantCreate){
  GWEN_INHERITDATA *ih;

  assert(l);

  DBG_VERBOUS(GWEN_LOGDOMAIN,
              "Searching for inheritance id \"%08x\"", id);
  ih=GWEN_InheritData_List_First(l);
  while(ih) {
    DBG_VERBOUS(GWEN_LOGDOMAIN,
                "Checking type \"%s\" (%08x) against %08x",
                ih->typeName, ih->id, id);
    if (ih->id==id)
      return ih->data;
    ih=GWEN_InheritData_List_Next(ih);
  } /* while */
  if (!wantCreate) {
    DBG_WARN(GWEN_LOGDOMAIN,
             "Type \"%08x\" not derived from this base type", id);
  }
  return 0;
}

Notice that it's looking through a linked list (which is the first parameter) to find an item with an id that matches the second one. There are two possible reasons that this would fail: Either the list is empty or it has no relevant members. You want to find out which it is and tell Martin and Christian so that they can figure out what went wrong.

So open the wizard in gdb, but don't run it yet. You need to set two breakpoints first:
gdb> b abgui.c:245
***message about the new breakpoint
gdb> b GWEN_Inherit_FindData
***message about the new breakpoint
gdb> dis 2 (This turns off the GWEN_Inherit_FindData breakpoint until you're ready for it)
gdb> r (Run the wizard. Do whatever you did before to make it assert. When it gets to the first breakpoint, it will stop, tell you about the breakpoint it hit, and give you a prompt)
gdb> ena 2 (Turn the GWEN_Inherit_FindData breakpoint back on)
gdb> c (resume execution. It will almost immediately stop in the GWEN_Inherit function with a breakpoint message and a prompt.)

Now is where the interesting work happens. Step through the code (the "n" command executes a line, the "s" command steps into a function call, but there aren't any interesting ones here, so just use n) until you enter the while loop. (If you don't, then the list is empty and you're done for now.) Set a watchpoint on id->id:
gdb> watch id->id
This will display the value of id->id on every iteration. Once you get to the "return 0" statement you can quit gdb (it's OK to kill the running process, it's just going to assert as soon as the function returns anyway), and copy gdb's output from your terminal window to an email for Martin and Christian to digest.

Regards,
John Ralls




More information about the gnucash-devel mailing list