Download - Debugging Arts of the Ninja Masters

Transcript
Page 1: Debugging Arts of the Ninja Masters

Monday, June 1, 2009

Page 2: Debugging Arts of the Ninja Masters

Monday, June 1, 2009

Page 3: Debugging Arts of the Ninja Masters

Debugging Arts of the Ninja MastersJustin MattsonDeveloper AdvocateAndroid Team @ Google28/5/2009

Monday, June 1, 2009

Page 4: Debugging Arts of the Ninja Masters

3

Agenda

• Tool tour– logcat– traceview– hierarchyviewer

• Real world usage• Pop quiz!• Q&A (pop quiz for me)

Monday, June 1, 2009

Page 5: Debugging Arts of the Ninja Masters

Monday, June 1, 2009

Page 6: Debugging Arts of the Ninja Masters

logcat

Monday, June 1, 2009

Page 7: Debugging Arts of the Ninja Masters

5

The dialog of death

Monday, June 1, 2009

Page 8: Debugging Arts of the Ninja Masters

6

ForensicsWhere to begin the autopsy

Monday, June 1, 2009

Page 9: Debugging Arts of the Ninja Masters

7

logcatYour news feed

Monday, June 1, 2009

Page 10: Debugging Arts of the Ninja Masters

8

logcat Levels Defined

• [E]rror– A unexpected critical or non-recoverable failure happened

• [W]arning– Something bad happened, but it was handled gracefully

• [I]nfo– An important event occurred

• [D]ebug– Something happened that may be useful in isolating a problem

• [V]erbose– Something occurred in the normal course of operation that was

expected.

Monday, June 1, 2009

Page 11: Debugging Arts of the Ninja Masters

9

A simple caseThe code can't break!

public class UriReader extends Thread { public String uriToRead = null; @Override public void run() { DefaultHttpClient client = new DefaultHttpClient(); HttpGet request = new HttpGet(uriToRead); try { InputStream reader = client.execute(request).getEntity().getContent(); while (reader.read() != -1); } catch (ClientProtocolException e) { Log.w(TAG, "Protocol exception while reading URL."); } catch (IOException e) { Log.e(TAG, "General I/O exception, exact type is: " + e.getClass().getCanonicalName()); } } }

Monday, June 1, 2009

Page 12: Debugging Arts of the Ninja Masters

10

The scene of the crime

Monday, June 1, 2009

Page 13: Debugging Arts of the Ninja Masters

11

Take a good look around

Monday, June 1, 2009

Page 14: Debugging Arts of the Ninja Masters

12

The dialog of despair

Monday, June 1, 2009

Page 15: Debugging Arts of the Ninja Masters

13

Warning signsWhat’s that noise?

• Same process id, similar object count, similar sizes

Monday, June 1, 2009

Page 16: Debugging Arts of the Ninja Masters

14

Data Management

• Filters– TAG:SEVERITY

• Smart tagging– Meaningful– Related

• !SPAM– Precise– Concise– Privacy sensitive

Monday, June 1, 2009

Page 17: Debugging Arts of the Ninja Masters

Monday, June 1, 2009

Page 18: Debugging Arts of the Ninja Masters

traceview

Monday, June 1, 2009

Page 19: Debugging Arts of the Ninja Masters

16

tracing and traceview

• Records every function entry and exit point• Records how long execution took• Provides a graphical representation of collected data

– Timeline view– Call tree view

• Is a must-use for any developer serious about performance

Monday, June 1, 2009

Page 20: Debugging Arts of the Ninja Masters

17

How to start tracing

public class ProfiledActivity extends Activity { protected void onCreate(Bundle savedInstanceState) { Debug.startMethodTracing(); } ... public void onPause() { Debug.stopMethodTracing(); }}

• Starting and stopping trace data collection is simple

• Controls tracing for entire VM• Tracing only what you need simplifies analysis

• Tracing has a big impact on performance

justin$ adb shell am profile com.example.foo profile start /sdcard/trace_file...justin$ adb shell am profile com.example.foo stop

Monday, June 1, 2009

Page 21: Debugging Arts of the Ninja Masters

18

Execution timeline

Monday, June 1, 2009

Page 22: Debugging Arts of the Ninja Masters

19

Function statistics

Monday, June 1, 2009

Page 23: Debugging Arts of the Ninja Masters

20

Function statisticsDetails

• Name• “Incl %” - percentage of time including descendants• Inclusive - raw execution time including descendants• “Excl %” - percentage of time sans descendants• Exclusive - time spent executing code only within this function• “Calls+Recur Calls/Total” - Number of times this method is called• Time/Call - Average execution time per call

