<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.8.5">Jekyll</generator><link href="https://blog.mattjustice.com//feed.xml" rel="self" type="application/atom+xml" /><link href="https://blog.mattjustice.com//" rel="alternate" type="text/html" /><updated>2022-10-24T14:27:20-04:00</updated><id>https://blog.mattjustice.com//feed.xml</id><title type="html">Matthew Justice’s blog</title><subtitle>technology and other things</subtitle><author><name>Matthew Justice</name></author><entry><title type="html">Programming UNROM-512 with Kazzo hardware (NESDEV)</title><link href="https://blog.mattjustice.com//2022/10/24/unrom-512-with-kazzo/" rel="alternate" type="text/html" title="Programming UNROM-512 with Kazzo hardware (NESDEV)" /><published>2022-10-24T10:00:00-04:00</published><updated>2022-10-24T10:00:00-04:00</updated><id>https://blog.mattjustice.com//2022/10/24/unrom-512-with-kazzo</id><content type="html" xml:base="https://blog.mattjustice.com//2022/10/24/unrom-512-with-kazzo/">&lt;p&gt;&lt;img src=&quot;/assets/images/kazzo-unrom-512-400px.jpg&quot; alt=&quot;alt text&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;background&quot;&gt;Background&lt;/h2&gt;

&lt;p&gt;I’m developing a game for the NES, and I recently got a couple of flashable &lt;a href=&quot;https://www.nesdev.org/wiki/UNROM_512&quot;&gt;UNROM-512&lt;/a&gt; PCBs from &lt;a href=&quot;https://www.brokestudio.fr/product/nes-unrom512-mapper-30-pcb-nesmaker/&quot;&gt;Broke Studio&lt;/a&gt;. To program these boards, I’m using the &lt;a href=&quot;http://www.infiniteneslives.com/kazzo.php&quot;&gt;Kazzo cartridge Dumper-Programmer&lt;/a&gt; from &lt;a href=&quot;https://twitter.com/InfiniteNesLive&quot;&gt;Infinite NES Lives&lt;/a&gt; - this is the older, discontinued version of the hardware based on the AVR / ATMEGA microcontroller. I didn’t have success using the old &lt;code class=&quot;highlighter-rouge&quot;&gt;INL retro-prog v1.1beta.exe&lt;/code&gt; software for programming these boards, but the newer software works. In case anyone else is interested, here’s what I did…&lt;/p&gt;

&lt;h2 id=&quot;steps&quot;&gt;Steps&lt;/h2&gt;

&lt;ol&gt;
  &lt;li&gt;Get the INL retro programmer-dumper software here:
&lt;a href=&quot;https://gitlab.com/InfiniteNesLives/INL-retro-progdump&quot;&gt;https://gitlab.com/InfiniteNesLives/INL-retro-progdump&lt;/a&gt; or from the &lt;a href=&quot;https://gitlab.com/BrokeStudio/INL-retro-progdump&quot;&gt;BrokeStudio fork&lt;/a&gt;.&lt;/li&gt;
  &lt;li&gt;Follow the instructions in the readme for installing the driver and updating the firmware on the kazzo device.&lt;/li&gt;
  &lt;li&gt;As mentioned in the &lt;a href=&quot;https://archive.nes.science/nesdev-forums/f9/t18856.xhtml&quot;&gt;discussion here&lt;/a&gt;, get the &lt;a href=&quot;https://www.dropbox.com/s/naxrms14dq035d5/mapper30v2.lua?dl=0&quot;&gt;modified mapper30v2 lua script file&lt;/a&gt; and replace the file in &lt;code class=&quot;highlighter-rouge&quot;&gt;\INL-retro-progdump\host\scripts\nes&lt;/code&gt;.&lt;/li&gt;
  &lt;li&gt;With the kazzo device in run mode and the UNROM-512 cart inserted, execute the following command from the &lt;code class=&quot;highlighter-rouge&quot;&gt;\INL-retro-progdump\host&lt;/code&gt; directory.&lt;/li&gt;
&lt;/ol&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;inlretro.exe -s scripts\inlretro2.lua -c NES -x 512 -m mapper30v2 -p &amp;lt;path_to_nes_file&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;blockquote&gt;
  &lt;p&gt;Important: the input file should be a full NES file, not just the PRG binary data. It needs to include a NES header.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2 id=&quot;example-output&quot;&gt;Example output&lt;/h2&gt;

&lt;p&gt;If everything works, you should see output like so:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Successfully found and connected to INL retro-prog
Device firmware version: 2.1.x
firmware app ver request:       3
checking for old firmware
later firmware sensed, running current script
Testing         MAP30
attempting to detect NES/FC mapper via mirroring...
vertical mirroring sensed
detected RAM @ PPU $    1000
EXP0 pull-up test:      15
reading PRG-ROM manf ID
attempted read PRG-ROM manf ID: BF
attempted read PRG-ROM prod ID: B7
CHR-RAM BANKING TEST PASSED

erasing MAP30
42      naks, done erasing prg.

Programming PRG-ROM flash
writting PRG bank:      0        of     31.0
writting PRG bank:      4        of     31.0
writting PRG bank:      8        of     31.0
writting PRG bank:      12       of     31.0
writting PRG bank:      16       of     31.0
writting PRG bank:      20       of     31.0
writting PRG bank:      24       of     31.0
writting PRG bank:      28       of     31.0
Done Programming PRG-ROM flash
total time:     43.374  seconds, average speed: 11.80   KBps
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;</content><author><name>Matthew Justice</name></author><summary type="html"></summary></entry><entry><title type="html">Profiling C code on Linux with gprof</title><link href="https://blog.mattjustice.com//2020/11/24/gprof-profiler/" rel="alternate" type="text/html" title="Profiling C code on Linux with gprof" /><published>2020-11-24T09:00:00-05:00</published><updated>2020-11-24T09:00:00-05:00</updated><id>https://blog.mattjustice.com//2020/11/24/gprof-profiler</id><content type="html" xml:base="https://blog.mattjustice.com//2020/11/24/gprof-profiler/">&lt;hr /&gt;
&lt;p&gt;&lt;strong&gt;Summary:&lt;/strong&gt; &lt;code class=&quot;highlighter-rouge&quot;&gt;gprof&lt;/code&gt; is performance analysis tool for Linux. Use it by compiling your C code with the &lt;code class=&quot;highlighter-rouge&quot;&gt;-pg&lt;/code&gt; option for &lt;code class=&quot;highlighter-rouge&quot;&gt;gcc&lt;/code&gt;, reproducing the issue, and then running &lt;code class=&quot;highlighter-rouge&quot;&gt;gprof&lt;/code&gt; against the previously-generated &lt;code class=&quot;highlighter-rouge&quot;&gt;gmon.out&lt;/code&gt; file.&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;background&quot;&gt;Background&lt;/h2&gt;

&lt;p&gt;I was writing some cross-platform C code that worked well on my Windows 10 PC, but didn’t work so well on a Raspberry Pi 4 running Raspberry Pi OS. The program would slow down dramatically, and a quick analysis showed that there was a CPU bottleneck. I needed a profiler to help me see where the program’s CPU time was being spent. I decided to use &lt;code class=&quot;highlighter-rouge&quot;&gt;gprof&lt;/code&gt;.&lt;/p&gt;

&lt;h2 id=&quot;steps&quot;&gt;Steps&lt;/h2&gt;

&lt;p&gt;First, your code needs to be recompiled with the &lt;code class=&quot;highlighter-rouge&quot;&gt;-pg&lt;/code&gt; option for the &lt;code class=&quot;highlighter-rouge&quot;&gt;gcc&lt;/code&gt; compiler. This option needs to be applied at both the compilation and linking step. The &lt;code class=&quot;highlighter-rouge&quot;&gt;-pg&lt;/code&gt; option generates instrumentation that tracks function calls at runtime.&lt;/p&gt;

&lt;p&gt;Once you rebuild your program, run it again and reproduce the issue. Ideally, allow the slow part of the program to execute multiple times so you get a good sample of the problem. Exit the program, and you should see that a new file was generated: &lt;code class=&quot;highlighter-rouge&quot;&gt;gmon.out&lt;/code&gt;. This file contains the data collected by the &lt;code class=&quot;highlighter-rouge&quot;&gt;-pg&lt;/code&gt; instrumentation.&lt;/p&gt;

&lt;p&gt;The next step is to process &lt;code class=&quot;highlighter-rouge&quot;&gt;gmon.out&lt;/code&gt; using &lt;code class=&quot;highlighter-rouge&quot;&gt;gprof&lt;/code&gt;. The tool takes two arguments: the executable filename that was used to generate the gmon.out file, and the path to the gmon.out file. This tool generates a lot of output text, so you may want to redirect it to a text file. Run it like this:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$ gprof /path/to/exe /path/to/gmon.out &amp;gt; gmon.txt
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Open the &lt;code class=&quot;highlighter-rouge&quot;&gt;gmon.txt&lt;/code&gt; file and you’ll see results that look something like this:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;  %   cumulative   self              self     total           
 time   seconds   seconds    calls  ms/call  ms/call  name    
 80.01      0.12     0.12      392     0.31     0.31  FunctionA
 20.00      0.15     0.03     2480     0.01     0.01  FunctionX
  0.00      0.15     0.00   169740     0.00     0.00  FunctionB
  0.00      0.15     0.00   144896     0.00     0.00  FunctionY
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;considerations&quot;&gt;Considerations&lt;/h2&gt;

&lt;p&gt;Be careful of how you interpret the results. There’s an explanation in the generated output of the meaning of the various columns. The cumulative time includes calls to other functions, so keep in mind the caller/callee relationship of the functions (the output also includes sampled call stacks, which can be helpful in understanding this). Also, consider that &lt;code class=&quot;highlighter-rouge&quot;&gt;gprof&lt;/code&gt; doesn’t track calls made into libraries that weren’t built with the &lt;code class=&quot;highlighter-rouge&quot;&gt;-pg&lt;/code&gt; option, so time spent in those libraries may instead accrue to the calling function.&lt;/p&gt;

