Showing posts with label monodevelop. Show all posts
Showing posts with label monodevelop. Show all posts

Monday, April 28, 2014

The Future of Debugging in Xamarin Studio

There comes a time in ever man's life when he says to himself, "there has got to be a better way..."

Set Next Statement

Have you ever been stepping through a method or hit a breakpoint and discovered that variables did not have the expected values? Don't you wish you could go back in time and start stepping through that method from an earlier point to see how things went so horribly wrong? Of course you do.

Last week, with the help of Zoltan Varga (who added the necessary runtime support), I implemented support in Xamarin Studio to set the next statement to execute when you resume execution of your program in the debugger. You can set the next statement to be any statement in the current method; any statement at all. This essentially allows you to jump back in time or completely step over execution of statements after the current position.

Don’t worry. As long as you hit Run To Cursor at precisely the moment the lightning strikes the tower, everything will be fine!

Run to Cursor

If you're like me, you've probably found yourself stepping through some code in the debugger and you get to a loop or something that you know is fine and you just don't feel like hitting Step Over the 5 bajillion times necessary to get past it, so what do you do? Hopefully you don't hit Step Over those 5 bajillion times. Hopefully you just set a breakpoint somewhere after that loop and then hit Continue.

The problem with this solution is that it's tedious.

Soon, however, you'll be able to simply right-click and select Run To Cursor (or just set/use a keybinding) and the debugger will resume execution until it reaches your cursor!

Client-Side Evaluation of Simple Properties

Assuming that you haven't disabled "Allow implicit property evaluation and method invocation" in your Xamarin Studio debugger preferences, whenever class properties are evaluated in the debugger (in the Watch pad, the Locals pad, or when you hover the mouse cursor over a property), in order to get the value, the debugger has to spin up a thread in the program being debugged in order to have it evaluate the property (or other expression) because, unlike fields, properties are really just methods that have to run arbitrary code.

