[{"data":1,"prerenderedAt":669},["ShallowReactive",2],{"\u002Fdebugging-techniques":3},{"id":4,"title":5,"body":6,"createdAt":657,"description":12,"draft":658,"extension":659,"image":660,"mastodonThread":660,"meta":661,"navigation":662,"path":663,"seo":664,"stem":665,"tags":666,"updatedAt":667,"__hash__":668},"content\u002FDebugging Techniques.md","Debugging_Techniques",{"type":7,"value":8,"toc":653},"minimark",[9,13],[10,11,12],"p",{},"A brain-dump of various approaches to debugging (code) things that I like.",[14,15,16,28,54,62,73,125,152,202,302,336,352,385,413,454,512,549,572,589,633],"ul",{},[17,18,19,20],"li",{},"Development is mostly debugging\n",[14,21,22,25],{},[17,23,24],{},"You could even say that it is ALL debugging",[17,26,27],{},"Implementing a feature is fixing the lack of that feature",[17,29,30,31],{},"Types of bugs\n",[14,32,33,36,39,42,45,48,51],{},[17,34,35],{},"Syntax",[17,37,38],{},"500 server error",[17,40,41],{},"Unexpected output",[17,43,44],{},"Legit issue that is not communicated to the user well",[17,46,47],{},"Configuration issue -- routes, library setup",[17,49,50],{},"Security issue",[17,52,53],{},"Generally undesired behavior",[17,55,56,57],{},"Read the documentation\n",[14,58,59],{},[17,60,61],{},"\"Use The Source, Luke\" -- Wise Sage",[17,63,64,65],{},"Dead Debugging vs Live Debugging\n",[14,66,67,70],{},[17,68,69],{},"Dead Debugging -- you can't (easily) run the code or modified versions",[17,71,72],{},"Live Debugging -- make a change, see result, breakpoints, everything",[17,74,75,76],{},"What's even happening\n",[14,77,78,100,117],{},[17,79,80,81],{},"Build your feedback loop\n",[14,82,83,86],{},[17,84,85],{},"Write log entries to SEE what is happening instead of guessing",[17,87,88,89],{},"Build shortcut to getting to the critical point\n",[14,90,91,94,97],{},[17,92,93],{},"This is a great spot for leveraging unit\u002Ffeature specs",[17,95,96],{},"Have a fast way to re-start -- like a save point in a game",[17,98,99],{},"Re-send XHR in browser, or open in new tab! Copy Curl command!",[17,101,102,103],{},"Get some visibility\n",[14,104,105,108,111,114],{},[17,106,107],{},"You can't debug what you can't observe or infer",[17,109,110],{},"Observing is easier than inferring",[17,112,113],{},"Log-based debugging (print \"here\")",[17,115,116],{},"Debugger-based debugging (binding.pry)",[17,118,119,120],{},"Why is it this way anyway?\n",[14,121,122],{},[17,123,124],{},"Revision control ... did someone do this on purpose?",[17,126,127,128],{},"State -- Best friend. Worst enemy.\n",[14,129,130,133,136,144],{},[17,131,132],{},"Think about inputs, outputs, and state",[17,134,135],{},"Local variables, parameters, scoped variables, global variables",[17,137,138,139],{},"Look at the actual database \u002F storage\n",[14,140,141],{},[17,142,143],{},"The state that exists even when your program isn't running",[17,145,146,147],{},"State CHANGES over TIME\n",[14,148,149],{},[17,150,151],{},"This is why multi-process debugging is so hard... competing timelines",[17,153,154,155],{},"Model the world. Beware of assumptions!\n",[14,156,157,188],{},[17,158,159,160],{},"Don't assume!\n",[14,161,162,165,168,171,174],{},[17,163,164],{},"LOOK at the contents of variables",[17,166,167],{},"RUN methods and see what they return",[17,169,170],{},"LOOK at the code you're calling and what calls you",[17,172,173],{},"VERIFY that it's even running this code at all",[17,175,176,177],{},"LOOK at the revision history to get some time-context\n",[14,178,179,182,185],{},[17,180,181],{},"Did this change recently?",[17,183,184],{},"Was this put here on purpose?",[17,186,187],{},"Look at the annotation, the commits, the commit-messages, the linked tickets",[17,189,190,191],{},"Verify assumptions\n",[14,192,193,196,199],{},[17,194,195],{},"Add an \"X\" and see if it shows up on the page where you expect",[17,197,198],{},"Add a syntax error and make sure it breaks. Delete everything and make sure it breaks.",[17,200,201],{},"Hard-wire weird values in place of method calls",[17,203,204,205],{},"Narrow the problem\n",[14,206,207,224,263,277,291,294],{},[17,208,209,210],{},"Simplify reproduction steps\n",[14,211,212,215,218,221],{},[17,213,214],{},"Try to figure out what you care about and what you don't",[17,216,217],{},"See if you can reproduce the issue without some of the nuance",[17,219,220],{},"Remove the weird bits one at a time",[17,222,223],{},"The less steps it takes to cause the problem, the less you have to think about",[17,225,226,227],{},"Figure out where this code even lives\n",[14,228,229,251,254,257,260],{},[17,230,231,235,236],{},[232,233,234],"code",{},"grep","!\n",[14,237,238,248],{},[17,239,240,243,244,247],{},[232,241,242],{},"ack",", ripgrep (",[232,245,246],{},"rg","), atom\u002Fvscode search, ...",[17,249,250],{},"See some text",[17,252,253],{},"Trace from entrypoints",[17,255,256],{},"Trace backwards from the error if you have one",[17,258,259],{},"Read the stacktrace!",[17,261,262],{},"Copy some random text from the screen and grep for that",[17,264,265,266],{},"Bracket the issue\n",[14,267,268,271,274],{},[17,269,270],{},"Hard-wire values",[17,272,273],{},"Interactive Unit Testing",[17,275,276],{},"Log state at various points of execution",[17,278,279,280],{},"Read the error message\n",[14,281,282,285,288],{},[17,283,284],{},"Sometimes ... often ... it will actually TELL you what is wrong",[17,286,287],{},"Even when it is vague or lying it is a good starting point to trace backwards from",[17,289,290],{},"Often it comes with a stack trace -- read the stack trace!",[17,292,293],{},"Read the log entries just before the error message",[17,295,296,297],{},"Trace forward and backward from the error\n",[14,298,299],{},[17,300,301],{},"Learning who calls what in any language is necessary knowledge",[17,303,304,305],{},"Execution Environment\n",[14,306,307,315],{},[17,308,309,310],{},"Use a completely different dataset \u002F environment to reproduce\n",[14,311,312],{},[17,313,314],{},"Go beyond \"Works on my machine!\"",[17,316,317,318],{},"Eliminate your environment as the unintended cause of the issue\n",[14,319,320,330,333],{},[17,321,322,323,326,327],{},"Speaking of environments, use ",[232,324,325],{},"asdf"," or similar and don't install using ",[232,328,329],{},"sudo",[17,331,332],{},"Try a different browser, or incognito, or different OS",[17,334,335],{},"Ask a friend!",[17,337,338,339],{},"Structured thinking\n",[14,340,341],{},[17,342,343,344],{},"Try to think about less things\n",[14,345,346,349],{},[17,347,348],{},"Chunk concepts into short-term memory",[17,350,351],{},"Take notes",[17,353,354,355],{},"Modify the world\n",[14,356,357,360,371,382],{},[17,358,359],{},"Don't suffer in the current world, switch to the one you wish you had",[17,361,362,363],{},"Build tiny scenarios\n",[14,364,365,368],{},[17,366,367],{},"Create toy worlds to play in",[17,369,370],{},"H1 tags should be clickable ... make a new component with an H1 tag and an onclick and ... click it",[17,372,373,374],{},"Edit your dependencies!\n",[14,375,376,379],{},[17,377,378],{},"bundle open",[17,380,381],{},"pry your way in",[17,383,384],{},"It's more obvious what a variable contains when it is hard-wired",[17,386,387,388],{},"Actual bug hunting in a living application\n",[14,389,390],{},[17,391,392,393],{},"Did this work before?\n",[14,394,395,398,401,404,407,410],{},[17,396,397],{},"What changed?",[17,399,400],{},"Assumptions about the data",[17,402,403],{},"Assumptions about the external world",[17,405,406],{},"Why did it change?",[17,408,409],{},"Why did this ever work?",[17,411,412],{},"Do we have tests around this? What do they assume?",[17,414,415,416],{},"Why does this work sometimes and not others?\n",[14,417,418,421,424,427,443],{},[17,419,420],{},"SOMETHING about the state is changing",[17,422,423],{},"The ordering in the sequence of events",[17,425,426],{},"The datatypes",[17,428,429,430],{},"External state is changing (and depended on)\n",[14,431,432,440],{},[17,433,434,435],{},"Time! My favorite. (TimeCop)\n",[14,436,437],{},[17,438,439],{},"Especially time zones, DST, and holidays",[17,441,442],{},"Other systems",[17,444,445,446],{},"The world is deterministic but chaotic\n",[14,447,448,451],{},[17,449,450],{},"Unless you are dealing with quantum physics",[17,452,453],{},"You are not dealing with quantum physics",[17,455,456,457],{},"When you are stuck\n",[14,458,459,473,509],{},[17,460,461,462],{},"Model the problem in detail\n",[14,463,464,467,470],{},[17,465,466],{},"Draw pictures of the data-flow",[17,468,469],{},"Draw pictures of the data-structures",[17,471,472],{},"Sequence diagrams are good for complex interactions, especially timing issues",[17,474,475,476],{},"Science!\n",[14,477,478,491,494,497,500,503,506],{},[17,479,480,481],{},"\"Remember kids, the only difference between screwing around and science is writing it down\" -- Adam Savage\n",[14,482,483],{},[17,484,485],{},[486,487,488],"a",{"href":488,"rel":489},"https:\u002F\u002Fwww.reddit.com\u002Fr\u002Fmythbusters\u002Fcomments\u002F3wgqgv\u002Fthe_origin_of_the_remember_kids_the_only\u002F",[490],"nofollow",[17,492,493],{},"The tool of last resort?",[17,495,496],{},"When things can't fit in our tiny brains",[17,498,499],{},"Write it as a test",[17,501,502],{},"Write it on paper",[17,504,505],{},"Write it on a whiteboard",[17,507,508],{},"Write it in code (aka Test Driven Debugging)",[17,510,511],{},"Ask for help!",[17,513,514,515],{},"The problem is not in the language\n",[14,516,517,520,523,526,529],{},[17,518,519],{},"You did not find an implementation error in Ruby (unless you are reading C code)",[17,521,522],{},"You did not find an implementation error in Linux (unless you are reading C code)",[17,524,525],{},"It is almost definitely not the framework",[17,527,528],{},"It is probably not the library",[17,530,531,532],{},"Prioritize your suspect list based on probability\n",[14,533,534,537,540,543,546],{},[17,535,536],{},"How many people use layer X without issue?",[17,538,539],{},"Linux -- LOTS",[17,541,542],{},"Ruby -- Lots",[17,544,545],{},"Rails -- Lots",[17,547,548],{},"app\u002Fmodels\u002Fmy_biz_logic.rb? Not so many",[17,550,551,552],{},"How to practice\n",[14,553,554,557,560,563,566,569],{},[17,555,556],{},"Pick something on the screen and find the code that makes it",[17,558,559],{},"Modify the code to see that you can affect change",[17,561,562],{},"Trace the code to see how it goes from Browser -> code -> Browser",[17,564,565],{},"Write failing tests that would have caught the issue",[17,567,568],{},"Try out different tools -- debuggers, REPLS, editors, git things",[17,570,571],{},"Read (trace!) code of your app, your dependencies, other applications",[17,573,574,575],{},"Write More Tests\n",[14,576,577,580,583,586],{},[17,578,579],{},"Unit tests are like robot-you that are validating assumptions all the time",[17,581,582],{},"Unit tests are a shortcut to get into situations quickly",[17,584,585],{},"Tests can contain bugs!",[17,587,588],{},"Feature (browser tests) verify that things fit together",[17,590,591,592],{},"Key tools\n",[14,593,594,601,604,616,619,624],{},[17,595,596,598,599],{},[232,597,234],{},"\u002F",[232,600,246],{},[17,602,603],{},"Your editor",[17,605,606,607,610,611],{},"Pry\u002Firb\u002Fbyebug, js ",[232,608,609],{},"debugger","+firefox\u002Fchrome\n",[14,612,613],{},[17,614,615],{},"pry-byebug",[17,617,618],{},"rspec\u002Fcapybara",[17,620,621],{},[232,622,623],{},"diff -u",[17,625,626,629,630],{},[232,627,628],{},"bundle open \u003Clib>"," \u002F ",[232,631,632],{},"gem open \u003Clib>",[17,634,635,636],{},"Crazy power tools\n",[14,637,638,641,644,647,650],{},[17,639,640],{},"git bisect",[17,642,643],{},"rspec bisect",[17,645,646],{},"ruby -rtracer hiya.rb",[17,648,649],{},"strace \u002F dtrace",[17,651,652],{},"wireshark\u002FProxy? xxd? decompiler?",{"title":654,"searchDepth":655,"depth":655,"links":656},"",2,[],"2020-05-20T14:53-04:00",false,"md",null,{},true,"\u002Fdebugging-techniques",{"title":5,"description":12},"Debugging Techniques",[232],"2020-05-21T10:08-04:00","CBUinuKlkszChf8qcOg2R1vUVYIvjliOizWJWr_QhKA",1778988311299]