&lt;h2 id=&quot;my-findings&quot;&gt;My Findings&lt;/h2&gt;

&lt;p&gt;Going back to the problem I had on Raspberry Pi, it turns out I had some rather inefficient code that was making too many calls to the OS graphics libraries. On Windows, this problem was masked by the excellent performance of the graphics driver. On Raspberry Pi OS, the graphics stack couldn’t keep up, and the problem became clear. Since I can’t rely on the performance of a particular system’s graphics implementation, I’m going to optimize my own code, minimizing calls to the OS graphics libraries.&lt;/p&gt;</content><author><name>Matthew Justice</name></author><summary type="html">Summary: gprof is performance analysis tool for Linux. Use it by compiling your C code with the -pg option for gcc, reproducing the issue, and then running gprof against the previously-generated gmon.out file.</summary></entry><entry><title type="html">Zoom security and privacy - how bad is it?</title><link href="https://blog.mattjustice.com//2020/04/07/zoom-security-privacy/" rel="alternate" type="text/html" title="Zoom security and privacy - how bad is it?" /><published>2020-04-07T14:00:00-04:00</published><updated>2020-04-07T14:00:00-04:00</updated><id>https://blog.mattjustice.com//2020/04/07/zoom-security-privacy</id><content type="html" xml:base="https://blog.mattjustice.com//2020/04/07/zoom-security-privacy/">&lt;p&gt;I keep reading news stories about how terrible Zoom is from a security and privacy standpoint. I host a weekly video call, and I’d like to use Zoom since everyone loves it, but should I be concerned about the issues recently uncovered, at least for my own use of Zoom? In this post I’m going to cover the various recent issues (using &lt;a href=&quot;https://www.cnet.com/news/zoom-every-security-issue-uncovered-in-the-video-chat-app/&quot;&gt;CNET’s recent article&lt;/a&gt; for a list of issues), and give my thoughts on each, focusing on how it matters in my own usage of Zoom.&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;&lt;strong&gt;TLDR:&lt;/strong&gt; Zoom has made some security and privacy missteps, but these issues won’t be of serious concern to the average user. Be sure to use a password on your meetings and only share the meeting link with people you trust. That said, given the number of recently discovered issues, there may be other problems lurking in Zoom’s code, so take note of new issues as they are reported.&lt;/p&gt;

&lt;hr /&gt;

&lt;h3 id=&quot;recent-zoom-issues&quot;&gt;Recent Zoom Issues&lt;/h3&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;strong&gt;Zoombombing and Zoomraids&lt;/strong&gt; - Troublemakers like to jump into Zoom calls and do bad stuff. This is less a Zoom issue and more a basic internet security issue. If you share a link to the world then bad people might click that link! This isn’t an issue if you password protect your Zoom calls and only share meeting URLs with people you trust. Plus, the person hosting the meeting has additional controls in terms of who to allow in the meeting, who can share content, etc. - use those features!&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Automated tool can find Zoom meetings&lt;/strong&gt; - Someone wrote a tool that can generate valid Zoom meeting IDs, making it easier for people to Zoombomb. Zoom should probably make their meeting IDs harder to guess, but again, password protect your meetings, and this won’t be an issue.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Zoom shares user contact info&lt;/strong&gt; - Sometimes Zoom treats email domains as company directories, and shares user info among users with the same domain. I think this is a poor design! I’m surprised this was ever released. That said, for me personally, it is a non-issue since my email address is on a well-known email domain and is excluded from the “feature.” Still, I’d like to see Zoom remove this capability.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Facebook data sharing on iOS&lt;/strong&gt; - In their iOS app, Zoom previously relied on the Facebook SDK to allow users to sign in with their Facebook account. This had a side effect of the app sharing certain device details to Facebook. I understand that people do not trust Facebook at all, but for my own usage of Zoom I’m not terribly concerned. Plus, &lt;a href=&quot;https://blog.zoom.us/wordpress/2020/03/27/zoom-use-of-facebook-sdk-in-ios-client/&quot;&gt;Zoom has issued a fix for this&lt;/a&gt;.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Lack of true E2E encryption&lt;/strong&gt; - This is a bad marketing move, with Zoom apparently saying they support end-to-end encryption when they really don’t. I never expected E2E encryption in Zoom, and the encryption which Zoom uses is good enough for me. See &lt;a href=&quot;https://blog.zoom.us/wordpress/2020/04/01/facts-around-zoom-encryption-for-meetings-webinars/&quot;&gt;Zoom’s clarification on their encryption&lt;/a&gt;.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Calls routed through China&lt;/strong&gt; - This was apparently a temporary misconfiguration on Zoom’s end where non-Chinese users had calls that connected to Zoom servers in China. Not great, but also not terribly alarming for me.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Zoom accounts found on the dark web&lt;/strong&gt; - It is unclear where the leaked account info originated. I suspect that the accounts were compromised by the usual methods (password re-use, phishing, etc.). If it came to light that Zoom is leaking account credentials that’s a much bigger concern.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Recorded Zoom videos on the web&lt;/strong&gt; - Some people record their Zoom meetings and upload them to a non-secure location on the web. Yeah, don’t share your private recordings on the public web! I almost didn’t mention this one, as it is clearly user error, but I included it since news sites are reporting on it.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;LinkedIn data-mining feature&lt;/strong&gt; - Zoom matched users to LinkedIn profiles under certain circumstances. I can see how this one is concerning, although given the audience of my Zoom meetings, it wasn’t an issue. &lt;a href=&quot;https://blog.zoom.us/wordpress/2020/04/01/a-message-to-our-users/&quot;&gt;Zoom has issued a fix for this&lt;/a&gt;.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Windows password theft&lt;/strong&gt; - Zoom was converting &lt;a href=&quot;https://www.pcmag.com/encyclopedia/term/unc&quot;&gt;UNC paths&lt;/a&gt; to clickable hyperlinks in chat. If a malicious user was in your chat, and that user posted a UNC path to an internet location, and you clicked that link, then they could steal your Windows username and password hash. Common sense: don’t click hyperlinks to untrusted servers (especially UNC links) from random users! Don’t ever do this, not just in Zoom! Also, don’t let untrusted users into your Zoom chats. &lt;a href=&quot;https://blog.zoom.us/wordpress/2020/04/01/a-message-to-our-users/&quot;&gt;Zoom has issued a fix for this&lt;/a&gt;.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Mac privilege escalation to root&lt;/strong&gt; - A local unprivileged attacker may be able to escalate their privileges to root (&lt;a href=&quot;https://objective-see.com/blog/blog_0x56.html&quot;&gt;details&lt;/a&gt;). That’s bad, but at least this is a local security issue - the attacker has to already have a foothold on the system. My personal take: I don’t use a Mac, but maybe some of the people in my calls do. &lt;a href=&quot;https://blog.zoom.us/wordpress/2020/04/01/a-message-to-our-users/&quot;&gt;Zoom has issued a fix for this&lt;/a&gt;.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Mac webcam vulnerability&lt;/strong&gt; - On a Mac, a local attacker can inject code into the Zoom process and leverage Zoom’s mic and camera access. That’s bad, but at least this is also a local security issue - the attacker has to already have a foothold on the system. &lt;a href=&quot;https://blog.zoom.us/wordpress/2020/04/01/a-message-to-our-users/&quot;&gt;Zoom has issued a fix for this&lt;/a&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3 id=&quot;keep-using-zoom&quot;&gt;Keep using Zoom?&lt;/h3&gt;

&lt;p&gt;When I look at these issues individually, none of them are a deal breaker for me. If you’re running the current version of the Zoom app, the fixes mentioned above should be automatically installed. Zoom is easy to use and people have quickly picked it up. I plan to keep using Zoom.&lt;/p&gt;

&lt;p&gt;However, looking at these issues in aggregate does  worry me. It would seem that Zoom has not historically focused on privacy and security, and so I’m concerned about what else may be lurking their code. &lt;strong&gt;I’m going to keep using Zoom for now, while keeping an eye on new issues as they arise.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;To Zoom’s credit, they are &lt;a href=&quot;https://blog.zoom.us/wordpress/2020/04/01/a-message-to-our-users/&quot;&gt;taking 90 days to fix issues and pause feature work&lt;/a&gt;. I wish their engineering team success.&lt;/p&gt;