For at least a year or so, now, we've mitigated this somewhat by cheating if the property has the CompilerGeneratedAttribute (signifying that it is an auto-property). When evaluating these properties, we would instead do a lookup of the backing field and get its value since we could do that locally without any need to round-trip to the program being debugged. While this helped a lot, there's a lot of properties out there that effectively just return a field and have no other logic (maybe an auto-property wasn't used because the setter does more than just set the field value?).

To improve performance of this, I started looking into what it would take to interpret the IL locally in the IDE. Obviously this could only really work if the property getter was "simple" enough and didn't have to take locks, etc. I started asking Zoltan some questions on the feasibility of this and he wrote a simple IL interpreter (included in Mono.Debugger.Soft) that I ended up using in Xamarin Studio to try and evaluate properties locally before falling back to having the debuggee's runtime spin up a thread to evaluate the property for us.

Great Scott! When Can I Start Using These Awesome Features?

To use these new features, you will need Mono 3.4.1 (or later) and an upcoming release of Xamarin Studio (5.0.1? It won't quite make it into 5.0).

Well, it's time I get back... to the future! ... And implementing more new features!

Tuesday, December 11, 2012

HOWTO: MonoTouch Enterprise Deployment

Okay, so you've gotten the "Engage" hand-gesture from your Captain to deploy your MonoTouch app to the rest of the crew of the Enterprise. Now all you need to know is which buttons to press on your helm...


Step 1.

First, you'll need to make sure that you've created and installed your "In-House" Distribution Certificate via Apple's iOS Provisioning Portal.


Step 2.

Open your Project Options in MonoDevelop and navigate to the iPhone Bundle Signing section.

If you've got MonoDevelop 3.1.0 or later, you'll be able to set your configuration to:


Otherwise you'll simply have to select your Provisioning Profile manually.

Once you've selected your signing certificate and provisioning profile, click the OK button to dismiss the Project Options dialog.


Step 3.

In MonoDevelop, click on the Build menu and select Archive. This will build your project and archive it in a location that Xcode will be able to see it in its Organizer window.


Step 4.

Launch Xcode and then click on the Window menu and select Organizer. At the top of Xcode's Organizer window, you will see an array of icons. Click on the one labeled Archives.

Find your application in the list of archives and select it.


Step 5.

Now click on the Distribute... button in the top-right area of the window and select Save for Enterprise or Ad-Hoc Deployment.

The next screen will prompt you for your code-signing certificate, providing you with a drop-down menu listing your available options.

Clicking Next will cause an action sheet to slide into view, prompting you for the location to save the AppName.ipa package and the AppName.plist file.

Important: Make sure to toggle the Save for Enterprise Distribution checkbox.

Once you've finished filling out all of the fields, click on the Save button.


Step 6.

You'll need to upload the saved AppName.ipa and AppName.plist files to your corporate web server in the location that you specified in the previous step. You'll also need a web page that will link to your app using a hyperlink similar to the one below:

<a href="itms-services://?action=download-manifest&url=http://internal.mycompany.com/Applications/AppName.plist">Install AppName!</a>

That's it! You're done!

Sunday, February 12, 2012

Meet the Hackers

This past week, I've started to get back into photography a bit more (thanks, Nina!) and started taking my camera into the office with me every day to remind myself to take photos. As a result, I've taken a bunch of photographs of my co-workers in the office.

Would you like to meet the hackers?

The Founders

Most of you would probably recognize the infamous Miguel de Icaza, Xamarin's CTO:

Miguel de Icaza

Next up is our very own Steve Jobs, Nat Friedman, our CEO and the man who reminds us to pay attention to the details:

Nat Friedman

Another person many of you will recognize is our very own COO, Joseph Hill:

Joseph Hill

MonoDevelop Team

Well, okay, I've only got a photo of the famous Michael Hutchinson, but he's a very important player in the development of MonoDevelop.

Michael Hutchinson

QA Team

Next up, we have the QA team. They do their best to make sure that we, the developers, didn't break anything. When they aren't testing a specific application before a launch, they hammer away at our products and try to find weak spots in our code (but we still love them anyway!)

This is PJ, and as you can see, he's demonstrating how to QA popcorn corn cobs:

PJ

(Did it pass the test, PJ?)

Next up is Lindsey. She's been working on writing automated tests to make it less likely for releases to include regressions. Let's hope she's successful!

Lindsey

Release Team

Alex Corrado is the man behind the curtain. He's our head Release Team engineer and also the brilliant mastermind that started CXXI, the Mono C++ interop project that we hope to give him time to finish someday soon.

Alex Corrado

Web Team

The newest addition to our ranks (just this week, in fact!), but long-time contributor to the Mono project, is Bojan Rajković. You can see we've already put him to work (he is no doubt puzzling over some ASP.NET code on his screen).

Bojan Rajković

Documentation Team

Nina is the only Cambridge resident on our Docs Team. Specifically, she hacks on our Documentation Portal. She's also the one who has encouraged me to get back into taking photographs, so she'll have to put up with me using her as a guinea pig the most. Here she is taunting me with her hot cup of Chaider:

Nina

Wednesday, August 3, 2011

Debugging Your MonoTouch Apps: The Future

One of the "paper cuts" developers have been having with developing their MonoTouch 4.0.x (and earlier) applications is that for some networking setups, the IP of the developer's workstation detected by MonoDevelop and given to the iPhone or iPad device for debugging purposes is not correct. This often happens if the WiFi is a different network than the network that the developer's machine is connected to (although there are other scenarios as well).

Since it does not seem to be widely known about, allow me to point out that current versions of MonoTouch allow developers to modify the IP that the runtime should connect to for debugging via the iOS Settings app found on any iPhone or iPad (or Simulator). You can see a screenshot of this per-App Settings page in the screenshot to the left. Each of these fields are editable, allowing you to override the defaults filled-in by MonoDevelop.

For our upcoming 4.1 release, Rolf Kvinge and I (but mostly Rolf) have been working on improving this. Rolf has modified the code to check the value of the IP provided in the per-App Settings and if it is set to nil or "automatic", the debugger falls back to checking for a file bundled with the app called MonoTouchDebugConfiguration.txt which can list any number of IP's to try and connect to, each one being on a separate line prefixed with "IP: ". For example:

IP: 10.0.1.31
IP: 192.168.1.31
IP: 204.11.102.79

The runtime will then attempt to connect to each of these IPs asynchronously until it establishes a connection to one of them (at which point it aborts the other waiting connections). This config file solution will hopefully help simplify things for developers a bit by allowing them to pre-configure which IPs to try for their local network configuration w/o having to manually override the iPhone debug settings on the device or simulator.

For Phase 2 of our plan for World Domination, Rolf is hard at work adding support to MonoDevelop and the runtime to allow for USB debugging which will obsolete the above functionality in future versions where the developer has a MonoDevelop which supports USB debugging. For developers stuck on an older MonoDevelop (like 2.4), the solution illustrated above requires no changes to MonoDevelop and so will be available for use.

Tuesday, August 10, 2010

Using Git


Now that Mono has moved to GitHub, a number of contributors (including myself) have been somewhat lost, not knowing how to properly use Git. So today, I'm recommending a book to help all the lost souls out there get comfortable with using Git.

As many long-time programmers probably know, O'Reilly books are top notch. Most probably also would not be surprised that O'Reilly has a book covering Git: Version Control with Git: Powerful Tools and Techniques for Collaborative Software Development.

Don't let the bat scare you.

Saturday, February 23, 2008

Speaking of Hack Week Projects...

I didn't really have any ideas for Hack Week this year, so I had started off working with Paolo and Zoltan on optimizing Mono's RegEx engine. Unfortunately 1 week wasn't enough to accomplish what I had hoped to accomplish - luckily, Paolo and Zoltan were able to improve Mono's RegEx performance significantly without the need for the hacks I had planned to implement (and in fact did some a terrific job, I'm not sure my ideas would have made much of a difference).

That said, I'd like to jot down a few ideas I just had for the next Hack Week:

  • Implement an "Evolution Plugin" project type for MonoDevelop which would setup everything you need to start writing plugins for Evolution in C#. This would include things like templating the E-Plug xml files, pulling in appropriate Evolution# bindings and the like.
  • Implement an Evolution Plugin in C# that would filter spam messages based on charset information. Most of the spam I get seems to use a russian or asian charset, so a filter like this would be extremely valuable to me.

My biggest interest is in templating out an Evolution Plugin project type for MonoDevelop because I'd really like to see more outside developers writing plugins for Evolution and I think that this would be a great way to lower the bar, so to speak.

Saturday, May 12, 2007

Implement Interface

MonoDevelop Refactory work update:

This past week, after getting Renaming working for method parameters, I added context menu items that could implement a target interface's properties, methods, and events implicitly or explicitly auto-magically for the programmer.

You can see screenshots of these menus in an older post of mine, Refactory Operations

Friday, May 4, 2007

MonoDevelop Refactoring

Have you ever wanted to rename a variable in a source file and have all of the references to that variable be renamed as well? I'm sure you have. If you are a typical Linux developer, the only option you've ever had available to you would be to perform a Search & Replace action in your editor (bound to Alt-% in my Emacs editor).

...But this solution is hardly perfect. Search & Replace might match substrings you wouldn't want to replace, so you'd have to examine each substring match manually to accept the change, but this is prone to mistakes. Using a regex Search & Replace might help minimize mistakes in that you might be able to eliminate substring matches that were part of other identifiers, but you'd still have to manually examine each change if you re-used variable names in different scopes or different functions/methods within the same file.

...Which brings us to the next problem: editors historically used by programmers on Linux have never offered to update source files that depend on the current buffer, so programmers would have to manually update the other source files as well.

Welcome... to the Future.

This past week I've been working on a feature allowing MonoDevelop users to rename local variables, classes, interfaces, class members, methods, events, properties, etc and have all the appropriate code in the entire project auto-magically updated, no matter where you invoke the rename action (whether it be in the base class, inner class, some other section of code that uses the class, etc).

Just another example of Mono bringing improvements to Linux developers everywhere.

Friday, April 13, 2007

Refactory Operations

I think I'm finally finished hacking on the Navigation History feature in MonoDevelop, which started off as more-or-less a direct rip-off of the one in SharpDevelop, but quickly began incorporating improvement ideas from Miguel, Lluis, and myself.

Now on to bigger and more exciting things... namely, refactory features.

A few weeks ago I had taken a look at some of Microsoft's Visual Studio 2005's and SharpDevelop's context-menu-based refactoring functions and have just stubbed a few of them out in current MonoDevelop svn (added the Rename and Implement Interface items):

In the above screenshot, you can see the menu we get when right-clicking on the name of an interface in a class definition.

Here, I right-clicked on the name of the class in the class definition.

Going forward, I'll be looking at the refactoring functionality that Eclipse provides along with Intellij's, ReSharper's and Refactor Pro's features.

So far I've really only had time to watch the Refactor Pro demos. They are pretty awesome, but I think the UI bits (at least) are a bit over the top. Certainly not going to be easy to implement. I'll probably be looking at easier approaches.

Saturday, March 10, 2007

Indenting case contents

On Friday, I decided to start implementing some customizable settings for my Smart Indent feature in MonoDevelop. I started off easy by adding the ability to choose how you'd like to indent (or not) your goto labels:



When I had first implemented Smart Indent, I did a lot of mimicking of Emacs because that was my choice in editors. Having programmed in (nay, lived in) Emacs for going on a decade, I did with goto labels what Emacs did (in C), which is to say that I put them in column 2 (one space over from fully left-justified).

However, when I was rewriting my original implementation in C# using Emacs csharp-mode, I decided that when editing C# code, I much preferred the way csharp-mode unindented the goto label by only a single level. At first I was simply going to change the behavior but I had remembered that Visual Studio 2005 had an option for this, so I decided to implement the 3 options it had instead, defaulting, of course, to the same style as csharp-mode.

Today I implemented something a little more useful, a config option for case label indentation. While I was looking at Visual Studio's C# Formatting options, I discovered they had a "Indent case contents" option, so I figured I'd have a go at implementing that as well. After getting it to mostly work, I decided to test how exactly the option was handled in some situations in Visual Studio. Turns out, the option is completely ignored - no matter what the toggle state of the option was, it always indented case contents exactly the same. After discovering this, thinking it was a rather absurd option anyway, I decided to just drop it.

Tuesday, March 6, 2007

MonoDevelop Smart Indent

Since I joined the Mono team about 2 weeks ago, I've been working on a developer suite, MonoDevelop.

Anyways, for the past week or so I've been working on implementing "Smart Indent" for the editor to make my (and, likely, your) life easier when it comes to pumping out code. The less time I have to spending formatting my code, the more code I can write and the less frustrated and distracted I get having to fix the formatting. Net result? A happier programmer and more bang for the buck, which is what .NET is all about in the first place, right? ;)

So tonight, if you update your local MonoDevelop svn repository and build the latest revision, you'll be able to test out my first (of many?) gift to you, Smart Indent. May it put a smile on your face and make your dreams come true.

For those interested in how I did it, read on...

I started out taking a look at the old code. The way it worked was that effectively every time the programmer typed <Return>, it would take a peek at the previous line or two in order to get enough context to make a decision on how much to indent the code. Unfortunately, one or two lines is rarely ever enough context to really tell what is going on, so it was really difficult to get indenting right that way. I needed more context... way more context. Ideally, we'd also be able to readjust indenting on-the-fly as the user typed if he typed something that would change the indent level for that line (think: user types a lone '}' on a line to finish off a block).

To do this The Right Way(tm), I would need to keep a parse tree handy and keep it updated as the user typed, constantly checking state to see if the current line indent level needed to be altered. So that's effectively what I did... I wrote a state machine that kept a rough parse tree handy at all times (see Extras/CSharpBinding/FormattingStrategy/CSharpIndentEngine.cs for the code). It's somewhat crude, but it works (although I'm sure it will need some tweaking here and there). In order to keep the parse tree up-to-date, I hooked it up to the editor's KeyPress() event and that's where I did my tinkering with the indent level as well (after querying the CSharpIndentEngine state).

So there you have it...

Code Snippet Licensing

All code posted to this blog is licensed under the MIT/X11 license unless otherwise stated in the post itself.