Monday, June 1, 2009

Page 24: Debugging Arts of the Ninja Masters

21

Getting to the bottom (or top) of things

• The source of the issue may be above or below your code• traceview allows you to easily navigate the call tree

Monday, June 1, 2009

Page 25: Debugging Arts of the Ninja Masters

21

Getting to the bottom (or top) of things

• The source of the issue may be above or below your code• traceview allows you to easily navigate the call tree

Monday, June 1, 2009

Page 26: Debugging Arts of the Ninja Masters

22

Optimize reality

• traceview gives you a lot of power, take advantage of it• Design sensibly, build proof of concept, test, and optimize

Monday, June 1, 2009

Page 27: Debugging Arts of the Ninja Masters

Monday, June 1, 2009

Page 28: Debugging Arts of the Ninja Masters

HierarchyViewer

Monday, June 1, 2009

Page 29: Debugging Arts of the Ninja Masters

24

Exploring the UI with HierarchyViewer

Monday, June 1, 2009

Page 30: Debugging Arts of the Ninja Masters

25

Climbing the tree

Monday, June 1, 2009

Page 31: Debugging Arts of the Ninja Masters

25

Climbing the tree

Monday, June 1, 2009

Page 32: Debugging Arts of the Ninja Masters

26

Questionable families

• “Infertile parents” - layout with no or single layout children

• “Clones” - parents with same-type children

Monday, June 1, 2009

Page 33: Debugging Arts of the Ninja Masters

27

<merge /> your @includes

<merge xmlns:android=”http://schemas.android.com/apk/res/android”> <TextView android:layout_width=”wrap_content” android:layout_height=”wrap_content” android:text=”@string/header_section” android:textColor=”@colors/header_color” /> <ImageView android:layout_width=”wrap_content” android:layout_height=”wrap_content” android:src=”@drawable/logo” /></merge>

• Merge is a placeholder layout• Children of <merge> go into the layout where they are included

Monday, June 1, 2009

Page 34: Debugging Arts of the Ninja Masters

Monday, June 1, 2009

Page 35: Debugging Arts of the Ninja Masters

Traveler’s Tales: Betrayal

Monday, June 1, 2009

Page 36: Debugging Arts of the Ninja Masters

29

TraceView on a shipping product

• Why is something running on the main thread for that long?• Must be a network request someone forgot to move to a thread

Monday, June 1, 2009

Page 37: Debugging Arts of the Ninja Masters

30

com.ibm.icu4jni.util.Resources.getTimeZonesNative

• A call about time zones is taking this long?• Wait, I’m not even doing anything with time zones

Monday, June 1, 2009

Page 38: Debugging Arts of the Ninja Masters

30

com.ibm.icu4jni.util.Resources.getTimeZonesNative

• A call about time zones is taking this long?• Wait, I’m not even doing anything with time zones

Monday, June 1, 2009

Page 39: Debugging Arts of the Ninja Masters

30

com.ibm.icu4jni.util.Resources.getTimeZonesNative

• A call about time zones is taking this long?• Wait, I’m not even doing anything with time zones

Monday, June 1, 2009

Page 40: Debugging Arts of the Ninja Masters

31

Fixing the problem

• Move the call• De-prioritize its execution• Result: Better perceived startup time

Monday, June 1, 2009

Page 41: Debugging Arts of the Ninja Masters

31

Fixing the problem

• Move the call• De-prioritize its execution• Result: Better perceived startup time

Monday, June 1, 2009

Page 42: Debugging Arts of the Ninja Masters

32

Key Learnings

• Trust no one

• A little profiling goes a long way

• Priority matters

Monday, June 1, 2009

Page 43: Debugging Arts of the Ninja Masters

Monday, June 1, 2009

Page 44: Debugging Arts of the Ninja Masters

Traveler’s Tales: Finding shortcuts

Monday, June 1, 2009

Page 45: Debugging Arts of the Ninja Masters

34

Search for hidden inefficiencies

• Look at the function listing for less obvious performance issues

• Sort by exclusive execution– Shows inside which methods the program spends most of its time– Long average time methods with a few calls are good targets– Explore reducing and eliminating these calls

Monday, June 1, 2009

Page 46: Debugging Arts of the Ninja Masters

35

Search for hidden inefficiencies

Monday, June 1, 2009

Page 47: Debugging Arts of the Ninja Masters

36

Take a look around