&lt;p&gt;I’m primarily looking at these issues from a consumer perspective. If you are using Zoom in a business scenario, particularly one where confidential information is shared, your evaluation criteria will differ. If your company already has an approved solution for video conferencing - use it!&lt;/p&gt;</content><author><name>Matthew Justice</name></author><summary type="html">I keep reading news stories about how terrible Zoom is from a security and privacy standpoint. I host a weekly video call, and I’d like to use Zoom since everyone loves it, but should I be concerned about the issues recently uncovered, at least for my own use of Zoom? In this post I’m going to cover the various recent issues (using CNET’s recent article for a list of issues), and give my thoughts on each, focusing on how it matters in my own usage of Zoom.</summary></entry><entry><title type="html">Installing adb</title><link href="https://blog.mattjustice.com//2020/03/29/installing-adb/" rel="alternate" type="text/html" title="Installing adb" /><published>2020-03-29T09:04:00-04:00</published><updated>2020-03-29T09:04:00-04:00</updated><id>https://blog.mattjustice.com//2020/03/29/installing-adb</id><content type="html" xml:base="https://blog.mattjustice.com//2020/03/29/installing-adb/">&lt;p&gt;Today I wanted to diagnose a problem on my Android phone. It had been a while since I wrote any Android code, so adb wasn’t installed on my computer. I decided to just quickly install the Android command line tools, rather than the full SDK. This turned out not to be so quick after all. In the end, I had to download the tools, extract them into a particular folder hierarchy, move some files around, install Java, and set some environment variables. It’s like someone was trying to make this difficult! Here’s what worked for me on Windows 10. Maybe it will help someone else.&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Downloaded and Installed the &lt;a href=&quot;https://www.java.com/en/download/win10.jsp&quot;&gt;Java Runtime Environment&lt;/a&gt; (currently version 8 update 241).&lt;/li&gt;
  &lt;li&gt;Download the latest &lt;a href=&quot;https://developer.android.com/studio&quot;&gt;Android command line tools&lt;/a&gt;. That’s &lt;code class=&quot;highlighter-rouge&quot;&gt;commandlinetools-win-6200805_latest.zip&lt;/code&gt; at the time I’m writing this.&lt;/li&gt;
  &lt;li&gt;Extracted to &lt;code class=&quot;highlighter-rouge&quot;&gt;C:\android\cmdline-tools\latest&lt;/code&gt;, following the guidance &lt;a href=&quot;https://stackoverflow.com/questions/60440509/android-command-line-tools-sdkmanager-always-shows-warning-could-not-create-se/60454207&quot;&gt;here&lt;/a&gt;. To clarify, the downloaded zip file contained a folder named &lt;code class=&quot;highlighter-rouge&quot;&gt;tools&lt;/code&gt;, and I renamed that folder to &lt;code class=&quot;highlighter-rouge&quot;&gt;latest&lt;/code&gt; and placed it in &lt;code class=&quot;highlighter-rouge&quot;&gt;C:\android\cmdline-tools&lt;/code&gt;. Why would a specific folder structure be required? I don’t know, and I’m not taking the time now to investigate.&lt;/li&gt;
  &lt;li&gt;Followed the advice &lt;a href=&quot;https://stackoverflow.com/questions/60544671/cannot-install-sdkmanager-in-windows-10&quot;&gt;here&lt;/a&gt; and copied the files in &lt;code class=&quot;highlighter-rouge&quot;&gt;latest\lib\_&lt;/code&gt; to &lt;code class=&quot;highlighter-rouge&quot;&gt;latest\lib&lt;/code&gt;. This doesn’t feel right to me… why would the zip file include a folder structure that doesn’t work? I’m sure there’s more going on here, but for now I’m going with that works.&lt;/li&gt;
  &lt;li&gt;Added an environment variable named &lt;code class=&quot;highlighter-rouge&quot;&gt;ANDROID_HOME&lt;/code&gt; and set it to &lt;code class=&quot;highlighter-rouge&quot;&gt;C:\android\cmdline-tools\latest&lt;/code&gt;.&lt;/li&gt;
  &lt;li&gt;Added &lt;code class=&quot;highlighter-rouge&quot;&gt;%ANDROID_HOME%\bin&lt;/code&gt; to my &lt;code class=&quot;highlighter-rouge&quot;&gt;PATH&lt;/code&gt;.&lt;/li&gt;
  &lt;li&gt;Opened a cmd prompt and ran &lt;code class=&quot;highlighter-rouge&quot;&gt;sdkmanager &quot;platform-tools&quot;&lt;/code&gt;. This installed adb and more to &lt;code class=&quot;highlighter-rouge&quot;&gt;C:\android\platform-tools&lt;/code&gt;.&lt;/li&gt;
  &lt;li&gt;With my Android device connected to my PC with USB debugging enabled, checked that adb is working by running &lt;code class=&quot;highlighter-rouge&quot;&gt;adb devices&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That took more effort than I expected, but at least adb works now!&lt;/p&gt;</content><author><name>Matthew Justice</name></author><summary type="html">Today I wanted to diagnose a problem on my Android phone. It had been a while since I wrote any Android code, so adb wasn’t installed on my computer. I decided to just quickly install the Android command line tools, rather than the full SDK. This turned out not to be so quick after all. In the end, I had to download the tools, extract them into a particular folder hierarchy, move some files around, install Java, and set some environment variables. It’s like someone was trying to make this difficult! Here’s what worked for me on Windows 10. Maybe it will help someone else.</summary></entry><entry><title type="html">Migrating from WordPress.com to Jekyll and Netlify</title><link href="https://blog.mattjustice.com//2019/02/03/migrating-from-wordpress-to-jekyll-and-netlify/" rel="alternate" type="text/html" title="Migrating from WordPress.com to Jekyll and Netlify" /><published>2019-02-03T16:23:39-05:00</published><updated>2019-02-03T16:23:39-05:00</updated><id>https://blog.mattjustice.com//2019/02/03/migrating-from-wordpress-to-jekyll-and-netlify</id><content type="html" xml:base="https://blog.mattjustice.com//2019/02/03/migrating-from-wordpress-to-jekyll-and-netlify/">&lt;p&gt;When I started my personal blog in 2016 I wanted a simple solution. I built software for a living, and I didn’t want to deal with writing code for a simple blog. WordPress.com provided a good platform for this. It was $13 / year for the privilege of using my custom domain, which seemed OK. It was fine for what I needed, but after a while I got tired of the ads, and didn’t really want to pay more.&lt;/p&gt;

&lt;p&gt;Now, three years later, I’ve taken an interest in static site generation. I began reading up on &lt;a href=&quot;https://jekyllrb.com/&quot;&gt;Jekyll&lt;/a&gt;, and I liked the idea of generating a static site based on simple markdown. I also learned about &lt;a href=&quot;https://www.netlify.com/&quot;&gt;Netlify&lt;/a&gt;, and I became a fan of their continuous deployment and integration with GitHub. The idea of updating my blog by simply pushing to GitHub sealed the deal for me. I decided to migrate off WordPress.com and onto Netlify, generating my site with Jekyll and managing the code in GitHub.&lt;/p&gt;

&lt;p&gt;Turns out I was able to migrate this blog in an afternoon! Here’s how I did it; maybe this will be helpful to someone else.&lt;/p&gt;

&lt;p&gt;First, I exported the XML for my WordPress.com site using the URL below (replacing BLOGNAME with my WordPress blog’s name)&lt;/p&gt;
&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;https://BLOGNAME.wordpress.com/wp-admin/export.php
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;I then created a new GitHub repo and cloned it&lt;/p&gt;
&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$ git clone reponame
$ cd reponame
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Installed &lt;a href=&quot;https://jekyllrb.com/docs/&quot;&gt;Ruby and Jekyll&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Created a new Jekyll blog in my local copy of the repo&lt;/p&gt;
&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$ jekyll new blog
$ cd blog
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Installed jekyll-import and prerequisites&lt;/p&gt;
&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$ sudo apt-get install zlib1g-dev
$ sudo gem install hpricot
$ sudo gem install open_uri_redirections
$ sudo gem install jekyll-import
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Copied the WordPress.com XML as wordpress.xml into the new blog directory.&lt;/p&gt;

&lt;p&gt;Ran the import tool&lt;/p&gt;
&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$ ruby -r rubygems -e 'require &quot;jekyll-import&quot;;
    JekyllImport::Importers::WordpressDotCom.run({
      &quot;source&quot; =&amp;gt; &quot;wordpress.xml&quot;,
      &quot;no_fetch_images&quot; =&amp;gt; false,
      &quot;assets_folder&quot; =&amp;gt; &quot;assets&quot;
    })'
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Ran the Jekyll site locally for testing&lt;/p&gt;
&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$ bundle exec jekyll serve
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Some cleanup was required. Namely:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;In _config.yml set the following so that link URLs would be the same as the old WordPress URLs:
    &lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;permalink: /:year/:month/:day/:title/
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
  &lt;li&gt;I set the timezone in _config.yml to ensure that permalinks generated on the server would be as expected.&lt;/li&gt;
  &lt;li&gt;Many of the images were weirdly sized or positioned. I removed width and height attributes on img tags and removed unused CSS classes. I also added some CSS classes as needed.&lt;/li&gt;
  &lt;li&gt;Image galleries weren’t imported at all. I manually downloaded the missing image files and then used &lt;a href=&quot;https://stackoverflow.com/questions/17677094/jekyll-for-loop-over-all-images-in-a-folder&quot;&gt;this helpful tip&lt;/a&gt; to enumerate the images in blog post.&lt;/li&gt;
  &lt;li&gt;Certain linked files weren’t imported. I manually copied them and fixed up the links.&lt;/li&gt;
  &lt;li&gt;Comments didn’t come over either, but I only had a few so I manually copied their text. I haven’t added a means of adding new comments.&lt;/li&gt;
  &lt;li&gt;I made some minor changes to the look and feel of the site.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Once I had the site running satisfactorily locally, I pushed to GitHub and set up a new site on Netlify that deployed from GitHub. Then I switched the DNS record for blog.mattjustice.com to point to Netlify rather than WordPress.com. All pretty straightforward!&lt;/p&gt;</content><author><name>Matthew Justice</name></author><summary type="html">When I started my personal blog in 2016 I wanted a simple solution. I built software for a living, and I didn’t want to deal with writing code for a simple blog. WordPress.com provided a good platform for this. It was $13 / year for the privilege of using my custom domain, which seemed OK. It was fine for what I needed, but after a while I got tired of the ads, and didn’t really want to pay more.</summary></entry><entry><title type="html">GDB commands for WinDbg users</title><link href="https://blog.mattjustice.com//2018/08/24/gdb-for-windbg-users/" rel="alternate" type="text/html" title="GDB commands for WinDbg users" /><published>2018-08-24T22:03:01-04:00</published><updated>2018-08-24T22:03:01-04:00</updated><id>https://blog.mattjustice.com//2018/08/24/gdb-for-windbg-users</id><content type="html" xml:base="https://blog.mattjustice.com//2018/08/24/gdb-for-windbg-users/">&lt;p&gt;Most of the debugging I've done has been on Windows using WinDbg (or kd, cdb, ntsd). Now I'm doing some GDB debugging on Linux, so I'm trying overcome my muscle memory of typing WinDbg commands. I'm sharing my table for translating WinDbg commands to GDB.&lt;/p&gt;
