To improve the existing workflow for receiving crash reports from Q/A, I created a crash report server built for Unreal Engine. Doing so allowed for a vast improvement in being able to diagnose and fix crashes.
I first began with reading through the engine source code and tracked down where the Unreal client was sending its data. From there I gained an understanding of how the crash data is packaged. Reverse-engineering the process I was able to understand how the raw bytes corresponded to different pieces of information. Unreal structures its dynamically sized data with a 32bit number prefixed which represents the size of the data itself.
Next was creating an http server. I chose go lang as I wanted to learn about the language. The things I personally like about the language having now used it are the simplicity of the language and the features of the standard library. Having built-in support for XML parsing and a multithreaded webserver greatly helped in the speed of development.
After the receiving of crashes was finished, I worked on creating a front end. I used TailwindCSS for styling and kept the UI very basic. I extracted project-specific data from each crash to allow for better tracking of where crashes occurred.
Initially, I was using a singular array for holding crash data. However, as we received more crashes 🥲 this array was continually growing in size. In addition to this, it offered no persistence if the reporter was shutdown (Windows Updates). Instead, I decided to set up an SQLite database for the backend. The benefits of this are that access to the database is thread-safe, data is persistent and doesn't always need to be loaded in memory. It was at this point I also decided to add a delete option. To prevent race conditions that could arise from deleting a crash report whilst another user was viewing it, I set up the database to act as a shared reference pointer. When one user began reading data, the reading count for that crash report would increase until the read was completed. Then, to delete a crash report, I created a goroutine that periodically ran and would check for rows where delete has been set to true and the reading count was 0.