Monday, February 24, 2014

My Android SDK and ADT Upgrade Experience

My last experiments with Android development was when I bought my first Android smart phone. Don't confuse by the word first smart phone, still I am using the same Galaxy Y. The truth is that after those days, I didn't get much time to play around due to various reasons such as busy with other technology stuff such as Big Data, Hadoop and project releases in Office. But recently I got a chance to do some research activities in Android phone. So started Eclipse again.

The research requires reading the calendar to get meeting details. The initial code base was set-up by one of my colleague and I am supposed to start from a zip file which he sent to me.He actually got the Zip from another one who left the company. The first challenge was how to check in the code into a repository. As our company mainly focus on the Microsoft technologies, we are using TFS. So downloaded and installed the TFS plugin for Eclipse. Things worked straight there. Then thought of compiling the project and here begins the story of upgrading Android development environment.


Since the calendar contact APIs are introduced in API Level 14, I had to have an environment which supports API Level 14. Mine was API Level 10 which is enough for developing apps for my Galaxy Y which uses 2.3.3 GingerBread. Things seemed straight as its the matter of upgrading the API levels. Opened the Android SDK manager but I was not able to find the API Level 14 to install. The installation starts from here.

Installing ADT

As all the developers know ADT is the Eclipse plug in for Android development. It provides the development support. My current ADT version doesn't support the API Level 14. So I started to install ADT 22.3.0. The first error started from here.The error was as follows

"A folder failed to be renamed or moved. On Windows this typically means that a program Is using that Folder (for example Windows Explorer or your anti-virus software.) Please momentarily deactivate your anti-virus software. Please also close any running programs that may be accessing the directory '..\android-sdk-dir\android-sdk_r12-windows\android-sdk-windows\tools'. When ready, press YES to try again."

If we look at the logs we can easily understand that the installer is trying to rename the tools folder to temp\ToolPackage.old01.Below is the log.

"Failed to rename directory ..\android-sdk-windows\tools to ..\android-sdk-windows\temp\ToolPackage.old01.

Done. Nothing was installed."

The google gave a bunch of ideas such as disabling antivirus which I never can do in my company machine, giving permissions,  renaming or moving some folders, killing some particular processes etc...Somebody even went to the extend of editing the install file. I did almost all the things except editing the install file. Since these methods are not helping, decided to setup the ADT from beginning.

It was smooth. I downloaded the SDK and extracted to new folder.Then changed the SDK path in the Eclipse and was able to install ADT and required API Levels. But when I run the application it got ended by the below message in the console window.

Upgrading All Android development supporting tools.

"Connection with adb was interrupted. 0 attempts have been made to reconnect. You may want to manually restart adb from the Devices view."

This tells more like a restart request. I tried restarting the simulator and Eclipse 2-3 times without any luck. Most of the links were talking about this issue in a USB debugging scenario. Since I am not using the USB debugging these things felt not applicable to me. Then thought of restarting the machine. But before restarting the machine decided to google once again with 'upgrade ADT' keyword in search. It gave one more SO link where says to upgrade everything when we upgrade ADT. I followed the same way and it got fixed.