&lt;div&gt;
&lt;table title=&quot;&quot; border=&quot;1&quot; summary=&quot;&quot; cellspacing=&quot;0&quot; cellpadding=&quot;0&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;white-space:nowrap;&quot;&gt;&lt;strong&gt;Action&lt;/strong&gt;&lt;/td&gt;
&lt;td style=&quot;white-space:nowrap;&quot;&gt;&lt;strong&gt;WinDbg&lt;/strong&gt;&lt;/td&gt;
&lt;td style=&quot;white-space:nowrap;&quot;&gt;&lt;strong&gt;GDB&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;white-space:nowrap;&quot;&gt;&lt;code style=&quot;font-size:10pt;&quot;&gt;Set breakpoint&lt;/code&gt;&lt;/td&gt;
&lt;td style=&quot;white-space:nowrap;&quot;&gt;&lt;code style=&quot;font-size:10pt;&quot;&gt;bp [addr]&lt;br /&gt;
bp [name]&lt;br /&gt;
&lt;/code&gt;&lt;/td&gt;
&lt;td style=&quot;white-space:nowrap;&quot;&gt;&lt;code style=&quot;font-size:10pt;&quot;&gt;b[reak] *[addr]&lt;br /&gt;
b[reak] [name]&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;white-space:nowrap;&quot;&gt;&lt;code style=&quot;font-size:10pt;&quot;&gt;List breakpoints&lt;/code&gt;&lt;/td&gt;
&lt;td style=&quot;white-space:nowrap;&quot;&gt;&lt;code style=&quot;font-size:10pt;&quot;&gt;bl&lt;/code&gt;&lt;/td&gt;
&lt;td style=&quot;white-space:nowrap;&quot;&gt;&lt;code style=&quot;font-size:10pt;&quot;&gt;i[nfo] b[reakpoints]&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;white-space:nowrap;&quot;&gt;&lt;code style=&quot;font-size:10pt;&quot;&gt;Enable breakpoint&lt;/code&gt;&lt;/td&gt;
&lt;td style=&quot;white-space:nowrap;&quot;&gt;&lt;code style=&quot;font-size:10pt;&quot;&gt;be [n]&lt;/code&gt;&lt;/td&gt;
&lt;td style=&quot;white-space:nowrap;&quot;&gt;&lt;code style=&quot;font-size:10pt;&quot;&gt;en[able]&lt;span style=&quot;color:#2e4453;font-family:Consolas;&quot;&gt; [n]&lt;/span&gt; &lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;white-space:nowrap;&quot;&gt;&lt;code style=&quot;font-size:10pt;&quot;&gt;Disable breakpoint&lt;/code&gt;&lt;/td&gt;
&lt;td style=&quot;white-space:nowrap;&quot;&gt;&lt;code style=&quot;font-size:10pt;&quot;&gt;bd&lt;span style=&quot;color:#2e4453;font-family:Consolas;&quot;&gt; [n]&lt;/span&gt; &lt;/code&gt;&lt;/td&gt;
&lt;td style=&quot;white-space:nowrap;&quot;&gt;&lt;code style=&quot;font-size:10pt;&quot;&gt;dis[able]&lt;span style=&quot;color:#2e4453;font-family:Consolas;&quot;&gt; [n]&lt;/span&gt; &lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;white-space:nowrap;&quot;&gt;&lt;code style=&quot;font-size:10pt;&quot;&gt;Clear one breakpoint&lt;/code&gt;&lt;/td&gt;
&lt;td style=&quot;white-space:nowrap;&quot;&gt;&lt;code style=&quot;font-size:10pt;&quot;&gt;bc [n]&lt;/code&gt;&lt;/td&gt;
&lt;td style=&quot;white-space:nowrap;&quot;&gt;&lt;code style=&quot;font-size:10pt;&quot;&gt;d[elete] [n]&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;white-space:nowrap;&quot;&gt;&lt;code style=&quot;font-size:10pt;&quot;&gt;Clear all breakpoints&lt;/code&gt;&lt;/td&gt;
&lt;td style=&quot;white-space:nowrap;&quot;&gt;&lt;code style=&quot;font-size:10pt;&quot;&gt;bc *&lt;/code&gt;&lt;/td&gt;
&lt;td style=&quot;white-space:nowrap;&quot;&gt;&lt;code style=&quot;font-size:10pt;&quot;&gt;d[elete]&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;white-space:nowrap;&quot;&gt;&lt;code style=&quot;font-size:10pt;&quot;&gt;Disassemble&lt;/code&gt;&lt;/td&gt;
&lt;td style=&quot;white-space:nowrap;&quot;&gt;&lt;code style=&quot;font-size:10pt;&quot;&gt;u&lt;br /&gt;
u [addr]&lt;/code&gt;&lt;/td&gt;
&lt;td style=&quot;white-space:nowrap;&quot;&gt;&lt;code style=&quot;font-size:10pt;&quot;&gt;disas[semble] /r&lt;br /&gt;
disas[semble] /r [addr]&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;white-space:nowrap;&quot;&gt;&lt;code style=&quot;font-size:10pt;&quot;&gt;Run&lt;/code&gt;&lt;/td&gt;
&lt;td style=&quot;white-space:nowrap;&quot;&gt;&lt;code style=&quot;font-size:10pt;&quot;&gt;g&lt;br /&gt;
g [addr]&lt;/code&gt;&lt;/td&gt;
&lt;td style=&quot;white-space:nowrap;&quot;&gt;&lt;code style=&quot;font-size:10pt;&quot;&gt;r[un]&lt;br /&gt;
sta[rt]&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;white-space:nowrap;&quot;&gt;&lt;code style=&quot;font-size:10pt;&quot;&gt;Continue&lt;/code&gt;&lt;/td&gt;
&lt;td style=&quot;white-space:nowrap;&quot;&gt;&lt;code style=&quot;font-size:10pt;&quot;&gt;g&lt;br /&gt;
gc&lt;/code&gt;&lt;/td&gt;
&lt;td style=&quot;white-space:nowrap;&quot;&gt;&lt;code style=&quot;font-size:10pt;&quot;&gt;c[ontinue]&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;white-space:nowrap;&quot;&gt;&lt;code style=&quot;font-size:10pt;&quot;&gt;Restart&lt;/code&gt;&lt;/td&gt;
&lt;td style=&quot;white-space:nowrap;&quot;&gt;&lt;code style=&quot;font-size:10pt;&quot;&gt;.restart&lt;/code&gt;&lt;/td&gt;
&lt;td style=&quot;white-space:nowrap;&quot;&gt;&lt;code style=&quot;font-size:10pt;&quot;&gt;r[un]&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;white-space:nowrap;&quot;&gt;&lt;code style=&quot;font-size:10pt;&quot;&gt;Trace (into calls)&lt;/code&gt;&lt;/td&gt;
&lt;td style=&quot;white-space:nowrap;&quot;&gt;&lt;code style=&quot;font-size:10pt;&quot;&gt;t&lt;/code&gt;&lt;/td&gt;
&lt;td style=&quot;white-space:nowrap;&quot;&gt;&lt;code style=&quot;font-size:10pt;&quot;&gt;s[tep]&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;white-space:nowrap;&quot;&gt;&lt;code style=&quot;font-size:10pt;&quot;&gt;Step (over calls)&lt;/code&gt;&lt;/td&gt;
&lt;td style=&quot;white-space:nowrap;&quot;&gt;&lt;code style=&quot;font-size:10pt;&quot;&gt;p&lt;/code&gt;&lt;/td&gt;
&lt;td style=&quot;white-space:nowrap;&quot;&gt;&lt;code style=&quot;font-size:10pt;&quot;&gt;n[ext]&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;white-space:nowrap;&quot;&gt;&lt;code style=&quot;font-size:10pt;&quot;&gt;Trace (into calls)&lt;br /&gt;
by machine instruction&lt;/code&gt;&lt;/td&gt;
&lt;td style=&quot;white-space:nowrap;&quot;&gt;&lt;code style=&quot;font-size:10pt;&quot;&gt;t&lt;/code&gt;&lt;/td&gt;
&lt;td style=&quot;white-space:nowrap;&quot;&gt;&lt;code style=&quot;font-size:10pt;&quot;&gt;s[tep]i&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;white-space:nowrap;&quot;&gt;&lt;code style=&quot;font-size:10pt;&quot;&gt;Step (over calls)&lt;br /&gt;
by machine instruction&lt;/code&gt;&lt;/td&gt;
&lt;td style=&quot;white-space:nowrap;&quot;&gt;&lt;code style=&quot;font-size:10pt;&quot;&gt;p&lt;/code&gt;&lt;/td&gt;
&lt;td style=&quot;white-space:nowrap;&quot;&gt;&lt;code style=&quot;font-size:10pt;&quot;&gt;n[ext]i&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;white-space:nowrap;&quot;&gt;&lt;code style=&quot;font-size:10pt;&quot;&gt;Toggle source mode&lt;br /&gt;
for stepping&lt;/code&gt;&lt;/td&gt;
&lt;td style=&quot;white-space:nowrap;&quot;&gt;&lt;code style=&quot;font-size:10pt;&quot;&gt;l+t&lt;br /&gt;
l-t&lt;/code&gt;&lt;/td&gt;
&lt;td style=&quot;white-space:nowrap;&quot;&gt;&lt;code style=&quot;font-size:10pt;&quot;&gt;n/a - See above.&lt;br /&gt;
(use si and ni&lt;/code&gt;)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;white-space:nowrap;&quot;&gt;&lt;code style=&quot;font-size:10pt;&quot;&gt;List modules&lt;/code&gt;&lt;/td&gt;
&lt;td style=&quot;white-space:nowrap;&quot;&gt;&lt;code style=&quot;font-size:10pt;&quot;&gt;lm&lt;/code&gt;&lt;/td&gt;
&lt;td style=&quot;white-space:nowrap;&quot;&gt;&lt;code style=&quot;font-size:10pt;&quot;&gt;i[nfo] sh[aredlibrary]&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;white-space:nowrap;&quot;&gt;&lt;code style=&quot;font-size:10pt;&quot;&gt;View registers&lt;/code&gt;&lt;/td&gt;
&lt;td style=&quot;white-space:nowrap;&quot;&gt;&lt;code style=&quot;font-size:10pt;&quot;&gt;r&lt;br /&gt;
r [name]&lt;/code&gt;&lt;/td&gt;
&lt;td style=&quot;white-space:nowrap;&quot;&gt;&lt;code style=&quot;font-size:10pt;&quot;&gt;i[nfo] r&lt;br /&gt;
i[nfo] r [name]&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;white-space:nowrap;&quot;&gt;&lt;code style=&quot;font-size:10pt;&quot;&gt;View call stack&lt;/code&gt;&lt;/td&gt;
&lt;td style=&quot;white-space:nowrap;&quot;&gt;&lt;code style=&quot;font-size:10pt;&quot;&gt;k[b|v|p]&lt;/code&gt;&lt;/td&gt;
&lt;td style=&quot;white-space:nowrap;&quot;&gt;&lt;code style=&quot;font-size:10pt;&quot;&gt;i s[tack]&lt;br /&gt;
bt f[ull]&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;white-space:nowrap;&quot;&gt;&lt;code style=&quot;font-size:10pt;&quot;&gt;View threads&lt;/code&gt;&lt;/td&gt;
&lt;td style=&quot;white-space:nowrap;&quot;&gt;&lt;code style=&quot;font-size:10pt;&quot;&gt;~&lt;/code&gt;&lt;/td&gt;
&lt;td style=&quot;white-space:nowrap;&quot;&gt;&lt;code style=&quot;font-size:10pt;&quot;&gt;i[nfo] th[reads]&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;white-space:nowrap;&quot;&gt;&lt;code style=&quot;font-size:10pt;&quot;&gt;Switch thread&lt;/code&gt;&lt;/td&gt;
&lt;td style=&quot;white-space:nowrap;&quot;&gt;&lt;code style=&quot;font-size:10pt;&quot;&gt;~[n]s&lt;/code&gt;&lt;/td&gt;
&lt;td style=&quot;white-space:nowrap;&quot;&gt;&lt;code style=&quot;font-size:10pt;&quot;&gt;thr[ead] [n]&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;white-space:nowrap;&quot;&gt;&lt;code style=&quot;font-size:10pt;&quot;&gt;View all thread stacks&lt;/code&gt;&lt;/td&gt;
&lt;td style=&quot;white-space:nowrap;&quot;&gt;&lt;code style=&quot;font-size:10pt;&quot;&gt;~*k&lt;/code&gt;&lt;/td&gt;
&lt;td style=&quot;white-space:nowrap;&quot;&gt;&lt;code style=&quot;font-size:10pt;&quot;&gt;thread apply all bt&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;white-space:nowrap;&quot;&gt;&lt;code style=&quot;font-size:10pt;&quot;&gt;Switch frame&lt;/code&gt;&lt;/td&gt;
&lt;td style=&quot;white-space:nowrap;&quot;&gt;&lt;code style=&quot;font-size:10pt;&quot;&gt;.frame [n]&lt;/code&gt;&lt;/td&gt;
&lt;td style=&quot;white-space:nowrap;&quot;&gt;&lt;code style=&quot;font-size:10pt;&quot;&gt;f[rame] [n]&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;white-space:nowrap;&quot;&gt;&lt;code style=&quot;font-size:10pt;&quot;&gt;View memory (8 bytes)&lt;/code&gt;&lt;/td&gt;
&lt;td style=&quot;white-space:nowrap;&quot;&gt;&lt;code style=&quot;font-size:10pt;&quot;&gt;dq [addr] L[n]&lt;/code&gt;&lt;/td&gt;
&lt;td style=&quot;white-space:nowrap;&quot;&gt;&lt;code style=&quot;font-size:10pt;&quot;&gt;x/[n]xg [addr]&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;white-space:nowrap;&quot;&gt;&lt;code style=&quot;font-size:10pt;&quot;&gt;View memory (4 bytes)&lt;/code&gt;&lt;/td&gt;
&lt;td style=&quot;white-space:nowrap;&quot;&gt;&lt;code style=&quot;font-size:10pt;&quot;&gt;dd [addr] L[n]&lt;/code&gt;&lt;/td&gt;
&lt;td style=&quot;white-space:nowrap;&quot;&gt;&lt;code style=&quot;font-size:10pt;&quot;&gt;x/[n]xw [addr]&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;white-space:nowrap;&quot;&gt;&lt;code style=&quot;font-size:10pt;&quot;&gt;View memory (2 bytes)&lt;/code&gt;&lt;/td&gt;
&lt;td style=&quot;white-space:nowrap;&quot;&gt;&lt;code style=&quot;font-size:10pt;&quot;&gt;dw [addr] L[n]&lt;/code&gt;&lt;/td&gt;
&lt;td style=&quot;white-space:nowrap;&quot;&gt;&lt;code style=&quot;font-size:10pt;&quot;&gt;x/[n]xh [addr]&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;white-space:nowrap;&quot;&gt;&lt;code style=&quot;font-size:10pt;&quot;&gt;View memory (1 byte)&lt;/code&gt;&lt;/td&gt;
&lt;td style=&quot;white-space:nowrap;&quot;&gt;&lt;code style=&quot;font-size:10pt;&quot;&gt;db [addr] L[n]&lt;/code&gt;&lt;/td&gt;
&lt;td style=&quot;white-space:nowrap;&quot;&gt;&lt;code style=&quot;font-size:10pt;&quot;&gt;x/[n]xb [addr]&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;white-space:nowrap;&quot;&gt;&lt;code style=&quot;font-size:10pt;&quot;&gt;View memory (ascii)&lt;/code&gt;&lt;/td&gt;
&lt;td style=&quot;white-space:nowrap;&quot;&gt;&lt;code style=&quot;font-size:10pt;&quot;&gt;da [addr] L[n]&lt;/code&gt;&lt;/td&gt;
&lt;td style=&quot;white-space:nowrap;&quot;&gt;&lt;code style=&quot;font-size:10pt;&quot;&gt;p[rint] (char*)[addr]&lt;br /&gt;
x/s [addr]&lt;br /&gt;
x/20c [addr]&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;white-space:nowrap;&quot;&gt;&lt;code style=&quot;font-size:10pt;&quot;&gt;View memory (stacked)&lt;/code&gt;&lt;/td&gt;
&lt;td style=&quot;white-space:nowrap;&quot;&gt;&lt;code style=&quot;font-size:10pt;&quot;&gt;dds [addr] L[n]&lt;/code&gt;&lt;/td&gt;
&lt;td style=&quot;white-space:nowrap;&quot;&gt;&lt;code style=&quot;font-size:10pt;&quot;&gt;x/xw [addr]&lt;br /&gt;
repeat Enter key&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;white-space:nowrap;&quot;&gt;&lt;code style=&quot;font-size:10pt;&quot;&gt;View local variables&lt;/code&gt;&lt;/td&gt;
&lt;td style=&quot;white-space:nowrap;&quot;&gt;&lt;code style=&quot;font-size:10pt;&quot;&gt;dv /v&lt;br /&gt;
x&lt;/code&gt;&lt;/td&gt;
&lt;td style=&quot;white-space:nowrap;&quot;&gt;&lt;code style=&quot;font-size:10pt;&quot;&gt;&lt;code style=&quot;font-size:10pt;&quot;&gt;i[nfo] lo[cals]&lt;br /&gt;
print [var_name]&lt;br /&gt;
x &amp;amp;[var_name]&lt;/code&gt;&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;white-space:nowrap;&quot;&gt;&lt;code style=&quot;font-size:10pt;&quot;&gt;View global variables&lt;/code&gt;&lt;/td&gt;
&lt;td style=&quot;white-space:nowrap;&quot;&gt;&lt;code style=&quot;font-size:10pt;&quot;&gt;x [mod]!*&lt;/code&gt;&lt;/td&gt;
&lt;td style=&quot;white-space:nowrap;&quot;&gt;&lt;code style=&quot;font-size:10pt;&quot;&gt;i[nfo] va[riables]&lt;br /&gt;
info address [g_name]&lt;br /&gt;
print [g_name]&lt;br /&gt;
x &amp;amp;[g_name]&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;white-space:nowrap;&quot;&gt;&lt;code style=&quot;font-size:10pt;&quot;&gt;View frame args&lt;/code&gt;&lt;/td&gt;
&lt;td style=&quot;white-space:nowrap;&quot;&gt;&lt;code style=&quot;font-size:10pt;&quot;&gt;x&lt;br /&gt;
kP L1&lt;/code&gt;&lt;/td&gt;
&lt;td style=&quot;white-space:nowrap;&quot;&gt;&lt;code style=&quot;font-size:10pt;&quot;&gt;i[nfo] ar[gs]&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;white-space:nowrap;&quot;&gt;&lt;code style=&quot;font-size:10pt;&quot;&gt;View type&lt;/code&gt;&lt;/td&gt;
&lt;td style=&quot;white-space:nowrap;&quot;&gt;&lt;code style=&quot;font-size:10pt;&quot;&gt;dt [type]&lt;/code&gt;&lt;/td&gt;
&lt;td style=&quot;white-space:nowrap;&quot;&gt;&lt;code style=&quot;font-size:10pt;&quot;&gt;explore [type]&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;white-space:nowrap;&quot;&gt;&lt;code style=&quot;font-size:10pt;&quot;&gt;Break on syscall&lt;/code&gt;&lt;/td&gt;
&lt;td style=&quot;white-space:nowrap;&quot;&gt;&lt;/td&gt;
&lt;td style=&quot;white-space:nowrap;&quot;&gt;&lt;code style=&quot;font-size:10pt;&quot;&gt;catch syscall [i]&lt;br /&gt;
catch syscall [name]&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;white-space:nowrap;&quot;&gt;&lt;code style=&quot;font-size:10pt;&quot;&gt;Set register&lt;/code&gt;&lt;/td&gt;
&lt;td style=&quot;white-space:nowrap;&quot;&gt;&lt;code style=&quot;font-size:10pt;&quot;&gt;r [name]=[value]&lt;/code&gt;&lt;/td&gt;
&lt;td style=&quot;white-space:nowrap;&quot;&gt;&lt;code style=&quot;font-size:10pt;&quot;&gt;set $[name]=[value]&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;white-space:nowrap;&quot;&gt;&lt;code style=&quot;font-size:10pt;&quot;&gt;Evaluate&lt;/code&gt;&lt;/td&gt;
&lt;td style=&quot;white-space:nowrap;&quot;&gt;&lt;code style=&quot;font-size:10pt;&quot;&gt;? [expr]&lt;br /&gt;
e.g. ? rax+5&lt;/code&gt;&lt;/td&gt;
&lt;td style=&quot;white-space:nowrap;&quot;&gt;&lt;code style=&quot;font-size:10pt;&quot;&gt;p [expr]&lt;br /&gt;
e.g. p $r11+5&lt;br /&gt;
&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;white-space:nowrap;&quot;&gt;&lt;code style=&quot;font-size:10pt;&quot;&gt;Quit&lt;/code&gt;&lt;/td&gt;
&lt;td style=&quot;white-space:nowrap;&quot;&gt;&lt;code style=&quot;font-size:10pt;&quot;&gt;q&lt;/code&gt;&lt;/td&gt;
&lt;td style=&quot;white-space:nowrap;&quot;&gt;&lt;code style=&quot;font-size:10pt;&quot;&gt;q&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;p&gt;Notes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;GDB: Prefix breakpoint memory addresses with *&lt;/li&gt;
&lt;li&gt;GDB: &quot;&lt;code&gt;set disassembly-flavor intel&lt;/code&gt;&quot; for disassembly more like WinDbg&lt;/li&gt;
&lt;li&gt;GDB: &quot;&lt;code&gt;start&lt;/code&gt;&quot; runs to the entry point (if named &quot;main&quot;)&lt;/li&gt;
&lt;li&gt;In the View memory commands, &quot;&lt;code&gt;n&lt;/code&gt;&quot; represents the number of values&lt;/li&gt;
&lt;li&gt;For viewing local variables, be sure to compile with symbolic information:
&lt;ul&gt;
&lt;li style=&quot;list-style-type:none;&quot;&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;gcc -g&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;cl /Zi&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt; &lt;/li&gt;
&lt;/ul&gt;</content><author><name>Matthew Justice</name></author><category term="Code" /><category term="Debugging" /><category term="Dev" /><category term="GDB" /><category term="Linux" /><category term="WinDbg" /><summary type="html">Most of the debugging I've done has been on Windows using WinDbg (or kd, cdb, ntsd). Now I'm doing some GDB debugging on Linux, so I'm trying overcome my muscle memory of typing WinDbg commands. I'm sharing my table for translating WinDbg commands to GDB. Action WinDbg GDB Set breakpoint bp [addr] bp [name] b[reak] *[addr] b[reak] [name] List breakpoints bl i[nfo] b[reakpoints] Enable breakpoint be [n] en[able] [n] Disable breakpoint bd [n] dis[able] [n] Clear one breakpoint bc [n] d[elete] [n] Clear all breakpoints bc * d[elete] Disassemble u u [addr] disas[semble] /r disas[semble] /r [addr] Run g g [addr] r[un] sta[rt] Continue g gc c[ontinue] Restart .restart r[un] Trace (into calls) t s[tep] Step (over calls) p n[ext] Trace (into calls) by machine instruction t s[tep]i Step (over calls) by machine instruction p n[ext]i Toggle source mode for stepping l+t l-t n/a - See above. (use si and ni) List modules lm i[nfo] sh[aredlibrary] View registers r r [name] i[nfo] r i[nfo] r [name] View call stack k[b|v|p] i s[tack] bt f[ull] View threads ~ i[nfo] th[reads] Switch thread ~[n]s thr[ead] [n] View all thread stacks ~*k thread apply all bt Switch frame .frame [n] f[rame] [n] View memory (8 bytes) dq [addr] L[n] x/[n]xg [addr] View memory (4 bytes) dd [addr] L[n] x/[n]xw [addr] View memory (2 bytes) dw [addr] L[n] x/[n]xh [addr] View memory (1 byte) db [addr] L[n] x/[n]xb [addr] View memory (ascii) da [addr] L[n] p[rint] (char*)[addr] x/s [addr] x/20c [addr] View memory (stacked) dds [addr] L[n] x/xw [addr] repeat Enter key View local variables dv /v x i[nfo] lo[cals] print [var_name] x &amp;amp;[var_name] View global variables x [mod]!* i[nfo] va[riables] info address [g_name] print [g_name] x &amp;amp;[g_name] View frame args x kP L1 i[nfo] ar[gs] View type dt [type] explore [type] Break on syscall catch syscall [i] catch syscall [name] Set register r [name]=[value] set $[name]=[value] Evaluate ? [expr] e.g. ? rax+5 p [expr] e.g. p $r11+5 Quit q q Notes: GDB: Prefix breakpoint memory addresses with * GDB: &quot;set disassembly-flavor intel&quot; for disassembly more like WinDbg GDB: &quot;start&quot; runs to the entry point (if named &quot;main&quot;) In the View memory commands, &quot;n&quot; represents the number of values For viewing local variables, be sure to compile with symbolic information: gcc -g cl /Zi  </summary></entry><entry><title type="html">The Desktop Heap Guy</title><link href="https://blog.mattjustice.com//2018/07/26/the-desktop-heap-guy/" rel="alternate" type="text/html" title="The Desktop Heap Guy" /><published>2018-07-26T11:14:50-04:00</published><updated>2018-07-26T11:14:50-04:00</updated><id>https://blog.mattjustice.com//2018/07/26/the-desktop-heap-guy</id><content type="html" xml:base="https://blog.mattjustice.com//2018/07/26/the-desktop-heap-guy/">&lt;p&gt;When I worked at Microsoft as an Escalation Engineer, I spent my days analyzing various failures in Windows. My team was called CPR, Critical Problem Resolution, and we were there to debug issues discovered in Windows by Microsoft's customers. These problems came to my team because they were either &quot;critical situations&quot; for a business customer, or because the issue was particularly technically challenging.&lt;/p&gt;
&lt;p&gt;In this role I worked on all kinds of weird failures, but one type of issue became a regular thing for me: desktop heap failures. I didn't set out to be an expert on desktop heap, but when a more senior engineer on my team decided that someone else needed to understand desktop heap, I was asked to become the subject matter expert.&lt;/p&gt;
&lt;p&gt;I started investigating every customer case that looked like the root cause might be a desktop heap failure. The symptoms were usually one of two things:&lt;/p&gt;
&lt;p&gt;1. Processes would fail to start altogether.&lt;br /&gt;
2. An application would run but certain windows would fail to display.&lt;/p&gt;
&lt;p&gt;This was perplexing for users and developers alike. The underlying cause wasn't obvious, and the same software that had previously worked without issue would suddenly start failing. There was already some limited documentation on this problem, including a KB article, but I needed more information if I was going to really understand the problem and help customers.&lt;/p&gt;
&lt;p&gt;I quickly learned that only a handful of people at Microsoft actually knew anything about desktop heap! So I studied the Windows source code, reached out to some other engineers on the Windows team, and began to pull together an understanding of the problem. I continued to get involved with every reported desktop heap failure, and eventually I became the unofficial &lt;strong&gt;Desktop Heap Guy&lt;/strong&gt;. Within Microsoft support, people had learned that there was this person who actually wanted to help with desktop heap issues! This of course led to me getting even more cases to investigate.&lt;/p&gt;
&lt;p&gt;Eventually I decided that we really needed some documentation on desktop heap. This led to me writing series of &lt;a href=&quot;https://docs.microsoft.com/en-us/archive/blogs/ntdebugging/desktop-heap-overview&quot;&gt;blog posts&lt;/a&gt;, and recording a &lt;a href=&quot;https://channel9.msdn.com/Blogs/jeff_dailey/ntdebugging-blog-talk-about-on-desktop-heap&quot;&gt;Channel 9 video&lt;/a&gt;. Even better, changes were made to the memory manager in Windows Vista and Windows Server 2008 that helped avoid the problem altogether, and the problem mostly became of thing of the past. Even so, for years after I left the Escalation Engineer role at Microsoft I would still get questions about desktop heap. Once the Desktop Heap Guy, always the Desktop Heap Guy, I guess!&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/assets/images/explaining_desktop_heap.jpg&quot; alt=&quot;explaining_desktop_heap&quot; /&gt;That's me, explaining desktop heap in 2007&lt;/p&gt;</content><author><name>Matthew Justice</name></author><category term="Dev" /><category term="Microsoft" /><category term="Windows" /><summary type="html">When I worked at Microsoft as an Escalation Engineer, I spent my days analyzing various failures in Windows. My team was called CPR, Critical Problem Resolution, and we were there to debug issues discovered in Windows by Microsoft's customers. These problems came to my team because they were either &quot;critical situations&quot; for a business customer, or because the issue was particularly technically challenging. In this role I worked on all kinds of weird failures, but one type of issue became a regular thing for me: desktop heap failures. I didn't set out to be an expert on desktop heap, but when a more senior engineer on my team decided that someone else needed to understand desktop heap, I was asked to become the subject matter expert. I started investigating every customer case that looked like the root cause might be a desktop heap failure. The symptoms were usually one of two things: 1. Processes would fail to start altogether. 2. An application would run but certain windows would fail to display. This was perplexing for users and developers alike. The underlying cause wasn't obvious, and the same software that had previously worked without issue would suddenly start failing. There was already some limited documentation on this problem, including a KB article, but I needed more information if I was going to really understand the problem and help customers. I quickly learned that only a handful of people at Microsoft actually knew anything about desktop heap! So I studied the Windows source code, reached out to some other engineers on the Windows team, and began to pull together an understanding of the problem. I continued to get involved with every reported desktop heap failure, and eventually I became the unofficial Desktop Heap Guy. Within Microsoft support, people had learned that there was this person who actually wanted to help with desktop heap issues! This of course led to me getting even more cases to investigate. Eventually I decided that we really needed some documentation on desktop heap. This led to me writing series of blog posts, and recording a Channel 9 video. Even better, changes were made to the memory manager in Windows Vista and Windows Server 2008 that helped avoid the problem altogether, and the problem mostly became of thing of the past. Even so, for years after I left the Escalation Engineer role at Microsoft I would still get questions about desktop heap. Once the Desktop Heap Guy, always the Desktop Heap Guy, I guess! That's me, explaining desktop heap in 2007</summary></entry><entry><title type="html">Handy MCU Infinity Stones Worksheet</title><link href="https://blog.mattjustice.com//2018/07/19/handy-mcu-infinity-stones-worksheet/" rel="alternate" type="text/html" title="Handy MCU Infinity Stones Worksheet" /><published>2018-07-19T11:38:37-04:00</published><updated>2018-07-19T11:38:37-04:00</updated><id>https://blog.mattjustice.com//2018/07/19/handy-mcu-infinity-stones-worksheet</id><content type="html" xml:base="https://blog.mattjustice.com//2018/07/19/handy-mcu-infinity-stones-worksheet/">&lt;p&gt;I'm watching the Marvel Cinematic Universe films with my older kids, 
  and we are tracking the infinity stones as they appear. To help with this, 
  I made an
  &lt;a title=&quot;mcu_infinity_stones_worksheet&quot; href=&quot;/assets/files/mcu_infinity_stones_worksheet.pdf&quot;&gt;Infinity Stones Worksheet&lt;/a&gt; 
  for them and an
  &lt;a title=&quot;mcu_infinity_stones_answer_key&quot; href=&quot;/assets/files/mcu_infinity_stones_answer_key.pdf&quot;&gt;answer key&lt;/a&gt; 
  for me. Enjoy!&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;</content><author><name>Matthew Justice</name></author><category term="MCU" /><summary type="html">I'm watching the Marvel Cinematic Universe films with my older kids, and we are tracking the infinity stones as they appear. To help with this, I made an Infinity Stones Worksheet for them and an answer key for me. Enjoy! &amp;nbsp;</summary></entry><entry><title type="html">Luke Skywalker Needs a Wife</title><link href="https://blog.mattjustice.com//2017/12/21/luke-skywalker-needs-a-wife/" rel="alternate" type="text/html" title="Luke Skywalker Needs a Wife" /><published>2017-12-21T09:29:43-05:00</published><updated>2017-12-21T09:29:43-05:00</updated><id>https://blog.mattjustice.com//2017/12/21/luke-skywalker-needs-a-wife</id><content type="html" xml:base="https://blog.mattjustice.com//2017/12/21/luke-skywalker-needs-a-wife/">&lt;p&gt;&lt;img src=&quot;/assets/images/luke_wife_blog.jpg&quot; alt=&quot;luke_wife_blog&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Star Wars: The Last Jedi&lt;/em&gt; was beautifully filmed and full of surprises. I enjoyed the film, but it had some issues. There's a lot I could say about it, but for now I want to talk about one character: Luke Skywalker. When we met Luke in the original trilogy, he was full of hope, willing to rush off to save his friends, and ready to confront evil on the slim chance that he could redeem his father. Luke didn't give up easily. Who is this guy in &lt;em&gt;The Last Jedi&lt;/em&gt;? Scared, in hiding, selfish. Sure, he arguably gets his act together by the end of the movie, but really, I'm disappointed in you, Luke.&lt;/p&gt;
