App crashes hard while debugging - help me with tracing the exact cause...

While my app is running in the debugger (have not tried standalone builds yet) it is crashing at seemingly random times with crash logs that look like this:

[code]Exception Type: EXC_CRASH (SIGABRT)
Exception Codes: 0x0000000000000000, 0x0000000000000000

Application Specific Information:
Assertion failed: (!!(srcCharLen > 0)), function sendOut, file /var/lib/buildbot/slave/QuickStableXCode/build/REAL Software Plugins/Xml Plugin/Sablot-1.0.1/src/engine/output.cpp, line 995.

Thread 0:: Dispatch queue: com.apple.main-thread
0 libsystem_kernel.dylib 0x981f9802 __psynch_mutexwait + 10
1 libsystem_pthread.dylib 0x9bb9b945 _pthread_mutex_lock + 404
2 libsystem_pthread.dylib 0x9bb9b7ac pthread_mutex_lock + 16
3 com.xojo.XojoFramework 0x01c83260 0x1b63000 + 1180256
4 com.xojo.XojoFramework 0x01b8a463 0x1b63000 + 160867
5 com.apple.CoreFoundation 0x97ad1f46 CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION + 22
6 com.apple.CoreFoundation 0x97ad1903 __CFRunLoopDoTimer + 1395
7 com.apple.CoreFoundation 0x97b4c06d __CFRunLoopDoTimers + 349
8 com.apple.CoreFoundation 0x97a89483 __CFRunLoopRun + 1779
9 com.apple.CoreFoundation 0x97a88b1a CFRunLoopRunSpecific + 394
10 com.apple.CoreFoundation 0x97a8897b CFRunLoopRunInMode + 123
11 com.apple.HIToolbox 0x940e1b7d RunCurrentEventLoopInMode + 259
12 com.apple.HIToolbox 0x940e1902 ReceiveNextEventCommon + 526
13 com.apple.HIToolbox 0x940e16dd _BlockUntilNextEventMatchingListInModeWithFilter + 92
14 com.apple.AppKit 0x91ef0389 _DPSNextEvent + 1602
15 com.apple.AppKit 0x91eef8b0 -[NSApplication nextEventMatchingMask:untilDate:inMode:dequeue:] + 119
16 com.xojo.XojoFramework 0x01b8a3d1 0x1b63000 + 160721
17 com.xojo.XojoFramework 0x01b8a438 0x1b63000 + 160824
18 com.miridiatech.namechanged 0x00042f9b Delegate.Invoke%% + 34
19 com.miridiatech.namechanged 0x0010ccb0 Application._CallFunctionWithExceptionHandling%%op + 248
20 com.xojo.XojoFramework 0x01c7c450 0x1b63000 + 1152080
21 com.xojo.XojoFramework 0x01b8a360 0x1b63000 + 160608
22 com.apple.AppKit 0x91ee219c -[NSApplication run] + 727
23 com.xojo.XojoFramework 0x01c7c4d7 0x1b63000 + 1152215
24 com.xojo.XojoFramework 0x01c7ab71 RuntimeRun + 49
25 com.miridiatech.namechanged 0x0029f4f3 REALbasic._RuntimeRun + 34
26 com.miridiatech.namechanged 0x00042c7b _Main + 257
27 com.miridiatech.namechanged 0x00002564 % main + 36
28 com.miridiatech.namechanged 0x0166b4d8 _start + 116
29 com.miridiatech.namechanged 0x0166b42e start + 43
[/code]

This sure looks to me like a nasty failed assertion (I’m sure you had a hand in this, @Norman Palardy! ) in the XML plugin in Xojo. The seeming randomness of this I’m pretty sure is because I have a thread doing some XML transaction stuff with a remote server running in the background. The crash happens when the XML processing in the thread pukes.

Are you accessing the same XMLDoc from multiple threads or something like that?

No, a single thread is doing all the XML work.

Can you post the code?

If I knew where in the XML plugin it is dying, I could post a narrow snippet of my code around where that is called… but this thread is handling the synchronization of data between 2 databases, so there is quite a bit of code (7 separate methods in this thread, about a dozen more in a module it uses, plus the run event in the thread itself) in the thread… probably too much to effectively just shotgun here (plus, this is a commercial project, and the code is not particularly… public). Perhaps someone at Xojo ( Hi, @Norman Palardy !) can look up what is going on at line 995 of /var/lib/buildbot/slave/QuickStableXCode/build/REAL Software Plugins/Xml Plugin/Sablot-1.0.1/src/engine/output.cpp and give me a clue about that XML function leads there. That will at least help me narrow down where to look.

Please file a bug report in Feedback with the crash log attached or post the crash log to something like pastebin. Partial crash reports aren’t very helpful.

/me runs the app again to generate full crash log…

Here’s a pastebin of the full crash log:
http://pastebin.com/x0kYX1Lj