• Explore ancestors and descendants of the method• Use timeline line view to check what happens before and after

the method

Monday, June 1, 2009

Page 48: Debugging Arts of the Ninja Masters

37

Take a look around

Monday, June 1, 2009

Page 49: Debugging Arts of the Ninja Masters

37

Take a look around

Monday, June 1, 2009

Page 50: Debugging Arts of the Ninja Masters

38

Iterate the route into a circle (square?)

Monday, June 1, 2009

Page 51: Debugging Arts of the Ninja Masters

38

Iterate the route into a circle (square?)

Parse response

Monday, June 1, 2009

Page 52: Debugging Arts of the Ninja Masters

38

Iterate the route into a circle (square?)

Parse response Create B

itmap

Monday, June 1, 2009

Page 53: Debugging Arts of the Ninja Masters

38

Iterate the route into a circle (square?)

Parse response Create B

itmap

Compress Bitmap

Monday, June 1, 2009

Page 54: Debugging Arts of the Ninja Masters

38

Iterate the route into a circle (square?)

Parse response Create B

itmap

Compress BitmapAdd

resu

lt to

cac

he

Monday, June 1, 2009

Page 55: Debugging Arts of the Ninja Masters

39

Fixing the problem

• Read in the full response• Store the PNG• Inflate Bitmap from PNG data• Discard PNG data

• Result: Decrease startup time by 350ms – 2% in “debug time”, larger real time effect since its native code

Monday, June 1, 2009

Page 56: Debugging Arts of the Ninja Masters

40

Key Learnings

• Big is beautiful

• Explore the area first

• Three rights can make a left

Monday, June 1, 2009

Page 57: Debugging Arts of the Ninja Masters

Monday, June 1, 2009

Page 58: Debugging Arts of the Ninja Masters

Traveler’s Tales: Packing mistakes

Monday, June 1, 2009

Page 59: Debugging Arts of the Ninja Masters

42

Sorting by inclusive execution

• Includes execution time of methods code and its descendants• List is somewhat like a breadth-first traversal of the call tree

Monday, June 1, 2009

Page 60: Debugging Arts of the Ninja Masters

42

Sorting by inclusive execution

• Includes execution time of methods code and its descendants• List is somewhat like a breadth-first traversal of the call tree

Monday, June 1, 2009

Page 61: Debugging Arts of the Ninja Masters

43

Taking a look at the code

try { List<MyDataType> itemsProcessed = new ArrayList<MyDataType>(); for (int i = 0; i < source.getNumItems(); i++) { Item currentItem = source.get(i); MyDataType processedItem = new MyDataType(currentItem); itemsProcessed.add(processedItem); itemProcessedCallback(itemsProcessed); }} catch (IOException e) { Log.W(TAG, “Reading data failed, retrying”);} catch (JSONException e) { Log.E(TAG, “JSON parsing failed”);}

• Items will be processed several times, this seems wrong

Monday, June 1, 2009

Page 62: Debugging Arts of the Ninja Masters

44

Fixing the problem

• Bug introduced when exception handling was refactored

• Result: Fewer calls to callback, 5% decrease in startup time

try { List<MyDataType> itemsProcessed = new ArrayList<MyDataType>(); for (int i = 0; i < source.getNumItems(); i++) { Item currentItem = source.get(i); MyDataType processedItem = new MyDataType(currentItem); itemsProcessed.add(processedItem); } itemProcessedCallback(itemsProcessed);} catch (IOException e) { Log.W(TAG, “Reading data failed, retrying”);} catch (JSONException e) { Log.E(TAG, “JSON parsing failed”);}

Monday, June 1, 2009

Page 63: Debugging Arts of the Ninja Masters

45

Key Learnings

• Each angle of approach is valuable

• Analyzing performance can reveal unknown bugs

Monday, June 1, 2009

Page 64: Debugging Arts of the Ninja Masters

Monday, June 1, 2009

Page 65: Debugging Arts of the Ninja Masters

Traveler’s Tales: Consolidating containers

Monday, June 1, 2009

Page 66: Debugging Arts of the Ninja Masters

47

A “simple” layout examined

Monday, June 1, 2009

Page 67: Debugging Arts of the Ninja Masters

47

A “simple” layout examined

Monday, June 1, 2009

Page 68: Debugging Arts of the Ninja Masters

48

Fixing the Problem

Monday, June 1, 2009

Page 69: Debugging Arts of the Ninja Masters

48

Fixing the Problem

Monday, June 1, 2009

Page 70: Debugging Arts of the Ninja Masters

48

Fixing the Problem