&lt;p&gt;While discussing this with my spouse, it became clear what went wrong with this version of Luke. He needs a wife! Specifically, he needs &lt;a href=&quot;https://en.wikipedia.org/wiki/Mara_Jade&quot;&gt;Mara Jade&lt;/a&gt;! Would Mara have allowed Luke to wallow in self-pity? No, she would have kicked him in the head and said &quot;Get up farm boy; you are better than this!&quot; Would Mara Jade have let Luke's nephew to go dark without confronting him? No! She would have ambushed him in her StealthX starfighter and fought him in the &lt;a href=&quot;http://starwars.wikia.com/wiki/Skirmish_on_Kavan&quot;&gt;tunnels of Kavan&lt;/a&gt;! OK, that's a very specific reference and it didn't end well, but you get the idea! Would Luke have been so self-centered if he had a wife? Of course not! Would Mara have allowed Luke to seemingly waste 30 years after the battle of Endor? No, she would have pushed him, challenged him, and made very sure he was able to continue the Jedi Order!&lt;/p&gt;
&lt;p&gt;Life is so much better with an awesome wife. Poor Luke in &lt;em&gt;The Last Jedi&lt;/em&gt;; if only he had a wife.&lt;/p&gt;

&lt;h3&gt;Comments&lt;/h3&gt;