Another error I got during this exercise was
"An internal error occurred during: "Launching com.myproject".
com.android.ddmlib.IDevice.installRemotePackage(Ljava/lange/String;Z[Ljava/lang/String;)Ljava/lang/String;

This also resolved when I installed everything fresh. The Eclipse tools which I upgraded are
Traceview, Hierarchy viewer, Android Development ToolKit & Dalvik Debug Monitor Service( DDMS)

Then I successfully executed the project which my colleague gave me and checked the source into TFS.

Changing the target in project.properties file

Then I thought of running my previous Android projects as those were my first study apps. But unfortunately they failed with below exception

[DateTime - Dex Loader] Unable to execute dex: java.nio.BufferOverflowException. Check the Eclipse log for stack trace.
[DateTime - Test] Conversion to Dalvik format failed: Unable to execute dex: java.nio.BufferOverflowException. Check the Eclipse log for stack trace.

Again googled. This time I was able to study about one more file called project properties. Since I have changed the build tools, I need to update this file to point to version 19. I changed the target from android-10 to android-19 and every project started working.

This might be familiar to the regular Android developers. But for developers like me who works mainly in other technologies, its a task.

Monday, February 17, 2014

Using PerfView to catch eaten .Net exceptions

Most of the time eaten exceptions are nightmares to debugging guys. Almost all the developers are taught that never eat any exception but still there are chances that they may eat the exception as a short cut to hide the issues in their code. An exception means something  happened wrong and there should be some actions  to be taken to resolve or to inform the caller about that error. We cannot continue the program execution same way as if, there was no exception. When the developers hide exceptions they can continue for short period of time but eventually the consumers, who calls their APIs will get wrong data back and their tracks will fail. Usually by that time the application might be in business testing or other final rounds of testing. In the worst case it might be reached production. At this time if something goes wrong it would be difficult to find out as the original error is hidden somewhere other than the place where the error is visible.

There are many ways to capture these exceptions.Here I am explaining one of those ways to find out eaten exceptions using a free Tool called PerfView from Microsoft. You may download the tool from Microsoft downloads. Its a standalone executable. Below are the steps

  1. Run the tool.
  2. Start collection.
  3. Analyse the .etl file which is generated.
Here I am explaining in more detailed way by taking a scenario.

Sample scenario / application


        private static void DivideWhichNeverFails(int n1,int n2)
        {
            int r = 0;
            try
            {
                r = n1 / n2;
            }
            catch (Exception ex) 
            { 
            }
            Console.WriteLine(r);
        }

I don't think the above code needs any kind of explanation. The developer cleverly written to escape from the error. The caller will get a zero even if his operation didn't carried out. Again, this will happen only in the projects where the developers are working like type writers who just produce lines of code and code review is not at all followed.

If such a code enters into the code base, it may survive the testing as long as there are no calls into this method with n2 as 0. But it may fail once its in production on the label of an inconsistent issue. When we need to deal with such issues in production, the first thing should be to check for eaten exceptions. Perfview is a gift here.

Starting PerfView and collecting.

Just run the PerfView.exe and select the Collect menu -> Run.It will show a popup which has boxes to fill our application name and the log file path. Thanks to .Net CLR team for instrumenting everything using ETW. The PerfView collects the data using ETW providers and the file extension is .etl. Make sure in the 'Advanced Options' section '.Net' is checked.  'Run Command' button will run the application. Execute the use case which is reported as error. Then close the application. The data collection phase is over.

Analyse the .etl file

Now we need to analyse the logs collected. In the main window of PerfView.exe there is a file browser.Point it to the .etl file which is created as part of the data collection. Double click on the etl file to expand it. Select the 'Events' node and open it by double click. Then filter the 'Event Types' using Exception to see all the exceptions. It will give us the list of exceptions happened during the run.

To see the call stack, expand the 'Exception Stacks' node of the etl file. It will open the call stacks for all the processes happened in the system during the collection. Find out our particular process and get the exception.

Using PerfView to find out eaten exceptions of ASP.Net web apps.

Here instead of running particular application, use the global collection method. To collect everything, select Collect menu-> Collect option.Set the data collection etl file and click the 'Start Collection' button. Then execute the failed test case. Stop the collection and start analysis in the same way did for windows application.

Happy debugging.

Tuesday, February 4, 2014

Power of bit wise operators - Program to convert bit sequence into integer number

Below is one program written to demonstrate bit processing to one of the fresh programmer. He was trying to code a simple game where the user guess a number between 1-15 and selects whether the guessed number is present in the groups of numbers shown to him. There will be 4 groups of numbers shown to him. 

The program internally shows the numbers which have particular bit positions set. He was doing a big chunk of combinational if statements to decide what is the number guessed based on his selections. This program simplifies it. See the method GetNumberFromBits(). It doesn't cover failure scenarios such as handling a sequence which is more than the size of integer etc..Also all the methods are static.

Seems now a days colleges are not paying attention towards the basics of computer programming which is assembly language which plays with bits.

    class GuessedNumberFinder
    {
        public static void Play()
        {
            byte bitAt1 = GetUserOptionUsingConsole(GetNumbersBasedOnBitPosition(0x0001));
            byte bitAt2 = GetUserOptionUsingConsole(GetNumbersBasedOnBitPosition(0x0002));
            byte bitAt4 = GetUserOptionUsingConsole(GetNumbersBasedOnBitPosition(0x0004));
            byte bitAt8 = GetUserOptionUsingConsole(GetNumbersBasedOnBitPosition(0x0008));
            byte [] bits=new byte[]{bitAt8,bitAt4,bitAt2,bitAt1};
            //int number = Convert.ToInt32(bits.ToString(), 2); //Easiest way
            int result = GetNumberFromBits(bits);
            ShowResult(result);
        }
 
        private static void ShowResult(int result)
        {
            Console.WriteLine();
            Console.WriteLine("Guessed number :{0}", result);
        }
 
        /// <summary>
        /// Converts the sequence of bits to integer number.
        /// </summary>
        /// <param name="bits"></param>
        /// <returns></returns>
        private static int GetNumberFromBits(byte[] bits)
        {
            int result = 0;
            for (int i = 0; i < bits.Length; i++)
            {
                int bitPositionToProcess = (bits.Length - 1) - i;
                result = result | bits[bitPositionToProcess] << i;
            }
            return result;
        }
 
        private static byte GetUserOptionUsingConsole(IEnumerable<byte> numberList)
        {
            Console.WriteLine();
            Console.Write("Press (y/n) if the guessed number present in ");
            foreach (byte number in numberList)
                Console.Write("{0},", number);
            ConsoleKeyInfo key = Console.ReadKey();
            return (key.Key == ConsoleKey.Y) ? (byte)0x1 : (byte)0;
        }
 
        private static IEnumerable<byte> GetNumbersBasedOnBitPosition(int mask)
        {
            for (int index = 0; index < 16; index++)
            {
                if ((index & mask) != 0) yield return (byte)index;
            }
        }
    }