I’ll take the blame for a lot of stuff - but not this one :stuck_out_tongue:
Thats way down deep in the bowels of some C++ code which I rarely touch (in all my time here I think I’ve fixed a handful bugs in our C++ code)

Feedback case created. For completeness, here’s the link: (Xojo: Account Login)>]<https://xojo.com/issue/33102>

Ok, after 2 days of bisecting code I believe I’ve found the exact root cause, and I believe it is a good case for why using assertions (especially in production code) is not a great idea for what should have been handled by error checking. In short, the bug I’ve spent 2 days chasing appears to be because the XML parser in Xojo simply barfs with a failed assertion if you send it a string to add to a node that consists of bytes that are not string-like. Instead of failing an assertion, it should gracefully recover in any number of ways (throw an exception with useful info as to the error, put in a blank string, offer some sort of error condition that can be checked to verify operations, etc). Simply barfing at runtime on a failed assertion rather than handle this better has cost me 2 days, and a fix won’t happen for at least several months (assuming it gets high enough priority) to several years (or maybe never.)

Here is the line of code that is causing my entire app to come crashing down:

rowNode.AppendChild(xml.CreateTextNode(rs.field(columnNames(i)).stringValue))

So, what is happening here? I’ve got an XMLDocument called rowNode that I’m stuffing things into. In the case of this line, I’m walking through the results of a select from my database and pulling out the string values of the columns in the table and putting them into the node.

The problem occurs when one of the values in the database is basically binary data rather than a recognizable string. rs.field(“foo”).stringValue still returns a string object, but the bytes of that string look like this:

In other words, it’s not an intelligible string at all, and is in fact the result of some other error long ago in this particular customer database that mucked up this specific row in this table. So I need to add some error checking to find and remove data that may have become corrupted in similar fashion before throwing at the XML parser. But here’s my concern: In what other ways will it just throw a failed assertion? What other failure conditions have been pushed out to me rather than handled in the XML framework? There is no way to know, and I only happened to catch this one because I was testing against a specific database that had this specific corrupted row.

In other news, does anyone know of a good way to check to see if a string that comes out of RecordSet.field(“name”).stringValue is in fact a “valid” string?

Shouldn’t you have a define encoding in that code

rowNode.AppendChild(xml.CreateTextNode(rs.field(columnNames(i)).stringValue))

otherwise the encoding is NIL

Now you can use Encoding.Name.IsValidData
All that WILL tell you is “you could take that data and define this data to be this encoding”
It is NOT a “guess what encoding this data might be” kind of method

That data would be valid in any single byte encoding - whether it’s “correct” is an entirely different question

And I’m still a proponent of “die early, die often, die hard” :stuck_out_tongue:
Much of the code in the XML plugin IS not ours and from an open source project (Sablotron) so the issue could be way down inside that
But I’d bet a sample could be put together now that we know whats causing this

[quote=78953:@Norman Palardy]Shouldn’t you have a define encoding in that code

rowNode.AppendChild(xml.CreateTextNode(rs.field(columnNames(i)).stringValue))

otherwise the encoding is NIL
[/quote]

I thought the default encoding for all strings in Xojo (for several years now) is UTF-8. In the debugger, this string (as returned by the StringValue() method appears to pop out of the database with UTF-8 as the encoding.

I’ll try the isValidData method.

Exactly. That’s why I kept referring to it as “valid”. Bytes are bytes. Strings are only bytes as interpreted in the context of their encoding.

Heya @Norman Palardy - thanks for the tip on isValidData! That is detecting at least this potential pitfall to the XML Parser.

[quote=78955:@Kimball Larsen]I thought the default encoding for all strings in Xojo (for several years now) is UTF-8. In the debugger, this string (as returned by the StringValue() method appears to pop out of the database with UTF-8 as the encoding.
[/quote]
It is but this data is NOT originating from anything IN Xojo or your app
If it comes from a serial tcp database file etc its “foreign” and probably needs a define encoding

I’d double check your data before shoving it into the XML child and see but I’d not be surprised if it has a nil encoding

XML is very finicky about what characters you stick in it. It will definitely barf on binary data in a text node. About the only place you can put binary data is in a CDATA section. Otherwise, XML just loses its mind.

It really is incumbent on the programmer to validate the data before handing it to xml. The kind of code you posted above is very dangerous.

My M_String package has a method that will analyze a string and return the best encoding it can. Another method will strip invalid bytes from a UTF-8 string, if either of those will help you.

You should post an URL to it when you mention it :stuck_out_tongue:

Yeah, I should.

http://www.mactechnologies.com/index.php?page=downloads#m_string

I’d agree that assertions shouldn’t be used for error checking, but having assertions in production code is a good thing, in my opinion. Assertions check that invariants hold true and if the assertion fails, the program is in an unknown state and it’s better to fail early than silently corrupt the XML document.

This appears to be true and an exception definitely should be raised before the information is passed off to the XML engine.