123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659 |
- Hacking Tor: An Incomplete Guide
- ================================
- Getting started
- ---------------
- For full information on how Tor is supposed to work, look at the files in
- https:
- For an explanation of how to change Tor's design to work differently, look at
- https:
- For the latest version of the code, get a copy of git, and
- git clone https:
- We talk about Tor on the tor-talk mailing list. Design proposals and
- discussion belong on the tor-dev mailing list. We hang around on
- irc.oftc.net, with general discussion happening on #tor and development
- happening on #tor-dev.
- How we use Git branches
- -----------------------
- Each main development series (like 0.2.1, 0.2.2, etc) has its main work
- applied to a single branch. At most one series can be the development series
- at a time; all other series are maintenance series that get bug-fixes only.
- The development series is built in a git branch called "master"; the
- maintenance series are built in branches called "maint-0.2.0", "maint-0.2.1",
- and so on. We regularly merge the active maint branches forward.
- For all series except the development series, we also have a "release" branch
- (as in "release-0.2.1"). The release series is based on the corresponding
- maintenance series, except that it deliberately lags the maint series for
- most of its patches, so that bugfix patches are not typically included in a
- maintenance release until they've been tested for a while in a development
- release. Occasionally, we'll merge an urgent bugfix into the release branch
- before it gets merged into maint, but that's rare.
- If you're working on a bugfix for a bug that occurs in a particular version,
- base your bugfix branch on the "maint" branch for the first supported series
- that has that bug. (As of June 2013, we're supporting 0.2.3 and later.) If
- you're working on a new feature, base it on the master branch.
- How we log changes
- ------------------
- When you do a commit that needs a ChangeLog entry, add a new file to
- the "changes" toplevel subdirectory. It should have the format of a
- one-entry changelog section from the current ChangeLog file, as in
- o Major bugfixes:
- - Fix a potential buffer overflow. Fixes bug 99999; bugfix on
- 0.3.1.4-beta.
- To write a changes file, first categorize the change. Some common categories
- are: Minor bugfixes, Major bugfixes, Minor features, Major features, Code
- simplifications and refactoring. Then say what the change does. If
- it's a bugfix, mention what bug it fixes and when the bug was
- introduced. To find out which Git tag the change was introduced in,
- you can use "git describe --contains <sha1 of commit>".
- If at all possible, try to create this file in the same commit where you are
- making the change. Please give it a distinctive name that no other branch will
- use for the lifetime of your change. To verify the format of the changes file,
- you can use "make check-changes".
- When we go to make a release, we will concatenate all the entries
- in changes to make a draft changelog, and clear the directory. We'll
- then edit the draft changelog into a nice readable format.
- What needs a changes file?::
- A not-exhaustive list: Anything that might change user-visible
- behavior. Anything that changes internals, documentation, or the build
- system enough that somebody could notice. Big or interesting code
- rewrites. Anything about which somebody might plausibly wonder "when
- did that happen, and/or why did we do that" 6 months down the line.
- Why use changes files instead of Git commit messages?::
- Git commit messages are written for developers, not users, and they
- are nigh-impossible to revise after the fact.
- Why use changes files instead of entries in the ChangeLog?::
- Having every single commit touch the ChangeLog file tended to create
- zillions of merge conflicts.
- Useful tools
- ------------
- These aren't strictly necessary for hacking on Tor, but they can help track
- down bugs.
- Jenkins
- ~~~~~~~
- https:
- Dmalloc
- ~~~~~~~
- The dmalloc library will keep track of memory allocation, so you can find out
- if we're leaking memory, doing any double-frees, or so on.
- dmalloc -l ~/dmalloc.log
- (run the commands it tells you)
- ./configure --with-dmalloc
- Valgrind
- ~~~~~~~~
- valgrind --leak-check=yes --error-limit=no --show-reachable=yes src/or/tor
- (Note that if you get a zillion openssl warnings, you will also need to
- pass --undef-value-errors=no to valgrind, or rebuild your openssl
- with -DPURIFY.)
- Coverity
- ~~~~~~~~
- Nick regularly runs the coverity static analyzer on the Tor codebase.
- The preprocessor define __COVERITY__ is used to work around instances
- where coverity picks up behavior that we wish to permit.
- clang Static Analyzer
- ~~~~~~~~~~~~~~~~~~~~~
- The clang static analyzer can be run on the Tor codebase using Xcode (WIP)
- or a command-line build.
- The preprocessor define __clang_analyzer__ is used to work around instances
- where clang picks up behavior that we wish to permit.
- clang Runtime Sanitizers
- ~~~~~~~~~~~~~~~~
- To build the Tor codebase with the clang Address and Undefined Behavior
- sanitizers, see the file contrib/clang/sanitize_blacklist.txt.
- Preprocessor workarounds for instances where clang picks up behavior that
- we wish to permit are also documented in the blacklist file.
- Running lcov for unit test coverage
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- Lcov is a utility that generates pretty HTML reports of test code coverage.
- To generate such a report:
- -----
- ./configure --enable-coverage
- make
- make coverage-html
- $BROWSER ./coverage_html/index.html
- -----
- This will run the tor unit test suite `./src/test/test` and generate the HTML
- coverage code report under the directory ./coverage_html/. To change the
- output directory, use `make coverage-html HTML_COVER_DIR=./funky_new_cov_dir`.
- Coverage diffs using lcov are not currently implemented, but are being
- investigated (as of July 2014).
- Running the unit tests
- ~~~~~~~~~~~~~~~~~~~~~~
- To quickly run all the tests distributed with Tor:
- -----
- make check
- -----
- To run the fast unit tests only:
- -----
- make test
- -----
- To selectively run just some tests (the following can be combined
- arbitrarily):
- -----
- ./src/test/test <name_of_test> [<name of test 2>] ...
- ./src/test/test <prefix_of_name_of_test>.. [<prefix_of_name_of_test2>..] ...
- ./src/test/test :<name_of_excluded_test> [:<name_of_excluded_test2]...
- -----
- To run all tests, including those based on Stem or Chutney:
- -----
- make test-full
- -----
- To run all tests, including those basedd on Stem or Chutney that require a
- working connection to the internet:
- -----
- make test-full-online
- -----
- Running gcov for unit test coverage
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- -----
- ./configure --enable-coverage
- make
- make check
- # or--- make test-full ? make test-full-online?
- mkdir coverage-output
- ./scripts/test/coverage coverage-output
- -----
- (On OSX, you'll need to start with "--enable-coverage CC=clang".)
- Then, look at the .gcov files in coverage-output. '-' before a line means
- that the compiler generated no code for that line. '######' means that the
- line was never reached. Lines with numbers were called that number of times.
- If that doesn't work:
- If you make changes to Tor and want to get another set of coverage results,
- you can run "make reset-gcov" to clear the intermediary gcov output.
- If you have two different "coverage-output" directories, and you want to see
- a meaningful diff between them, you can run:
- -----
- ./scripts/test/cov-diff coverage-output1 coverage-output2 | less
- -----
- In this diff, any lines that were visited at least once will have coverage
- "1". This lets you inspect what you (probably) really want to know: which
- untested lines were changed? Are there any new untested lines?
- Running integration tests
- ~~~~~~~~~~~~~~~~~~~~~~~~~
- We have the beginnings of a set of scripts to run integration tests using
- Chutney. To try them, set CHUTNEY_PATH to your chutney source directory, and
- run "make test-network".
- We also have scripts to run integration tests using Stem. To try them, set
- STEM_SOURCE_DIR to your Stem source directory, and run "test-stem".
- Profiling Tor with oprofile
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~
- The oprofile tool runs (on Linux only!) to tell you what functions Tor is
- spending its CPU time in, so we can identify berformance pottlenecks.
- Here are some basic instructions
- - Build tor with debugging symbols (you probably already have, unless
- you messed with CFLAGS during the build process).
- - Build all the libraries you care about with debugging symbols
- (probably you only care about libssl, maybe zlib and Libevent).
- - Copy this tor to a new directory
- - Copy all the libraries it uses to that dir too (ldd ./tor will
- tell you)
- - Set LD_LIBRARY_PATH to include that dir. ldd ./tor should now
- show you it's using the libs in that dir
- - Run that tor
- - Reset oprofiles counters/start it
- - After a while, have it dump the stats on tor and all the libs
- in that dir you created.
- - Profit
- Generating and analyzing a callgraph
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- 1. Run ./scripts/maint/generate_callgraph.sh . This will generate a
- bunch of files in a new ./callgraph directory.
- 2. Run ./scripts/maint/analyze_callgraph.py callgraph/src
- (Doxygen will recognize any comment beginning with
- 3. Make sure to escape the characters "<", ">", "\", "%" and "#" as "\<",
- "\>", "\\", "\%", and "\#".
- 4. To document structure members, you can use two forms:
- struct foo {
-
- int a;
- int b;
- };
- 5. To generate documentation from the Tor source code, type:
- $ doxygen -g
- To generate a file called 'Doxyfile'. Edit that file and run
- 'doxygen' to generate the API documentation.
- 6. See the Doxygen manual for more information; this summary just
- scratches the surface.
- Doxygen comment conventions
- ^^^^^^^^^^^^^^^^^^^^^^^^^^^
- Say what functions do as a series of one or more imperative sentences, as
- though you were telling somebody how to be the function. In other words, DO
- NOT say:
-
- long strtol(const char *nptr, char **nptr, int base);
- Instead, please DO say:
-
- long strtol(const char *nptr, char **nptr, int base);
- Doxygen comments are the contract in our abstraction-by-contract world: if
- the functions that call your function rely on it doing something, then your
- function should mention that it does that something in the documentation. If
- you rely on a function doing something beyond what is in its documentation,
- then you should watch out, or it might do something else later.
- Putting out a new release
- -------------------------
- Here are the steps Roger takes when putting out a new Tor release:
- 1) Use it for a while, as a client, as a relay, as a hidden service,
- and as a directory authority. See if it has any obvious bugs, and
- resolve those.
- 1.5) As applicable, merge the maint-X branch into the release-X branch.
- 2) Gather the changes
|