&lt;div class=&quot;comment-header&quot;&gt;
    &lt;span class=&quot;comment-username&quot;&gt;David Cole&lt;/span&gt;
  - &lt;span class=&quot;comment-date&quot;&gt;December 21, 2017 at 5:35 PM&lt;/span&gt;
&lt;/div&gt;
&lt;div class=&quot;comment-text&quot;&gt;
    ***spoilers***
  &lt;br&gt;&lt;br&gt;
    With all the push for more strong female characters in Star Wars, it’s really very surprising that Mara Jade has been seemingly completely deleted. Also while I enjoyed The Last Jedi, I really feel like it has jumped the shark. They’re going to have to shock me in the next trailer to get me excited for the third installment the way I was about this one. While Rey, Finn, Po, and Kylo Ren are interesting characters, I just don’t feel the same interest in their fates as I did with Han, Leia, and especially Luke. And while, yes, they gave him one of the most epic last stands anyone could have wished for, the fact that his story is “done” has me really scratching my head about what I can get excited about in the next movie.
&lt;/div&gt;

&lt;div class=&quot;comment-header&quot;&gt;
    &lt;span class=&quot;comment-username&quot;&gt;Matthew Justice&lt;/span&gt;
  - &lt;span class=&quot;comment-date&quot;&gt;December 21, 2017 at 8:52 PM&lt;/span&gt;
