tag:blogger.com,1999:blog-42167399246208327152024-03-13T02:18:46.716+01:00To Infinity and BeyondUnknownnoreply@blogger.comBlogger19125tag:blogger.com,1999:blog-4216739924620832715.post-32348360914691921602013-07-18T17:44:00.000+01:002013-07-18T17:47:48.793+01:00A common SQLite pitfallThis is something I've seen happen to several of our customers, and it can be quite difficult to track down if you don't know how.<br />
<br />
<u>Make sure you dispose commands before closing their connections!</u><br />
<br />
The code I've seen typically goes like this:<br />
<br />
<code><span style="color: #3333ff;">protected void</span> ExecuteNonQuery (<span style="color: #3333ff;">string</span> cmd)<br />
{<br />
<span style="color: #3333ff;">using</span> (<span style="color: #3333ff;">var</span> c = connection.CreateCommand ()) {<br />
c.CommandText = cmd;<br />
connection.Open ();<br />
c.ExecuteNonQuery ();<br />
connection.Close ();<br />
}<br />
}</code><br />
<br />
This is broken. Here the connection is closed before the command is disposed. Unfortunately SQLite doesn't tell you anything when this happens, but it will leak file handles (the connection will in fact not be closed), eventually leading to random errors somewhere else when you run out of file handles.<br />
<br />
Random errors are of course not fun, but fortunately this is very easy to debug if you just know how: in Xamarin Studio open the Run->Exceptions menu and add SqliteExceptions to the list of exceptions to break on:<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh6Ehcf9HFE0npMbuPlzFEYyZACpHeoIpjE12CbTFZMrdLhpqmN8Y6-1v2iALtbtF94xKqjXVv-Hr9_YatPdnqDlQxpECEbN12zNScFo_xQUNC3_0cmjdwDuaHxIW6lSRPDHVMihpt49zeh/s1600/foo.png" imageanchor="1"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh6Ehcf9HFE0npMbuPlzFEYyZACpHeoIpjE12CbTFZMrdLhpqmN8Y6-1v2iALtbtF94xKqjXVv-Hr9_YatPdnqDlQxpECEbN12zNScFo_xQUNC3_0cmjdwDuaHxIW6lSRPDHVMihpt49zeh/s1600/foo.png" /></a><br />
<br />
Now run your app. You'll break here if your code is broken:<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgOOxNa46QaaEWv26c8gn2Di0zXfwUjKGZsy0jHOCOmP3EekOgdhDGIdz3E8lduvfgPW7CuAFcdqH7ayj0tPXI56SHmQ-CRPsU-3IFNNtaxP1iy1DNhAggH9bvaBVxuPrdEOBqAgzXV34T6/s1600/foo.png" imageanchor="1"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgOOxNa46QaaEWv26c8gn2Di0zXfwUjKGZsy0jHOCOmP3EekOgdhDGIdz3E8lduvfgPW7CuAFcdqH7ayj0tPXI56SHmQ-CRPsU-3IFNNtaxP1iy1DNhAggH9bvaBVxuPrdEOBqAgzXV34T6/s1600/foo.png" /></a><br />
<br />
and now it's just a matter of walking up the call stack until you find out where the SQLiteConnection.Close is called:<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhCceqoEg_oDWY5CVwixOHLTwYOzhXfUsf8Zy3Cpgk5aXWP4xyKe81nb_2qfqC1ZRGQzN0dqCQ5oKz6jq0XvUDhLz_bTs3Pe2fYE-moFXQF92c_VnRxYtD8h0O7ESUbjVx_jB3NIs7p2wrL/s1600/foo.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhCceqoEg_oDWY5CVwixOHLTwYOzhXfUsf8Zy3Cpgk5aXWP4xyKe81nb_2qfqC1ZRGQzN0dqCQ5oKz6jq0XvUDhLz_bTs3Pe2fYE-moFXQF92c_VnRxYtD8h0O7ESUbjVx_jB3NIs7p2wrL/s1600/foo.png" /></a><br />
<br />
And you should be able to spot the bug and fix it easily:<br />
<br />
<code><span style="color: #3333ff;">protected void</span> ExecuteNonQuery (<span style="color: #3333ff;">string</span> cmd)<br />
{<br />
<span style="color: #3333ff;">using</span> (<span style="color: #3333ff;">var</span> c = connection.CreateCommand ()) {<br />
c.CommandText = cmd;<br />
connection.Open ();<br />
c.ExecuteNonQuery ();<br />
}<br />
connection.Close ();<br />
}</code><br />
<br />
As a final note I'd like to mention that breaking on all exceptions (configure Xamarin Studio to break on System.Exception) can be a valuable debugging tool when weird things are happening - when I first ran into this issue I spent several frustrating hours trying to track it down without success. Out of a hunch I decided to break on all exceptions, and then it took me only a couple of minutes to understand what was going on and fix the code.Unknownnoreply@blogger.com2tag:blogger.com,1999:blog-4216739924620832715.post-14039031379785329412012-09-21T10:47:00.000+01:002012-09-21T10:47:22.915+01:00ValgrindStarting with MonoTouch 5.4 it is possible to use <a href="http://valgrind.org/">Valgrind</a> on a MonoTouch project. In some cases Valgrind is invaluable in finding strange crashes, in particular when freed memory is accessed. <br />
<br />
This is what you need to do:<br />
<br />
Download <a href="http://www.valgrind.org/downloads/current.html#current">latest</a> Valgrind (3.7.0 as of this writing). Extract somewhere, and compile:<br />
<br />
<pre>./configure --enable-only32bit --prefix=/usr/local
make
sudo make install
</pre><br />
Now open the project you want to valgrind, and set the VALGRIND environment variable to the command to execute to use valgrind:<br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjfDbe71NFLLZO17IjtrElQSG0uyYopDjWus6S3WbG2bkCgGpm5X7FGBAvsovCxgGif9WcmyUVY1gX-JUiXyUQnc-huhc0Mv0sJ7FOSbD0VUsjw3F-WObC-pcn6I2B3eRFIC8rGpRE6tuhs/s1600/valgrind-in-md.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjfDbe71NFLLZO17IjtrElQSG0uyYopDjWus6S3WbG2bkCgGpm5X7FGBAvsovCxgGif9WcmyUVY1gX-JUiXyUQnc-huhc0Mv0sJ7FOSbD0VUsjw3F-WObC-pcn6I2B3eRFIC8rGpRE6tuhs/s1600/valgrind-in-md.png" /></a></div><br />
Run (not debug) your project. You will see this in the Application Output:<br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhGZhk-jNElSVHHPIpZzufLFGCfExTUmWpBeDqcwtTvvhuj_gpz0Df380TcD6GDCQ4DYfuKWps3UidZC_6t0qzPwhRERhK_y2GlyBkZr5BMhzofW0w_t6b4HU_6bi8vJdVx6_k2hRlsJ0OA/s1600/valgrind-gdb.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhGZhk-jNElSVHHPIpZzufLFGCfExTUmWpBeDqcwtTvvhuj_gpz0Df380TcD6GDCQ4DYfuKWps3UidZC_6t0qzPwhRERhK_y2GlyBkZr5BMhzofW0w_t6b4HU_6bi8vJdVx6_k2hRlsJ0OA/s1600/valgrind-gdb.png" /></a></div><br />
In particular read the second line, you need to do exactly as it says: use gdb to attach to the app and then detach again. Once you've done this the app should start up (slowly, Valgrind makes your app <b>a lot</b> slower). Quite much output is printed to the Application Output, most of it is just noise though.<br />
<br />
The messages you should be looking for (if you're trying to figure out why your app is crashing), are:<br />
<br />
<ul><li>Invalid read of size X</li>
<li>Invalid write of size X</li>
</ul><br />
You can try to track down the reason for the following messages if you're just trying to find out why the app behaves strangely. Just have in mind that most of these messages are harmless, it can be due to "smart" optimizations in the code or by the compiler which valgrind doesn't understand.<br />
<br />
<ul><li>Conditional jump or move depends on uninitialised value(s)</li>
<li>Use of uninitialised value of size X</li>
</ul><br />
For a thorough explanation of all these messages from Valgrind you should read <a href="http://www.valgrind.org/docs/manual/quick-start.html#quick-start.interpret">their documentation</a>.Unknownnoreply@blogger.com2tag:blogger.com,1999:blog-4216739924620832715.post-13666738702986116332012-08-02T22:10:00.000+01:002012-08-02T22:10:44.156+01:00I can't debug on device!<br />
<h3>
My app won't connect to MonoDevelop when debugging on device, what do I do?</h3>
<br />
<br />
Here are a few tips to track down this particular failure:<br />
<br />
<br />
<ul>
<li> Switch between USB and WiFi mode. Just go to MonoDevelop's Preferences and toggle this check box:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEidnWhwE0QruGSrpRTLrP7iejZpItPg8ZIWfPOXgiCvDsP3HzMvTisFXNjzfU8_wgaWZBLONw7w9pLZBx6mPXoXqToZeKkriYaP6whgkreg2O77FmjNkCTDckbEhboMmEYiopDgXwsYp3F2/s1600/2012-08-02_1505.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEidnWhwE0QruGSrpRTLrP7iejZpItPg8ZIWfPOXgiCvDsP3HzMvTisFXNjzfU8_wgaWZBLONw7w9pLZBx6mPXoXqToZeKkriYaP6whgkreg2O77FmjNkCTDckbEhboMmEYiopDgXwsYp3F2/s1600/2012-08-02_1505.png" /></a></div>
<br />
<br />
</li>
<li> Enable diagnostic output when the app tries to connect to MonoDevelop. This is done by adding "-v -v -v" to the additional mtouch arguments in your project's options:<br />
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhK_bdrenMHz5uziuKa9EneQceXl32decn3GV8XTwEER5HiZ2hsCWi4Iy-7TA5pk1o7f0EJ6fIoaCoDVaWBcDtJ2U7cfSY7jmGm38LHhwg5jZzVrTrcJUNr2UbJDLCP6qGn-tthDu7KTCKr/s1600/2012-08-02_1556.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhK_bdrenMHz5uziuKa9EneQceXl32decn3GV8XTwEER5HiZ2hsCWi4Iy-7TA5pk1o7f0EJ6fIoaCoDVaWBcDtJ2U7cfSY7jmGm38LHhwg5jZzVrTrcJUNr2UbJDLCP6qGn-tthDu7KTCKr/s1600/2012-08-02_1556.png" /></a></div>
<br />
Now rebuild your app, and you should get more information on what's happening in the iOS Device Log:<br />
<br />
<pre style="word-wrap: normal;">MonoTouch: Added IP to look for MonoDevelop: 123.123.123.123
MonoTouch: MonoDevelop Port: 10000 Transport: USB
MonoTouch: Successfully received USB connection from MonoDevelop on port 10000, fd: 5
MonoTouch: Processing: 'connect output'
MonoTouch: Successfully received USB connection from MonoDevelop on port 10000, fd: 6
MonoTouch: Processing: 'start debugger: sdb'
MonoTouch: Debugger loaded with custom transport (fd: 6)
MonoTouch: Successfully received USB connection from MonoDevelop on port 10000, fd: 7
MonoTouch: Processing: 'start profiler: no'
</pre>
<br />
Some of this information should also (but probably won't since that's the problem you're trying to solve in the first place) show up in MonoDevelop's Application Output pad (everything after the 'connect output' line, since that's when the app's standard output is redirected to MonoDevelop):<br />
<br />
<pre style="word-wrap: normal;"><span style="color: #666666;">Please ensure your device is connected...
Connected to: Rolf Bjarne Kvinge’s iPad
Killed the process 'instruments' with pid 1287.
Launching /private/var/mobile/Applications/06007ED7-84C1-4D67-A893-7C04CE477F15/instruments.app -debugtrack -monodevelop-port 10000 -connection-mode usb
</span>
MonoTouch: Successfully received USB connection from MonoDevelop on port 10000, fd: 6
MonoTouch: Processing: 'start debugger: sdb'
MonoTouch: Debugger loaded with custom transport (fd: 6)
MonoTouch: Successfully received USB connection from MonoDevelop on port 10000, fd: 7
MonoTouch: Processing: 'start profiler: no'
<span style="color: #666666;">Loaded assembly: /private/var/mobile/Applications/06007ED7-84C1-4D67-A893-7C04CE477F15/instruments.app/Mono.Security.dll
Loaded assembly: /private/var/mobile/Applications/06007ED7-84C1-4D67-A893-7C04CE477F15/instruments.app/System.dll
Loaded assembly: /private/var/mobile/Applications/06007ED7-84C1-4D67-A893-7C04CE477F15/instruments.app/System.Core.dll
Loaded assembly: /private/var/mobile/Applications/06007ED7-84C1-4D67-A893-7C04CE477F15/instruments.app/monotouch.dll
Loaded assembly: /private/var/mobile/Applications/06007ED7-84C1-4D67-A893-7C04CE477F15/instruments.app/MonoTouch.Dialog-1.dll
Loaded assembly: /private/var/mobile/Applications/06007ED7-84C1-4D67-A893-7C04CE477F15/instruments.app/instruments.exe
Thread started: Finalizer</span>
</pre>
<br />
This time everything connected fine, but if error messages may be printed to the iOS Device Log if anything goes wrong.<br />
<br />
</li>
<li> Restart your device and machine.<br />
</li>
<li> Last solution: <a href="http://bugzilla.xamarin.com/">file a bug</a> or ask on the <a href="http://lists.ximian.com/mailman/listinfo/monotouch">MonoTouch mailing list</a>. Please remember to include the information you got from the previous steps, that's the first thing anybody will ask you anyway.<br />
</li>
</ul>Unknownnoreply@blogger.com1tag:blogger.com,1999:blog-4216739924620832715.post-67413017858316884922012-05-31T13:55:00.001+01:002012-08-03T14:39:55.138+01:00MonoTouch debugging tipsThis is mostly for myself so these ideas aren't lost in bugzilla comments or GMail's bottomless mail pit.<br />
<br />
<h3>How to create a crash report when the app is hung</h3><br />
<i><b>Update</b></i><br />
<br />
There is a much easier way to do this. All iOS versions and devices include a way to force quit an application:<br />
<br />
<br />
<ul><li>Hold down the On/Off button until "slide to power off" appears.</li>
<li>Release the On/Off button.</li>
<li>Hold down the Home button.</li>
<li>After a few seconds the app will be terminated, and a crash report will be generated (the app's exception code will be 0xdeadfa11).</li>
</ul><br />
<br />
<strike>This snippet will cause the app to generate a crash report after 30 seconds (feel free to modify the timeout to ensure it only crashes after you've managed to hang the app).</strike><br />
<strike><br />
</strike><br />
<strike>Once the app has crashed, you should get a crash report in Xcode, hopefully with stack traces giving some clues as to what the app was trying to do when it hung. If you can't make heads and tails of the crash report, you should <a href="http://bugzilla.xamarin.com/">file a bug</a> (remember to attach the crash report!).</strike><br />
<strike><br />
</strike><br />
<strike>Just replace the Application class in Main.cs with this (if you've made modifications to the Main.cs file yourself, you'll have to modify this code accordingly).</strike><br />
<strike><br />
</strike><br />
<pre><strike>public class Application {
[System.Runtime.InteropServices.DllImport ("libc")]
static extern int strlen (IntPtr zero);
static unsafe void Tick ()
{
int zero = 0;
int* z = &zero;
// This is so that strlen is initialized
// (so no/fewer locks are required later)
strlen ((IntPtr) z);
// The sleep interval can be modified to sleep
// until you're sure the app has hung.
System.Threading.Thread.Sleep (30000);
// Create a crash report
strlen (IntPtr.Zero);
}
static void Main (string[] args)
{
new System.Threading.Thread (Tick).Start ();
UIApplication.Main (args, null, "AppDelegate");
}
}</strike>
</pre><br />
<br />
<h3>Next tip will go here next time I remember something I don't want to forget again</h3>Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-4216739924620832715.post-83139590528128190902012-04-14T01:11:00.001+01:002012-04-14T01:11:45.964+01:00Native crashes in MonoTouchIf you use MonoTouch a bit, you will once in a while run into native crashes. In a perfect world you'd never see such a horrible thing, but unfortunately the world isn't perfect, and in real life there are several ways you can end up crashing your app. Usual debugging techniques with MonoDevelop will not work, but with some ingenuity you can figure out what's going on. And you will catch a glimpse of how the world is for those poor guys who can't develop in C#!<br />
<br />
Now, how do you find out what happened? You need as much information as possible, and information related to a native crash is twofold: <br />
<ul><li>Crash report.</li>
<li>Console output.</li>
</ul><br />
Where you can find each differs depends on whether you're running in the iOS simulator or on an iOS device.<br />
<br />
<center><h3><u>You're running in the iOS simulator.</u></h3></center><br />
<br />
In this case, the console is the system console on your Mac. You can find the Console application in Applications -> Utilities -> Console. This is how it looks like:<br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEib-C8-vnedN7TY1649qLHDD5nhpqvqC5zUPWkixbeLxrLV5lvivFrN3Ztsa0zaayxCXtLodKKGeNQLnzFpQCiJQcIyzyg8W21s9TBYd8VlY9Nw-MnRPIXxmEsy6wNl8WVGHsBk2uh1ZSNv/s1600/blog-ConsoleApp.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="451" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEib-C8-vnedN7TY1649qLHDD5nhpqvqC5zUPWkixbeLxrLV5lvivFrN3Ztsa0zaayxCXtLodKKGeNQLnzFpQCiJQcIyzyg8W21s9TBYd8VlY9Nw-MnRPIXxmEsy6wNl8WVGHsBk2uh1ZSNv/s640/blog-ConsoleApp.png" width="640" /></a></div><br />
Now let's see what happens if you crash in the simulator. You will get this dialog:<br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi0jYfHdJM-Z8tW_tdoo6yZqH0YJ_350ZsUEV4yBpIfnMg7RHsqOFad9lmeluq4-rXFlbkx58bHCO3sMCzScf1K3e65gAjtu4EqRxjJ28VZ_FsWZurVmIe4hfb7EWUY3s7sQMlKI_Sphzov/s1600/blog-SimulatorCrashDialog.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi0jYfHdJM-Z8tW_tdoo6yZqH0YJ_350ZsUEV4yBpIfnMg7RHsqOFad9lmeluq4-rXFlbkx58bHCO3sMCzScf1K3e65gAjtu4EqRxjJ28VZ_FsWZurVmIe4hfb7EWUY3s7sQMlKI_Sphzov/s1600/blog-SimulatorCrashDialog.png" /></a></div><br />
and if you click the Report button, you'll see the crash report:<br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiA6ifDJK0O0qgoiTkcB4xwaqCrKpY11CVsJNDSHGEmoaTkup6fdhKiWf6OqLnKH28cxo4iahXi0BJZACqq3-29kKuPvYTGnBawHHnwt8UHvgQ3n9UX53S3ojthyphenhyphenqQ78n28kuBidBdz_GWu/s1600/blog-SimulatorCrashReport.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="444" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiA6ifDJK0O0qgoiTkcB4xwaqCrKpY11CVsJNDSHGEmoaTkup6fdhKiWf6OqLnKH28cxo4iahXi0BJZACqq3-29kKuPvYTGnBawHHnwt8UHvgQ3n9UX53S3ojthyphenhyphenqQ78n28kuBidBdz_GWu/s640/blog-SimulatorCrashReport.png" width="640" /></a></div><br />
The same crash report is also available in the Console, in case you dismissed the dialog:<br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiooDaA99hpg34jx3V4_2mJ8vTkyLlpSQS0pbrScK_Q1lR8wtwapj4NPr4vjysZseN-iwyDH-gqTCiUn6Pe03EK1BVCutpW1yrqF31bPLR-k3OIbaYoCGsJ0hGdCMXBhexGnOS99a4tKQiu/s1600/blog-ConsoleAppWithCrashReport.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="340" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiooDaA99hpg34jx3V4_2mJ8vTkyLlpSQS0pbrScK_Q1lR8wtwapj4NPr4vjysZseN-iwyDH-gqTCiUn6Pe03EK1BVCutpW1yrqF31bPLR-k3OIbaYoCGsJ0hGdCMXBhexGnOS99a4tKQiu/s640/blog-ConsoleAppWithCrashReport.png" width="640" /></a></div><br />
<br />
<br />
<center><h3><u>You're running on an iOS device.</u></h3></center><br />
<br />
In this case, you want Xcode's Organizer. Open Xcode, and go to the Window -> Organizer menu entry.<br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhF_rYLkCX_USMeavyBxjFGc0PsIIqWxad00CmNYNekT_AfWMd4hCVfPyO7tiWamFKJmVkUoFQ_ThM5fFSjBXOcEeQPxlJT8k5wxy_t8gjQONrgGzsVu0Su_m2IoGT13jrjMwuD657GGLo4/s1600/blog-Organizer.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="510" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhF_rYLkCX_USMeavyBxjFGc0PsIIqWxad00CmNYNekT_AfWMd4hCVfPyO7tiWamFKJmVkUoFQ_ThM5fFSjBXOcEeQPxlJT8k5wxy_t8gjQONrgGzsVu0Su_m2IoGT13jrjMwuD657GGLo4/s640/blog-Organizer.png" width="640" /></a></div><br />
Here you will find crash reports under the Device Logs node, and the obviously the console output will be under the Console node.<br />
<br />
<center><h3><u>Now what?</u></h3></center><br />
Some times the information you found tells you exactly what happened.<br />
<br />
This is the case for an unhandled exception, in which case you'll see something like this in the console:<br />
<br />
<pre style="white-space: nowrap;">13/04/12 4:28:54.101 PM CrashReporting: <br/>
Unhandled Exception: System.Exception: Unhandled I am!<br/>
at CrashReporting.AppDelegate.UnhandledException () [0x00000] in /Users/rolf/Projects/CrashReporting/AppDelegate.cs:27 <br/>
at MonoTouch.Dialog.StringElement.Selected (MonoTouch.Dialog.DialogViewController dvc, MonoTouch.UIKit.UITableView tableView, MonoTouch.Foundation.NSIndexPath indexPath) [0x0000b] in /mono/ios/MonoTouch.Dialog/MonoTouch.Dialog/Elements.cs:691 <br/>
at MonoTouch.Dialog.DialogViewController.Selected (MonoTouch.Foundation.NSIndexPath indexPath) [0x00029] in /mono/ios/MonoTouch.Dialog/MonoTouch.Dialog/DialogViewController.cs:518 <br/>
at MonoTouch.Dialog.DialogViewController+Source.RowSelected (MonoTouch.UIKit.UITableView tableView, MonoTouch.Foundation.NSIndexPath indexPath) [0x00019] in /mono/ios/MonoTouch.Dialog/MonoTouch.Dialog/DialogViewController.cs:364 <br/>
at (wrapper managed-to-native) MonoTouch.UIKit.UIApplication:UIApplicationMain (int,string[],intptr,intptr)<br/>
at MonoTouch.UIKit.UIApplication.Main (System.String[] args, System.String principalClassName, System.String delegateClassName) [0x0004c] in /mono/ios/monotouch/src/UIKit/UIApplication.cs:38 <br/>
at CrashReporting.Application.Main (System.String[] args) [0x00000] in /Users/rolf/Projects/CrashReporting/Main.cs:17 <br/>
</pre><br />
in this case it's pretty obvious what happened. But this isn't often the case, usually the information is at best unfamiliar unless you already have experience debugging native crashes (and in some cases the crash happens way after the underlying cause, and any relevant information is long lost. When this happens you'll have to resort to more creative debugging techniques).<br />
<br />
I will write more blog posts describing some of the most common reasons for native crashes later, but in the mean time you have a few options to get help:<br />
<br />
<ul><li><a href="http://lists.ximian.com/mailman/listinfo/monotouch">The monotouch mailing list</a>. There is also a <a href="http://monotouch.2284126.n4.nabble.com/">forum interface</a> to the mailing lists.</li>
<li>File a <a href="http://bugzilla.xamarin.com/">bug</a>.<br />
</li>
<li>Contact <a href="http://support.xamarin.com/">Xamarin support</a>.<br />
</li>
</ul><br />
In all cases be sure to include all information you're able to gather, have in mind that even though the console output and crash reports may be greek to you, it may provide valuable information to somebody else.<br />
<br />
<br />Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-4216739924620832715.post-86530982386599026852010-06-22T23:36:00.000+01:002010-06-22T23:36:34.834+01:00HackweeekA couple of weeks ago we had another hackweek at Novell, and I continued working on getting vbnc to use cecil, as I did <a href="http://rolfkvinge.blogspot.com/2008/08/cecil-reloaded.html">last time</a>. With a big difference: I finished.
</br></br>
Yep, vbnc now uses Cecil to emit assemblies, the System.Reflection.Emit API is not used anymore. This makes it possible to fix a few long standing bugs, but most importantly (to me at least, the bugs are quite corner-case), a lot of unnecessary code has been deleted (~10k fewer lines of code in the compiler).
</br></br>
Another advantage is that it's now trivial to add support for compiling to different runtime versions - vbnc won't ever suffer from multiple personalities like the mono's C# compiler does: mcs/gmcs/smcs/dmcs...
</br></br>
Performance is still somewhat lower (bootstrapping the compiler itself is ~20% slower), but I haven't even looked at why (almost 3 years of working on a branch with fairly big changes has probably introduced some non-optimal code), so this is likely to change. Speed is also helped by using the new <a href="http://evain.net/blog/articles/2010/04/12/mono-cecil-0-9-cecil-light">cecil/light</a> which <a href="http://evain.net/blog/">jbevain</a> released recently.
</br></br>
And since I was done a day early and wanted to have a break from what I've been doing for the last 3 years with vbnc, I implemented the first VB 9 feature: <a href="http://www.panopticoncentral.net/archive/2007/05/08/20433.aspx">ternary ifs</a>!Unknownnoreply@blogger.com2tag:blogger.com,1999:blog-4216739924620832715.post-21798233707630335702009-10-15T13:22:00.007+01:002009-10-15T13:59:35.179+01:00ASX playlistsIf you tried watching <a href="http://rolfkvinge.blogspot.com/2009/10/nasa-tv.html">Nasa TV in my last post</a> with Silverlight, you'd find that it wouldn't work. And once again the problem is with the ASX file - to be more specific, the exact same problem I had to find a quick fix for last week for Moonlight.<br /><br />The <a href="http://www.nasa.gov/55644main_NASATV_Windows.asx">ASX file I linked to</a> links to <a href="http://playlist.yahoo.com/makeplaylist.dll?id=1369080&segment=149773">another ASX file</a>. This second ASX file has a copyright symbol in it (©), and it stores it in the CP1252 code page (i.e. the binary value 0xA9 - this is an illegal value in utf8). Now it seems like Silverlight expects the file to be in utf8 [1], and it errors out if it isn't [2].<br /><br />Unfortunately I can't link to the real mms link, Yahoo seems to uses some sort of authentication ensuring that you got the link from the ASX playlist.<br /><br />I notified Yahoo using their contact form about this, asking them to fix their ASX output, now let's see what happens...<br /><br />[1] When there are no byte-order markers at least<br />[2] Windows Media Player plays the ASX file just fine.Unknownnoreply@blogger.com1tag:blogger.com,1999:blog-4216739924620832715.post-1272008977654806852009-10-09T11:48:00.006+01:002009-10-09T12:06:45.857+01:00Nasa TVInterested by the NASA's crash landing on the moon, I wanted to watch the event live on my Linux machine. NASA has a few live TV channels, but none seemed to work on Linux. Until I discovered that they use ASX files to view the channels in Windows Media Player - turns out Silverlight (and by consequence Moonlight) also support ASX files. It was just a matter of creating a simple silverlight application referencing the ASX links. And that's what I did!<br /><br />The bad thing is that our ASX support was a bit broken [1], and I had to fix it. This means that the currently released beta is not able to view the streams, you need to download brand new xpis from here: <a href="http://moon.sublimeintervention.com/GetFile.aspx?id=17224538">x86</a> / <a href="http://moon.sublimeintervention.com/GetFile.aspx?id=17224360">x64</a> (fair warning: these xpis are not tested at all, download at your own risk). Download, restart firefox and you should be able to watch the event live here.<br /><br /><script type="text/xaml" id="xaml"> <?xml version="1.0"?> <Canvas xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> <MediaElement x:Name="TestVideo1" MediaOpened="OnMediaOpened" MediaFailed="OnMediaFailed" Source="http://www.nasa.gov/55644main_NASATV_Windows.asx" Volume="1.0" Width="640" Height="480" /> </Canvas></script><br /><br /><center><br /><div><embed type="application/x-silverlight" width="640" height="480" id="NasaTV" Source="#xaml" ><br /></embed><br /></div></center><br /><br />(video is scaled 200%, quality is kinda bad, but that's how it's transmitted from NASA)<br /><br />[1] IMHO ASX files are broken by themselves - they look like xml files but aren't (they don't escape special characters that xml files have to), and they're encoded in the current encoding of the machine generating the ASX file, and in order to correctly parse the file you have to know which encoding that is (the file itself doesn't know).Unknownnoreply@blogger.com2tag:blogger.com,1999:blog-4216739924620832715.post-25318639524234886322009-06-10T09:47:00.002+01:002009-06-10T10:05:33.324+01:00Git & makeOne of the most annoying issues with git (which is actually a side-product of the fact that it's very easy to create/administer branches), is that switching branches will cause a lot of recompiles.<br /><br /><a href="http://ccache.samba.org/">ccache</a> helps some, but the real life-saver here is a script which doesn't come bundled with your installed git, but which you'll have to download the source code to get: <a href="http://blog.nuclearsquid.com/writings/git-new-workdir">git-new-workdir</a>. It clones your repository to a different directory, with some symlink magic so that everything is shared except the index. It's the git equivalent a checkout of a svn repository to different directories, except that anything you do in any of the directories is available in all directories.Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-4216739924620832715.post-83542443470368743912009-06-02T11:16:00.004+01:002009-06-02T11:36:31.939+01:00Git & WhitespaceRecently I've been slowly transitioning from svn to git, though one of the mildly annoying differences is that git likes to colorize trailing whitespace in diffs with a very distracting color:<br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgU7R3LxiJuX4iP9y4SxNvkcu7YH0rRWszE0LN7qa-N_RPEIyTlLIO1_o-S-H4LLqNU6TkSmGvqBWaiSl9K6Brpd2rnFR99xJFTIqdR5HK7Ch_UiLO_SE4uvHboL4QxaITZfLtr_ubHJeKD/s1600-h/GitRedDiff.png"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 166px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgU7R3LxiJuX4iP9y4SxNvkcu7YH0rRWszE0LN7qa-N_RPEIyTlLIO1_o-S-H4LLqNU6TkSmGvqBWaiSl9K6Brpd2rnFR99xJFTIqdR5HK7Ch_UiLO_SE4uvHboL4QxaITZfLtr_ubHJeKD/s320/GitRedDiff.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5342675788654518386" /></a><br /><br />First try at fixing it: a tiny script to fix the file before committing.<br /><br />Oops, that introduced a huge number of changes and would mess up history quite a bit, not the way to go.<br /><br />So I added this to my ~/.gitconfig:<br /><br /><pre><br />[core]<br /> whitespace = -trailing-space<br /></pre><br /><br />and now I can see the important changes in the diffs again.Unknownnoreply@blogger.com1tag:blogger.com,1999:blog-4216739924620832715.post-35397577548922252432008-08-29T13:50:00.004+01:002008-08-29T19:06:04.891+01:00Cecil ReloadedFor our hack week here at Novell I continued hacking on making vbnc work with Cecil, and yesterday I reached the point where vbnc is able to compile itself using only Cecil (in my previous post I also said vbnc was able to bootstrap, but back then vbnc was still using SRE to do all the hard work, and Cecil just to write the final assembly to disk).<br /><br />The initial performance problems are mostly gone, it's still not quite as fast as before, but there are also quite a few low-hanging fruit yet in that area. The first successful bootstrap yesterday took 40 seconds (compared to 12 seconds for the normal vbnc), and after a few optimizations I'm now down at 24 seconds. Almost all of that time was gained by allocating less strings, the first non-optimized version allocated ~1.4 GB of strings, and it's now down to 119 MB.<br /><br />I'm also using a delay-loading mechanism to load data from referenced assemblies on-demand, this is not that visible when you compile a lot of code in one go, but it sure make a difference when compiling thousands of 15-20 line tests one by one.<br /><br />I'm pretty confident I can get compilation time down to the 12 seconds I had before, especially given that Cecil hasn't been much optimized [1] (not actually used by compilers) before, while Mono's SRE implementation is known to be quite fast.<br /><br />As a sidenote the actual amount of code in the compiler has decreased, from ~75k lines with the normal vbnc to ~68k for the cecil version.<br /><br />[1] Sébastien Pouliot corrected me, cecil is <a href="http://groups.google.com/group/mono-cecil/web/projects-using-cecil?hl=en">used by some know compilers</a>, and probably some unknown too. Some parts of Cecil has also been optimized already.Unknownnoreply@blogger.com1tag:blogger.com,1999:blog-4216739924620832715.post-53601553432764066712008-01-07T09:39:00.000+01:002008-01-07T10:12:42.725+01:00CecilWhen I started writing vbnc, there weren't many options when it came to deciding which library to use to write the assemblies, only <a href="http://msdn2.microsoft.com/en-us/library/system.reflection.emit.aspx">System.Reflection.Emit</a> (SRE) was a real option.<br /><br />SRE is very powerful, but unfortunately it has a <a href="http://blogs.msdn.com/yirutang/archive/2005/05/19/420134.aspx">few known</a> and <a href="http://rolfkvinge.blogspot.com/2007/04/oh-captain-my-forms.html">unknown</a> <a href="http://blogs.msdn.com/yirutang/archive/2005/07/12/437702.aspx">limitations</a>, mostly because it was never designed to be used by a full-fledged compiler.<br /><br />Since I heard about <a href="http://www.mono-project.com/Cecil">Cecil</a>, I've wanted to switch, and for the last months I've slowly added support for emitting assemblies with Cecil. Yesterday I reached a very important milestone: vbnc is able to bootstrap itself when using Cecil!<br /><br />And I have to say that Cecil is A LOT easier to use than SRE, especially with generics.<br /><br />There are still some problems for switching right away to only using Cecil, one of the biggest being that it's quite slow if you have many referenced assemblies (since Cecil loads everything from an assembly when loading it), though there is work in progress here.<br /><br />Hopefully these issues will be solved shortly, and I can finally remove everything SRE-related, which has caused me quite a few head-aches!Unknownnoreply@blogger.com1tag:blogger.com,1999:blog-4216739924620832715.post-42908488685533976522007-10-06T17:27:00.000+01:002007-10-07T16:47:17.497+01:00VB 10<a href="http://www.panopticoncentral.net/">Paul Vick</a> asks <a href="http://www.panopticoncentral.net/archive/2007/10/05/22298.aspx">what people want for VB 10</a>.<br /><br />Here's my list:<br /><br />1) Inline and multiline comments (why not just copy C's /* */?)<br /><br />2) Option Overflow On/Off<br /><br />3) Option Warning 30XXX On/Off/Error<br /><br />3) The ability to apply Options to methods and/or blocks of code. Something like this maybe:<br /><br /><code><br /><span style="color:#3333ff;">Block Option Strict Off</span>, <span style="color:#3333ff;">Option Overflow On<br /> <span style="color:#009900;">'Some code here</span><br />End Block</span><br /></code><br /><br />I don't particularily like this syntax though, it's somewhat verbose.<br />Another idea might be to add it to the attribute syntax:<br /><br /><code><br /><<span style="color:#3333ff;">Option Strict Off></span> _<br /><span style="color:#3333ff;">Sub</span> A<br /> <<span style="color:#3333ff;">Option Overflow On</span>> _<br /> <span style="color:#3333ff;">Using</span> x<br /> <span style="color:#3333ff;">End Using</span><br /><span style="color:#3333ff;">End Sub></span><br /></code><br /><br />4) <a href="http://www.panopticoncentral.net/archive/2007/10/05/22298.aspx#22302">Select on types,</a> like this:<br /><br /><code><br /><span style="color:#3333ff;">Select TypeOf</span> obj<br /> <span style="color:#3333ff;">Case Integer</span><br /> <span style="color:#3333ff;">Case Double</span><br /><span style="color:#3333ff;">End Select</span><br /></code><br /><br />6) Select on reference equality<br /><br /><code><br /><span style="color:#3333ff;">Select</span> var <span style="color:#3333ff;">Is</span><br /> <span style="color:#3333ff;">Case objA</span><br /> <span style="color:#3333ff;">Case objB</span><br /><span style="color:#3333ff;">End Select</span><br /></code><br /><br />The proposed syntax <a href="http://www.panopticoncentral.net/archive/2007/10/05/22298.aspx#22302">here</a> doesn't work:<br /><br /><code><br /><span style="color:#3333ff;">Select</span> obj <br /> <span style="color:#3333ff;">Case Is</span> varA <br /> <span style="color:#3333ff;">Case Is</span> varB<br /><span style="color:#3333ff;">End Select</span><br /></code><br /><br />since this is already correct VB code. You can actually write this:<br /><br /><code><br /><span style="color:#3333ff;">Select</span> number <br /> <span style="color:#3333ff;">Case Is</span> 1 <br /> <span style="color:#3333ff;">Case Is</span> 2<br /><span style="color:#3333ff;">End Select</span><br /></code><br /><br />where the 'Is' works like a '='. The IDE will remove the 'Is', but it's still allowed. This is bad design IMHO, VB should never have allowed this since it's mixing the meaning of 'Is' and '='.<br /><br />7) Binary numbers<br /><br /><code><br /><span style="color:#3333ff;">Dim</span> i <span style="color:#3333ff;">As Integer</span> = &B0110110<br /></code><br /><br />8) Static method / operator constraints on generic type parameters<br /><br /><code><br /><span style="color:#3333ff;">Class</span> Point (<span style="color:#3333ff;">Of</span> T {+, -})<br /><span style="color:#3333ff;">End Class</span><br /></code><br /><br />Yeah, I know, this is a IL restriction, not a VB restriction, but still...<br /><br />9) Option Warning 4XXXX On/Off/Error<br /><br />10) The possibility to specify that sections of code should not be pretty formatted.<br /><br /><code><br /><span style="color:#3333ff;">#Format None</span><br /><span style="color:#3333ff;">Dim</span> var <span style="color:#3333ff;">As String</span> ()() = <span style="color:#3333ff;">new String</span> () { _<br /> {"a", "bbbbbb"}, _<br /> {"cccccccc", "ddd"}}<br /><span style="color:#3333ff;">#End Format</span><br /></code><br /><br />Once in a while it is nice to be able to format the code just as you want yourself, especially when you can detect bugs due to things not being symmetric or lined up.<br /><br />11) Do NOT allow the user to change pretty formatting (other than disabling it). It's worth it if it avoids the mess in the C world of what's correct formatting or not (how many spaces are there in a tab? 4, 8, 2, 128? where do we put the semi-colon? where do we put spaces?). And mixed formatting in source code is just plain ugly.Unknownnoreply@blogger.com2tag:blogger.com,1999:blog-4216739924620832715.post-55952836514145706742007-08-25T17:03:00.001+01:002007-08-25T17:06:47.156+01:00Killer featureI see the light at the end of the tunnel.<br /><br />Finally, the one single thing that has been <a href="http://my.opera.com/community/forums/topic.dml?id=177943&t=1188057871&page=1#comment1917535">annoying me</a> for a loooong time with Opera, is about to be <a href="http://my.opera.com/community/forums/topic.dml?id=191685&t=1188057699&page=1#comment2134130">fixed</a>. <br /><br />I just hope it's really, really killed now.Unknownnoreply@blogger.com1tag:blogger.com,1999:blog-4216739924620832715.post-80559978652034415612007-04-16T19:34:00.001+01:002011-09-21T08:10:12.294+01:00Oh Captain My FormsToday I finally committed support for one of the last remaining features in vbnc: the My namespace.<br /><br />It was easier than expected, hadn't it been for one little problem I had with a little close friend of mine: Reflection.Emit. I stumbled upon the single worst issue I had during last year's SoC, an issue it took me <a href="http://groups.google.com/group/mono-soc-2006/browse_thread/thread/8dc8ceb21487291e">four days to work around</a>. Note: work around, not fix.<br /><br />At that time I was able to work around it, since it was happening with the compiler, now this wasn't an option anymore, since it was the generated My code that was causing this.<br /><br />The problem is quite simple: anytime you have a generic type parameter on a method with a constraint, some other generic type parameter (on a completely unrelated type, not method) might fail emission (with a nice TypeLoadException, claiming that the constraint isn't met).<br /><br />The workaround I used last year is quite simple: remove all constraints, but as mentioned, that isn't an option anymore, so I started investigating. Unfortunately I lost the test case I cooked up last year, but it didn't take me long to recreate one this time. (Last year I had to start with the entire compiler and comment it out piece by piece...)<br /><br /><span style="font-size:10;"><span style="color:#3333ff;">Namespace</span> OhCaptainIMixedUpTheTypeParameters<br /><span style="color:#3333ff;"> Class</span> C1(<span style="color:#3333ff;">Of</span> Y)<br /><span style="color:#3333ff;"> End Class</span><br /><span style="color:#3333ff;"> Class</span> C2(<span style="color:#3333ff;">Of</span> Z)<br /><span style="color:#3333ff;"> Inherits</span> C1(<span style="color:#3333ff;">Of</span> Z)<br /></span><span style="color:#3333ff;"><span style="font-size:10;"> End Class<br /></span></span><span style="font-size:10;"></span><span style="color:#3333ff;"><span style="font-size:10;"> Class</span></span><span style="font-size:10;"> C3<br /></span><span style="font-size:10;"></span><span style="font-size:10;"></span><span style="font-size:10;"><span style="color:#3333ff;"> Sub</span> M1(<span style="color:#3333ff;">Of</span> A <span style="color:#3333ff;">As New</span>)()<br /></span><span style="font-size:10;"></span><span style="font-size:10;"></span><span style="color:#3333ff;"><span style="font-size:10;"> End Sub<br /></span></span><span style="color:#3333ff;"><span style="font-size:10;"> Sub</span></span><span style="font-size:10;"> M2(<span style="color:#3333ff;">Of</span> B)()<br /></span><span style="font-size:10;"></span><span style="font-size:10;"></span><span style="color:#3333ff;"><span style="font-size:10;"> End Sub<br /></span></span><span style="font-size:10;"></span><span style="color:#3333ff;"><span style="font-size:10;"> End Class<br />End Namespace</span></span><br /><br />Looks quite innocuous, doesn't it?<br /><br />On MS this fails with: TypeLoadException: GenericArguments[0], 'B', on 'TypeParameter1.C1`1[A]' violates the constraint of type parameter 'A'.<br /><br />Now read the exception again and try to relate the A and B to the Z and Y.<br /><br />Of things you can try to make this compile includes changing the order (for example make C3 the first class in the file), or moving the methods to either C1 or C2.<br /><br />With this test case in hand I was quite certain it was a bug in Reflection.Emit, but I wasn't entirely sure either. So I added code to vbnc that dumps out how it emits everything in VB code, and got a nice 90-line source file that when compiled and run nicely reproduces the problem.<br /><br />The conclusion is that it's not a bug in vbnc, which is quite bad (I can't fix it). So everybody that wants to compile any VB code with generic type method parameters, be warned: if the compiler quits with a weird TypeLoadException, you know who to blame.<br /><br />The best part is that it Mono does not suffer from this bug, so if you want your project to compile no matter what, you'll have to use Mono :)<br /><br />PD: Already filed a bug with MS (<a href="https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=270717">link</a>), and they seem to have confirmed it's a bug in Reflection.Emit.<br /><br />Update 01/07/2007: Fixed bug-link.<br />Update 21/09/2011: Fixed html for VB code.Unknownnoreply@blogger.com6tag:blogger.com,1999:blog-4216739924620832715.post-50483590304995576722007-04-16T17:55:00.000+01:002007-04-16T18:22:54.995+01:00Ain't NumericToday I learned something: don't trust a compiler. I repeat: don't ever trust a compiler. It might be doing some magic behind your back.<br /><br />A while ago I was assigned <a href="http://bugzilla.ximian.com/show_bug.cgi?id=80955">a bug</a>, at first it looked really easy, but no matter what I tried I couldn't reproduce it, and I was positive the reporter was experiencing the problem. So I just left the bug standing there, and of course, eventually it hit me.<br /><br />Quiz: If you compile the following source code, what will the IL look like?<br /><code><br />Class AintNumeric<br /> Shared Sub Main<br /> Console.WriteLine(Microsoft.VisualBasic.Information.IsNumeric("0"))<br /> End Sub<br />End Class<br /></code><br />The problem was that this printed "False" on Mono and "True" on MS. I compiled the code with vbnc, ran the code on Mono and it printed "True". I ran it on MS and it printed "True". I disassembled the program to see if the compiler was doing something wrong, and it wasn't. I put Console.WriteLines in MS.VB.Information.IsNumeric and they all confirmed that the function was working like it should. Just to check I compiled the program with vbc, ran it on MS and it printed "True".<br /><br />You might have seen what I missed, but I'll tell you anyway: I didn't run the MS compiled program on Mono. My bad, the reported of the bug explicitly wrote that he did it, but I honestly didn't think it would change anything. vbnc was compiling everything correctly, wasn't it? <br /><br />Well no, and now here is the answer to the quiz:<br /><br /><code>.method public static void Main() cil managed {<br /> .entrypoint<br /> .maxstack 8<br /> L_0000: ldstr "0"<br /> L_0005: call bool [Microsoft.VisualBasic]Microsoft.VisualBasic.CompilerServices.Versioned::IsNumeric(object)<br /> L_000a: call void [mscorlib]System.Console::WriteLine(bool)<br /> L_000f: ret<br />}</code><br /><br />The Microsoft VB8 compiler changes every method call to Microsoft.VisualBasic.Information.IsNumeric to Microsoft.VisualBasic.CompilerServices.Versioned.IsNumeric. And of course, that function was buggy in Mono...<br /><br />Now you may think about it and find this is some really bad behaviour, but it's all because of backwards compatibility. When VB 8 came out they added support for unsigned types, which is the reason behind this: The old version of IsNumeric returns false for unsigned numeric types... and since that couldn't change it because it would break backwards compatibility, and they didn't want to add another function handling the new data types (and telling everybody they had to use the new funcion), they created some compiler magic.<br /><br />And yes, the bug is fixed and vbnc does the same magic now.Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-4216739924620832715.post-58004663103253169662007-03-21T09:56:00.000+01:002007-03-27T11:37:33.883+01:00How?A few people have been asking me how to learn how to write compilers.<br/><br/>After all, when I studied they didn't require me to write a compiler, but they didn't teach much about how to write them either, so how did I do it?<br/><br/>I went to the university library and got the <a href="http://www.amazon.com/gp/redirect.html?ie=UTF8&location=http%3A%2F%2Fwww.amazon.com%2Fgp%2Fproduct%2F0321486811%2F&tag=toinfandbey-20&linkCode=ur2&camp=1789&creative=9325">Dragon Book</a><img src="http://www.assoc-amazon.com/e/ir?t=toinfandbey-20&l=ur2&o=1" width="1" height="1" border="0" alt="" />. But I didn't have time to read it before I had to return it, so I can't say I've actually read it though. Since I was still interested in writing a compiler when I had to return the book I figured I had to get some documentation that could stay with me (and at the time I didn't have the money to buy any book) so I yahooed a bit and found some resources about <a href="http://en.wikipedia.org/wiki/Recursive_descent_parser">recursive descent compilers</a> and printed it out (the original site I used was of course not wikipedia, but it doesn't seem to be available anymore, at least I can't find it - it was some university course in a South African university if I remember correctly).<br/><br/>So, armed with some a little bit of knowledge and much patience I started writing, and here I am today, with a compiler that's actually working on such weird architectures as ppc or s390x. <br/><br/>It sounds easy and for me it wasn't really that hard (the head-aches I got a few times were usually because of the buggy and lacking Reflection.Emit from MS - this could probably have been avoided had <a href="http://evain.net/">Jb Evain</a> written <a href="http://www.mono-project.com/Cecil">Cecil</a> a few years earlier). <br/><br/>However I certainly didn't think I would get this far when I started!Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-4216739924620832715.post-81289325455231475522007-02-22T13:22:00.000+01:002007-02-22T16:40:10.462+01:00Why?<span style="font-size:130%;">Why did I write a compiler?</span><br />When I was studying computer programming at <a href="http://www.ub.edu.ar/">Universidad de Belgrano</a>, one of my fellow students mentioned that "at least they don't require us to write a compiler anymore", making reference to earlier years when the students seemingly were required to write compilers in order to finish their degree.<br />This obviously made me want to write a compiler, not to finish my degree, but to only satisfy my geeky desire to do something nobody else wanted to do.<br /><br /><span style="font-size:130%;">Why did I write a compiler for Visual Basic.Net?</span><br />Visual Basic was the first computer language I learnt (way back at high school in '98 I got my hands on VB4, later on it was upgraded to VB5 and then VB6), and I did actually like it (no comments on this one please :) .<br />Later on I started learning C++ (but I didn't like it since the relation between "tangible results"/"amount of code written" is way lower than for VB - in other words it took me far longer to do the same thing in C++ than in VB), and Delphi (which after about half an hour of trying things out the compiler started throwing internal errors at me, so I figured Delphi wasn't the language for me either).<br />This happened about the same time as the first beta of VS2002 came out (VB7/VB.Net), I had ordered a copy so I was trying it out and learning about the new VB.Net language, and I liked it way better than the previous editions of VB, so the choice wasn't really that hard. Besides, I couldn't find any other VB compiler (non-MS and compatible with MS' version of VB) out there, so it always feels good to create something new :)<br />The original intention was to write a compiler that compiled VB.Net into native code (I did actually get it produce a HelloWorld.exe, it was however mostly hardcoded into the compiler), but when I got to learn more about the managed world I realized that the intelligent thing to do would be to create a compiler that compiled IL to native code and therefore targeting several languages in one hit. The amount of document-reading required to do this (I would have to learn IL, assembler, the PE file format...), made it completely uninteresting, so I rescoped my project into creating a compiler to compile VB.Net into IL, just as vbc.exe does it.<br /><br /><span style="font-size:130%;">Why did I write the compiler in Visual Basic.Net?</span><span style="font-size:+0;"><br /></span>It didn't start out like that, I first tried C++ (yes, even though I didn't like it, but I thought it was a great change to learn it better and maybe make the mentioned result/work relation better). You can actually still see this in the code (check out the comments at the end of <a href="http://svn.myrealbox.com/viewcvs/trunk/mono-basic/vbnc/vbnc/source/Enums/KS.vb?view=markup">this file</a>). The effort didn't last much though, after a couple of days of debugging memory leaks and seeing weird compiler messages all the time I got bored and figured I'd have to change the source language if I was ever going to finish anything at all.<br />Next try was VB6. I'd read everywhere that no sane person would write a compiler in VB6, so I decided to kill that myth. After a couple of hours the myth had survived. The lack of inheritance in VB6 made me crazy, I saw myself either copy-paste huge amounts of code, or write it all in functions, with no OOP whatsoever, neither very pleasant alternatives. Especially now that I was learning the new Visual Basic.Net language. Once again, the choice wasn't really that hard.Unknownnoreply@blogger.com8tag:blogger.com,1999:blog-4216739924620832715.post-80295143052713601272007-02-20T20:54:00.000+01:002007-02-20T21:15:28.361+01:00My NameHi there!<br /><br />I'm the guy behind the new vb compiler for Mono and my name is Rolf Bjarne Kvinge. Yeah, that's right, you're probably not going to be able to pronounce it unless you know some scandinavian language (not even my wife can). And for the record: I have one first name (Rolf), one middle name (Bjarne) and one last name (Kvinge). Especially people from the Spanish-speaking world think I have one first name and two last names (it probably comes from the fact that in Spain everyone gets two last names, one from the father and one from the mother, and if you have only one, it's sort of like you don't know who is your father...).<br /><br />You have no idea how many ways I've seen my name spelled and pronounced (and even though I really think my first name is really easy to spell), though <a href="http://www.desktoplinux.com/news/NS3057967810.html">Raulf Jarve</a> is one of the better ones (you'd think journalists would spend more time on checking these kind of things, but this one obviously didn't - if google returns 2 (two) results for it something should tell you there's something wrong).<br /><br />When I was living in Brazil they pronounced my name something like "Houlfi", in Argentina/Spain it's like "RRRRRRolf", in English it's with the English "R", it's only the French that is able to pronounce my first name more or less the way I do in Norwegian... and here in Spain I normally have to spell even my first name for them to be able to pronounce it (normally it will be either turn out Raul, Ralph, Rodolfo or Rudolf otherwise), but then they normally get it right.<br /><br />Regarding my middle name and my last name I've learnt that it's completely useless to try to teach anyone how to pronounce them, so just call me Rolf, ok?Unknownnoreply@blogger.com8