Giter Club home page Giter Club logo

spray's People

Contributors

thass0 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

spray's Issues

Make tests agnostic to specific addresses

At this point in time, many unit (and some integration) tests rely on checking for specific addresses to validate the output of different parts of the debugger. This is problematic because if the addresses in one of the example binaries used in testing change just a bit, the tests that expect them will fail. Those failures will usually be false negatives, since it's just the binary that contains a different address after compiling again.

An obvious solution that comes to mind is to compile all the examples once and check them into version control. This way they would stay the same no matter what machine the tests
run on. This approach has the disadvantage that the range of different compilers and platforms tests is much more narrow. Specifically the tests will exclusively make assertions about the platform they were once compiled on.

In the integration tests, regular expressions might be used to check that there are addresses at the right positions. The downside of this is that any address will be accepted. Since all addresses passed around internally have their own address type anyways, the type system already enforces the presence of addresses. Hence, this solution decreases the value of the assertions drastically, too.

Lastly, we could assert that any given address must be in a specific (narrow) range. I've seen multiple tests fail because of off-by-one assertions where the new address was only slightly different.

This is definitely still an open problem and I'd be happy to discuss different options.

Add more asserts

  • is_dyn_exec in src/info.c ought not to return false if info is NULL. Just crash, otherwise totally wrong data is passed around.
  • parse_num (src/debugger.c) will segfault if passed NULL in its first argument. The function should check that this argument is not NULL.

Stop the debugger REPL automatically after the tracee has exited

If the child process ("tracee") exists, the REPL continues and signals an error every time one tries to step through the program (because the child process cannot step anywhere).

Instead of this behavior, the REPL should (for example) exit once the child exists, or drop into some state from which the child process can be restarted.

Find a way to test more DWARF operations

A lot of DWARF debug information is encoded as programs for a stack-based VM. Without turning on optimizations, only very few of the operations that exist for this VM are used in the debug information produced by Clang. Turning on optimizations seems to break multiple assumptions that Spray currently makes for analyzing programs at runtime.

To implement (and test) more VM operations, a method of producing reference binaries that use these operations is needed that doesn't rely on turning up the optimization level. Without reference binaries, it doesn't make sense to add implementations to the missing operations.

Find a more robust algorithm for finding the locations of runtime variables in memory

The current approach to finding the DIE that contains runtime information about a variable (by the variable's name) consists of two steps:

  1. We continually narrow the range of potential DIEs until we end up in a range that can only contain the variable we are looking for once (i.e., the scope of the function that contains the given PC)
  2. If no such range could be found, we traverse the entire DIE tree again, this time ignoring scope and choosing the first occurrence we find.

(This is implemented in the sd_runtime_variable function in src/spray_dwarf.c. It's documented here)

The problem of this top-down approach is that it's opposite to how variable scopes work. At any point in the program, when trying to access a variable, the closest one to the instruction pointer (PC) should be selected.

It appears that the current approach word fine (so far) for C because, in C, functions are not nested. This means that we are usually limited to two types of variables: those in the global scope and those in the current function.

The more general and reliable approach would be to build up a new tree of potential variables from the DIE tree and then traverse this variables tree, starting at the point closest to the given PC. If code blocks create new variable scopes, this would likely be the more correct approach (I haven't checked if nested {} blocks are reflected in the DWARF info at runtime).

TODO

  • Find out how re-declaring variables and shadowing in nested scopes (e.g., {int a; {int a;}}) is reflected in DWARF info.
  • Find a concrete example of how the current approach fails. Use it as a test.
  • Act like inlining doesn't exist ... ๐Ÿคซ

Implement more of the roadmap

A few notes on implementing potential roadmap features.

  • It would be cool if inlined function were allowed. As a place to start, there is a short mention of inlining in this post: "With inlining, for example, once weโ€™ve found the function whose range contains our PC, weโ€™ll need to recurse over the children of that DIE to see if there are any inlined functions which are a better match."
  • Add multi-word memory read and write using process_vm_readv(2). The implementation would live in src/registers.c.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.