&lt;/div&gt;
&lt;div class=&quot;comment-text&quot;&gt;
    Yes, I have similar feelings about it. Interesting choices were made to leave TFA’s “mystery boxes” unopened (or opened with nothing inside), and then wrap up things as they did.
&lt;/div&gt;</content><author><name>Matthew Justice</name></author><category term="StarWars" /><summary type="html">Star Wars: The Last Jedi was beautifully filmed and full of surprises. I enjoyed the film, but it had some issues. There's a lot I could say about it, but for now I want to talk about one character: Luke Skywalker. When we met Luke in the original trilogy, he was full of hope, willing to rush off to save his friends, and ready to confront evil on the slim chance that he could redeem his father. Luke didn't give up easily. Who is this guy in The Last Jedi? Scared, in hiding, selfish. Sure, he arguably gets his act together by the end of the movie, but really, I'm disappointed in you, Luke. While discussing this with my spouse, it became clear what went wrong with this version of Luke. He needs a wife! Specifically, he needs Mara Jade! Would Mara have allowed Luke to wallow in self-pity? No, she would have kicked him in the head and said &quot;Get up farm boy; you are better than this!&quot; Would Mara Jade have let Luke's nephew to go dark without confronting him? No! She would have ambushed him in her StealthX starfighter and fought him in the tunnels of Kavan! OK, that's a very specific reference and it didn't end well, but you get the idea! Would Luke have been so self-centered if he had a wife? Of course not! Would Mara have allowed Luke to seemingly waste 30 years after the battle of Endor? No, she would have pushed him, challenged him, and made very sure he was able to continue the Jedi Order! Life is so much better with an awesome wife. Poor Luke in The Last Jedi; if only he had a wife.</summary></entry><entry><title type="html">Why I’m leaving my job at Microsoft</title><link href="https://blog.mattjustice.com//2017/11/26/why-im-leaving-my-job-at-microsoft/" rel="alternate" type="text/html" title="Why I'm leaving my job at Microsoft" /><published>2017-11-26T20:28:19-05:00</published><updated>2017-11-26T20:28:19-05:00</updated><id>https://blog.mattjustice.com//2017/11/26/why-im-leaving-my-job-at-microsoft</id><content type="html" xml:base="https://blog.mattjustice.com//2017/11/26/why-im-leaving-my-job-at-microsoft/">&lt;p&gt;My last day working at Microsoft will be December 1, 2017. I'm not taking another job right away. Instead, I'm blocking off time to pray, to invest in my family, to study, and to work on some projects. As I've shared this news in recent weeks, I sometimes get confused looks. &quot;Why?&quot; is the general question. &quot;Why leave a perfectly good job with no other work lined up?&quot; Great question! What follows is my answer.&lt;/p&gt;
&lt;p&gt;I began working at Microsoft in the fall of 2000, a few months after finishing a degree in Electrical Engineering from the University of Tennessee. My first role was as a Support Engineer for Windows. I can easily remember how excited I was to get this job! Microsoft was the only software company I interviewed with; all the other companies I considered were hardware-focused, which was more aligned with my education. And yet… &lt;i&gt;Microsoft&lt;/i&gt;… what an opportunity! This was a company that was changing the world, and I wanted to be a part of it.&lt;/p&gt;
&lt;p&gt;Over the next 17 years my career at Microsoft as a software engineer took a variety of interesting turns. Some highlights: I debugged Windows and worked on hotfixes, helped develop &quot;Fix it&quot;, led a team of engineers who built diagnostic tools and services, and led an engineering team building services for Microsoft's financial systems. Through all of this I found that not only is Microsoft a place to do incredible technical work, but perhaps more importantly the &lt;i&gt;people&lt;/i&gt; at this company are amazing. They are intelligent, technical, collaborative, driven… these are my kind of people, and I've learned so much from them over the years.&lt;/p&gt;
&lt;p&gt;Why would I want to leave a company like that? There are actually several reasons, but when distilled down it comes to one thing: I want to be &lt;b&gt;intentional&lt;/b&gt;. Microsoft has been incredible, but I came to realize that I've allowed myself to be swept along in my career, taking each opportunity as it came, without stopping to consider where I'm going.&lt;/p&gt;
&lt;p&gt;I'm choosing to be &lt;b&gt;intentional in how I spend time with my family&lt;/b&gt;. My wife and children are the most important people in my life, and they deserve more of my time and attention than they have received in recent years. As I've taken on more responsibility at work I've found it increasingly difficult to maintain a healthy work / life balance (or just &quot;life balance&quot; as a leader I respect calls it). Right now, all four of my kids are at home, and I've come to realize just how precious, and limited, this time is. It won't be long before my oldest kids are in college. If I wait until normal retirement age to take a career break, my kids will be grown. I'm choosing to spend time with them &lt;i&gt;now&lt;/i&gt;, even if it means I have to work more years overall.&lt;/p&gt;
&lt;p&gt;I'm choosing to be &lt;b&gt;intentional in what work I do&lt;/b&gt;. Software engineering has been a good fit for me, but right now I've lost much of my passion for it. I still have a love of technology, but I'm no longer excited about the day to day details of my work. As a manager at Microsoft, I cannot lead effectively if I'm not genuinely excited and passionate about my team's work. I have other interests and abilities outside of software, and I plan to use my time to study and grow those skills, and consider other career paths. Or perhaps doing so will lead me back to software engineering as my true calling, and I will be happy in the knowledge that I took the time to make a deliberate career choice.&lt;/p&gt;
&lt;p&gt;I'm choosing to be &lt;b&gt;intentional in how I seek after God&lt;/b&gt;. I'm a Christian, but too often I trust in my own abilities rather than in God. I make too many decisions just based on my own logic, and not on faith. As I leave my job and step out of the comfort of regular income and a clear plan for my career, my intent is to be more deliberate in the time I spend in prayer and study of the Bible, seeking God in how I may be involved with the work of his kingdom.&lt;/p&gt;
&lt;p&gt;All of that said, I realize that leaving full-time employment is not a prerequisite for being intentional! However, as mentioned above, I need a change. While I could jump to another similar position at Microsoft or elsewhere, in doing so I would miss the opportunity to pause, fully consider what is next, invest in my family, and seek God.&lt;/p&gt;
&lt;p&gt;I'm thankful that I had the chance to work at Microsoft; it truly is a great company full of exceptional people. I don't take my decision to leave such an organization lightly, and I recognize that I am blessed to even have the option to take time off from regular work. I plan to make the most of the opportunity!&lt;/p&gt;