Monday, June 1, 2009

Page 71: Debugging Arts of the Ninja Masters

48

Fixing the Problem

Monday, June 1, 2009

Page 72: Debugging Arts of the Ninja Masters

48

Fixing the Problem

Monday, June 1, 2009

Page 73: Debugging Arts of the Ninja Masters

48

Fixing the Problem

Monday, June 1, 2009

Page 74: Debugging Arts of the Ninja Masters

48

Fixing the Problem

Monday, June 1, 2009

Page 75: Debugging Arts of the Ninja Masters

48

Fixing the Problem

Monday, June 1, 2009

Page 76: Debugging Arts of the Ninja Masters

48

Fixing the Problem

Monday, June 1, 2009

Page 77: Debugging Arts of the Ninja Masters

48

Fixing the Problem

Monday, June 1, 2009

Page 78: Debugging Arts of the Ninja Masters

48

Fixing the Problem

Monday, June 1, 2009

Page 79: Debugging Arts of the Ninja Masters

49

Fixing the problem

Monday, June 1, 2009

Page 80: Debugging Arts of the Ninja Masters

49

Fixing the problem

Monday, June 1, 2009

Page 81: Debugging Arts of the Ninja Masters

50

If it looks the same, who cares?

• Flatten for aerodynamic performance

• RelativeLayouts adapt to their environment

• RelativeLayouts force you to think

Monday, June 1, 2009

Page 82: Debugging Arts of the Ninja Masters

51

Key Learnings

• Layouts are code too and will evolve iteratively

• LinearLayouts are simple to visualize and understand, but can result in overly complex, less flexible hierarchies

• Rationalization needs to happen to keep the layout comprehensible and efficient

INSERT GLUED TOGETHER UI GRAPHIC

Monday, June 1, 2009

Page 83: Debugging Arts of the Ninja Masters

Monday, June 1, 2009

Page 84: Debugging Arts of the Ninja Masters

Traveler’s Tales: Squeaky wheels

Monday, June 1, 2009

Page 85: Debugging Arts of the Ninja Masters

53

What’s that noise?

• Same process id, similar object count, similar sizes

Monday, June 1, 2009

Page 86: Debugging Arts of the Ninja Masters

54

Allocation Tracker

Monday, June 1, 2009

Page 87: Debugging Arts of the Ninja Masters

55

Allocation Tracking

Monday, June 1, 2009

Page 88: Debugging Arts of the Ninja Masters

56

Using the right tool

• Problem caused by old code– Used for speed and convenience, over-stayed its welcome

public static byte[] fetchUri(String url) { ... InputStream in = openUrl(url); byte[] response = new byte[0]; byte[] readChunk = new byte[384]; int byteSize = 0; while ( (byteSize = in.read(readChunk)) != -1) { byte[] alreadyRead = response; response = new byte[alreadyRead.length + byteSize]; mergeArrays(response, alreadyRead, readChunk); }}

Monday, June 1, 2009

Page 89: Debugging Arts of the Ninja Masters

57

Fixing the problem

• Rewrite code to fit the problem• Anticipate larger read sizes, read in pieces, zipper together only

at the end

• Result: 90% decrease in read times

public static byte[] fetchUri(String url) { ... InputStream in = openUrl(url); ArrayList <byte[]> responsePieces = new ArrayList <byte[]>(); byte[] readChunk = new byte[2048]; int biteSize = 0; int responseSize = 0; while ( (biteSize = in.read(readChunk)) != -1) { responsePieces.add(readChunk); responseSize += biteSize; readChunk = new byte[2048]; } byte[] fullResponse = new byte[responseSize]; mergeArrays(fullResponse, responseSize);}

Monday, June 1, 2009

Page 90: Debugging Arts of the Ninja Masters

58

Key Learnings

• Take care with reused or prototype code

• Log messages if code is used beyond tolerances

Monday, June 1, 2009

Page 91: Debugging Arts of the Ninja Masters

Monday, June 1, 2009

Page 92: Debugging Arts of the Ninja Masters

Pop quiz!

Monday, June 1, 2009

Page 93: Debugging Arts of the Ninja Masters

60

What’s gone wrong?

Monday, June 1, 2009

Page 94: Debugging Arts of the Ninja Masters

60

What’s gone wrong?

Monday, June 1, 2009

Page 95: Debugging Arts of the Ninja Masters

61

What change caused this slow down?

Monday, June 1, 2009

Page 96: Debugging Arts of the Ninja Masters

Q&A

Monday, June 1, 2009