https://github.com/d4ckard/spray Skip to content Toggle navigation Sign up * Product + Actions Automate any workflow + Packages Host and manage packages + Security Find and fix vulnerabilities + Codespaces Instant dev environments + Copilot Write better code with AI + Code review Manage code changes + Issues Plan and track work + Discussions Collaborate outside of code Explore + All features + Documentation + GitHub Skills + Blog * Solutions For + Enterprise + Teams + Startups + Education By Solution + CI/CD & Automation + DevOps + DevSecOps Resources + Learning Pathways + White papers, Ebooks, Webinars + Customer Stories + Partners * Open Source + GitHub Sponsors Fund open source developers + The ReadME Project GitHub community articles Repositories + Topics + Trending + Collections * Pricing Search or jump to... Search code, repositories, users, issues, pull requests... Search [ ] Clear Search syntax tips Provide feedback We read every piece of feedback, and take your input very seriously. [ ] [ ] Include my email address so I can be contacted Cancel Submit feedback Saved searches Use saved searches to filter your results more quickly Name [ ] Query [ ] To see all available qualifiers, see our documentation. Cancel Create saved search Sign in Sign up You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session. You switched accounts on another tab or window. Reload to refresh your session. Dismiss alert {{ message }} d4ckard / spray Public * Notifications * Fork 1 * Star 99 A x86_64 Linux debugger License MIT license 99 stars 1 fork Activity Star Notifications * Code * Issues 2 * Pull requests 0 * Actions * Projects 0 * Security * Insights More * Code * Issues * Pull requests * Actions * Projects * Security * Insights d4ckard/spray This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository. main Switch branches/tags [ ] Branches Tags Could not load branches Nothing to show {{ refName }} default View all branches Could not load tags Nothing to show {{ refName }} default View all tags Name already in use A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch? Cancel Create 1 branch 0 tags Code * Local * Codespaces * Clone HTTPS GitHub CLI [https://github.com/d] Use Git or checkout with SVN using the web URL. [gh repo clone d4ckar] Work fast with our official CLI. Learn more about the CLI. * Open with GitHub Desktop * Download ZIP Sign In Required Please sign in to use Codespaces. Launching GitHub Desktop If nothing happens, download GitHub Desktop and try again. Launching GitHub Desktop If nothing happens, download GitHub Desktop and try again. Launching Xcode If nothing happens, download Xcode and try again. Launching Visual Studio Code Your codespace will open once ready. There was a problem preparing your codespace, please try again. Latest commit @d4ckard d4ckard Improve help message ... 8f7e24f Nov 11, 2023 Improve help message - Remove full command docs - Mention using Clang with `-g` - Refer to the README for more info 8f7e24f Git stats * 144 commits Files Permalink Failed to load latest commit information. Type Name Latest commit message Commit time .assets Replace example image with asciinema recording November 11, 2023 11:16 dependencies Add dependencies as submodules July 22, 2023 17:12 examples Add a simple example with a double free error November 11, 2023 11:16 src Improve help message November 11, 2023 11:54 tests Add a simple filter to dereference values November 8, 2023 16:40 .gitignore Extend info interface for variables and print basic types October 4, 2023 19:31 .gitmodules Add dependencies as submodules July 22, 2023 17:12 LICENSE Add license August 22, 2023 20:20 Makefile Begin adding install command November 11, 2023 11:16 README.md Improve help message November 11, 2023 11:54 View code [ ] Spray Features Roadmap [?] Installation [?] Running Spray [?][?] Commands Reading and writing values Breakpoints Stepping Filters [?]Contributing References README.md Spray Get started - Issues - Bug report Spray Demo You can watch a tiny demo of using Spray to interact with a running program here: https://youtu.be/mjwIrfQkURc Spray is a small debugger for C code that comes with minimal mental overhead. All functionality aims to be simple and easy to grasp. In Spray you can easily control the execution of running programs, and inspect and modify their state. I started work on Spray out of curiosity about the mysterious inner workings of debuggers. In addition, I want to explore ways in which debugging can be made more approachable. Features * [*] Breakpoints on functions, on lines in files and on addresses * [*] Printing and setting variables, memory at addresses and registers * [*] C syntax highlighting * [*] Backtraces * [*] Instruction, function and line level stepping * [*] Filters to format command output Roadmap * [ ] Printing and modifying complex structures * [ ] Syntax highlighting for complex structures * [ ] Backtraces based on DWARF instead of frame pointers * [ ] Inlined functions * [ ] Loading external libraries * [ ] Catching signals sent to the debugged program [?] Installation Parts of the Spray frontend are written in Scheme and embedded into the application using CHICKEN Scheme which compiles Scheme to C. Currently, you need to have CHICKEN installed to build Spray. In the future it's possible that the generated C files are provided instead so that you only need a C compiler. Spray depends on libdwarf so if you want to build Spray, you need to install libdwarf first. Then, to install Spray you clone this repository and run make. Note the you have to clone all the submodules too. git clone --recurse-submodules https://github.com/d4ckard/spray.git cd spray make The compiled binary is named spray and can be found in the build directory. To use spray as a regular command you need to add it to your $PATH. [?] Running Spray Ensure that the binary you want to debug has debug information enabled, i.e. it was compiled with the -g flag. Also, you should disable all compile-time optimizations to ensure the best output. Spray is only tested using Clang. The debug information generated by different compilers for the same piece of code varies. Thus, clang should be used to compile the programs you want to debug using Spray. The first argument you pass to spray is the name of the binary that should be debugged (the debugee). All subsequent arguments are the arguments passed to the debugee. For example clang -g examples/free_uninit.c spray a.out starts a debugging session with the executable a.out. [?][?] Commands Spray's REPL offers the following commands to interact with a running program. Reading and writing values Command Argument(s) Description Print the value of the runtime variable. print, Print the value of the register. p
Print the value of the program's memory at the address. Set the value of the runtime variable. set, t Set the value of the register.
Set the value of the program's memory at the address. Register names are prefixed with a %, akin to the AT&T assembly syntax. This avoids name conflicts between register names and variable names. For example, to read the value of rax, use print %rax. You can find a table of all available register names in src/ registers.h. A can be a hexadecimal or a decimal number. The default is base 10 and hexadecimal will only be chosen if the literal contains a character that's exclusive to base 16 (i.e. one of a - f). You can prefix the literal with 0x to explicitly use hexadecimal in cases where decimal would work as well. An
is always a hexadecimal number. The prefix 0x is again optional. Breakpoints Command Argument(s) Description Set a breakpoint on the function. break, b : Set a breakpoint on the line in the file.
Set a breakpoint on the address. Delete a breakpoint on the function. delete, d : Delete a breakpoint on the line in the file.
Delete a breakpoint on the address. continue, c Continue execution until the next breakpoint. It's possible that the location passed to break, delete, print, or set is both a valid function name and a valid hexadecimal address. For example, add could refer to a function called add and the number 0xadd. In such a case, the default is to interpret the location as a function name. Use the prefix 0x to explicitly specify an address. Stepping Command Description next, n Go to the next line. Don't step into functions. step, s Go to the next line. Step into functions. leave, l Step out of the current function. inst, i Step to the next instruction. backtrace, a Print a backtrace starting at the current position. Filters The print and set commands can be followed by a filter, to change how output is displayed. For example, if you want to inspect the binary data in the rdx register, you can enter print %rdx | bin. Filters are separated from the command by a pipe symbol: '| ' . Currently, only one filter can be used at a time. The following table shows how different filters format the same 64-bit word with the value 103. Filter Output dec (decimal) 103 hex ( 0x67 hexadecimal) addr (address 0x0000000000000067 ) bits 00000000 00000000 00000000 00000000 00000000 00000000 00000000 01100111 bytes 00 00 00 00 00 00 00 67 deref * Prints the value found at memory address 0x67 Except for deref, all the above simply change the way the output is formatted. deref, abbreviated as *, interprets the value that would be printed as a memory address, and prints whatever is found it memory that address. Using deref, you can inspect that value that a pointer points to. [?]Contributing All contributions are welcome. Before opening a pull request, please run the test suite locally to verify that your changes don't break any other features. It's possible that some of the tests fail due to off-by-one errors when making assertions about specific values found in the example binaries that are used in the tests. Refer to this issue for more details. You can ignore tests that fail for this reason only. References * Sy Brand's blog series Writing a Linux Debugger on writing a debugger in C++ * The DWARF 5 standard * libdwarf's documentation * Eli Bendersky's posts How debuggers work About A x86_64 Linux debugger Topics c debugger cli scheme Resources Readme License MIT license Activity Stars 99 stars Watchers 2 watching Forks 1 fork Report repository Languages * C 78.8% * Scheme 13.1% * Python 6.3% * Makefile 1.8% Footer (c) 2023 GitHub, Inc. Footer navigation * Terms * Privacy * Security * Status * Docs * Contact GitHub * Pricing * API * Training * Blog * About You can't perform that action at this time.