&lt;h3&gt;Comments&lt;/h3&gt;

&lt;div class=&quot;comment-header&quot;&gt;
    &lt;span class=&quot;comment-username&quot;&gt;mrwhiskernc&lt;/span&gt;
  - &lt;span class=&quot;comment-date&quot;&gt;November 30, 2017 at 9:24 PM&lt;/span&gt;
&lt;/div&gt;
&lt;div class=&quot;comment-text&quot;&gt;Proud Dad here.&lt;/div&gt;

&lt;div class=&quot;comment-header&quot;&gt;
    &lt;span class=&quot;comment-username&quot;&gt;Aritra DattaGupta&lt;/span&gt;
  - &lt;span class=&quot;comment-date&quot;&gt;November 30, 2017 at 9:51 PM&lt;/span&gt;
&lt;/div&gt;
&lt;div class=&quot;comment-text&quot;&gt;
    Matt,
    It was really a pleasure getting to know you, to work for you and with you (albeit briefly). I hope our paths cross again soon and as I told you earlier as well, I would love to work with you again.
&lt;/div&gt;

&lt;div class=&quot;comment-header&quot;&gt;
    &lt;span class=&quot;comment-username&quot;&gt;Oneibus&lt;/span&gt;
  - &lt;span class=&quot;comment-date&quot;&gt;December 1, 2017 at 1:00 AM&lt;/span&gt;
&lt;/div&gt;
&lt;div class=&quot;comment-text&quot;&gt;
    Thank you Matthew for all you have done for me! You are one of the finest people with which I have ever had the privilege to work. I feel even more honored to call you my friend. I hope our work paths cross again some day. Best of everything to you and the family and enjoy the journey! 🙂
&lt;/div&gt;

&lt;div class=&quot;comment-header&quot;&gt;
    &lt;span class=&quot;comment-username&quot;&gt;Rebecca Christianson&lt;/span&gt;
  - &lt;span class=&quot;comment-date&quot;&gt;December 1, 2017 at 1:00 AM&lt;/span&gt;
&lt;/div&gt;
&lt;div class=&quot;comment-text&quot;&gt;
    Good luck in your new adventures, Matthew! You never know, our paths may cross again someday. Take care of yourself and your family.
&lt;/div&gt;

&lt;div class=&quot;comment-header&quot;&gt;
    &lt;span class=&quot;comment-username&quot;&gt;Carl&lt;/span&gt;
  - &lt;span class=&quot;comment-date&quot;&gt;December 1, 2017 at 11:10 PM&lt;/span&gt;
&lt;/div&gt;
&lt;div class=&quot;comment-text&quot;&gt;
    Good luck to you sir. I learned a lot from you many moons ago, and it was a pleasure to work with you. Hopefully whatever you choose will give you newfound happiness and purpose.
&lt;/div&gt;

&lt;div class=&quot;comment-header&quot;&gt;
    &lt;span class=&quot;comment-username&quot;&gt;Vidyadhar&lt;/span&gt;
  - &lt;span class=&quot;comment-date&quot;&gt;December 3, 2017 at 4:03 PM&lt;/span&gt;
&lt;/div&gt;
&lt;div class=&quot;comment-text&quot;&gt;
    Though it was very short period compared to long journey at Microsoft, your leadership will be missed at work. But, one of your ‘Intention’ with family is so true that many of the software geeks are already in the mode of ‘life as it takes’. It takes lot of courage to take such an important decision. Good luck with all new paths you would take!
&lt;/div&gt;</content><author><name>Matthew Justice</name></author><summary type="html">My last day working at Microsoft will be December 1, 2017. I'm not taking another job right away. Instead, I'm blocking off time to pray, to invest in my family, to study, and to work on some projects. As I've shared this news in recent weeks, I sometimes get confused looks. &quot;Why?&quot; is the general question. &quot;Why leave a perfectly good job with no other work lined up?&quot; Great question! What follows is my answer. I began working at Microsoft in the fall of 2000, a few months after finishing a degree in Electrical Engineering from the University of Tennessee. My first role was as a Support Engineer for Windows. I can easily remember how excited I was to get this job! Microsoft was the only software company I interviewed with; all the other companies I considered were hardware-focused, which was more aligned with my education. And yet… Microsoft… what an opportunity! This was a company that was changing the world, and I wanted to be a part of it. Over the next 17 years my career at Microsoft as a software engineer took a variety of interesting turns. Some highlights: I debugged Windows and worked on hotfixes, helped develop &quot;Fix it&quot;, led a team of engineers who built diagnostic tools and services, and led an engineering team building services for Microsoft's financial systems. Through all of this I found that not only is Microsoft a place to do incredible technical work, but perhaps more importantly the people at this company are amazing. They are intelligent, technical, collaborative, driven… these are my kind of people, and I've learned so much from them over the years. Why would I want to leave a company like that? There are actually several reasons, but when distilled down it comes to one thing: I want to be intentional. Microsoft has been incredible, but I came to realize that I've allowed myself to be swept along in my career, taking each opportunity as it came, without stopping to consider where I'm going. I'm choosing to be intentional in how I spend time with my family. My wife and children are the most important people in my life, and they deserve more of my time and attention than they have received in recent years. As I've taken on more responsibility at work I've found it increasingly difficult to maintain a healthy work / life balance (or just &quot;life balance&quot; as a leader I respect calls it). Right now, all four of my kids are at home, and I've come to realize just how precious, and limited, this time is. It won't be long before my oldest kids are in college. If I wait until normal retirement age to take a career break, my kids will be grown. I'm choosing to spend time with them now, even if it means I have to work more years overall. I'm choosing to be intentional in what work I do. Software engineering has been a good fit for me, but right now I've lost much of my passion for it. I still have a love of technology, but I'm no longer excited about the day to day details of my work. As a manager at Microsoft, I cannot lead effectively if I'm not genuinely excited and passionate about my team's work. I have other interests and abilities outside of software, and I plan to use my time to study and grow those skills, and consider other career paths. Or perhaps doing so will lead me back to software engineering as my true calling, and I will be happy in the knowledge that I took the time to make a deliberate career choice. I'm choosing to be intentional in how I seek after God. I'm a Christian, but too often I trust in my own abilities rather than in God. I make too many decisions just based on my own logic, and not on faith. As I leave my job and step out of the comfort of regular income and a clear plan for my career, my intent is to be more deliberate in the time I spend in prayer and study of the Bible, seeking God in how I may be involved with the work of his kingdom. All of that said, I realize that leaving full-time employment is not a prerequisite for being intentional! However, as mentioned above, I need a change. While I could jump to another similar position at Microsoft or elsewhere, in doing so I would miss the opportunity to pause, fully consider what is next, invest in my family, and seek God. I'm thankful that I had the chance to work at Microsoft; it truly is a great company full of exceptional people. I don't take my decision to leave such an organization lightly, and I recognize that I am blessed to even have the option to take time off from regular work. I plan to make the most of the opportunity!</summary></entry></feed>