summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/exception_architecture.md77
-rw-r--r--docs/memory_management.md6
-rw-r--r--docs/parsing_stack_traces.md63
-rw-r--r--docs/string_manipulation.md31
4 files changed, 177 insertions, 0 deletions
diff --git a/docs/exception_architecture.md b/docs/exception_architecture.md
new file mode 100644
index 00000000000..230a26e75c1
--- /dev/null
+++ b/docs/exception_architecture.md
@@ -0,0 +1,77 @@
+# Exception Architecture
+
+MongoDB code uses the following types of assertions that are available for use:
+
+- `uassert`
+ - Checks for per-operation user errors. Operation-fatal.
+- `massert`
+ - Checks per-operation invariants. Operation-fatal.
+- `fassert`
+ - Checks fatal process invariants. Process-fatal. Use to detect unexpected situations (such
+ as a system function returning an unexpected error status).
+- `invariant`
+ - Checks process invariant. Process-fatal. Use to detect code logic errors ("pointer should
+ never be null", "we should always be locked").
+
+__Note__: Calling C function `assert` is not allowed. Use one of the above instead.
+
+The following types of assertions are deprecated:
+
+- `verify`
+ - Checks per-operation invariants. A synonym for massert but doesn't require an error code.
+ Do not use for new code; use invariant or fassert instead.
+- `dassert`
+ - Calls `verify` but only in debug mode. Do not use!
+
+
+## Considerations
+
+When per-operation invariant checks fail, the current operation fails, but the process and
+connection persist. This means that `massert`, `uassert` and `verify` only terminate the current
+operation, not the whole process. Be careful not to corrupt process state by mistakenly using these
+assertions midway through mutating process state. Examples of this include `uassert` and `massert`
+inside of constructors and destructors.
+
+`fassert` failures will terminate the entire process; this is used for low-level checks where
+continuing might lead to corrupt data or loss of data on disk.
+
+Both `massert` and uassert take error codes, so that all errors have codes associated with them.
+These error codes are assigned incrementally; the numbers have no meaning other than a way to
+associate a log message with a line of code. SCons checks for duplicates, but if you want the next
+available code you can run:
+
+```
+python buildscripts/errorcodes.py
+```
+
+## Exception
+
+A failed operation-fatal assertion throws an `AssertionException` or a child of that.
+The inheritance hierarchy resembles:
+
+- `std::exception`
+ - `mongo::DBException`
+ - `mongo::AssertionException`
+ - `mongo::UserException`
+ - `mongo::MsgAssertionException`
+
+See util/assert_util.h.
+
+Generally, code in the server should be prepared to catch a `DBException`. The code should also
+expect `UserException`. We use [Resource Acquisition Is Initialization][1] heavily.
+
+
+## Gotchas
+
+Gotchas to watch out for:
+
+- Generally, do not throw an `AssertionException` directly. Functions like `uasserted()` do work
+ beyond just that. In particular, it makes sure that the `getLastError` structures are set up
+ properly.
+- Think about the location of your asserts in constructors, as the destructor would not be
+ called. But at a minimum, use `wassert` a lot therein, we want to know if something is wrong.
+- Do __not__ throw in destructors or allow exceptions to leak out (if you call a function that
+ may throw).
+
+
+[1]: https://en.wikipedia.org/wiki/Resource_acquisition_is_initialization
diff --git a/docs/memory_management.md b/docs/memory_management.md
new file mode 100644
index 00000000000..5363f7aff25
--- /dev/null
+++ b/docs/memory_management.md
@@ -0,0 +1,6 @@
+# Memory Management
+
+- Avoid using bare pointers for dynamically allocated objects. Prefer `std::unique_ptr`,
+ `std::shared_ptr`, or another RAII class such as `BSONObj`.
+- If you assign the output of `new/malloc()` directly to a bare pointer you should document where
+ it gets deleted/freed, who owns it along the way, and how exception safety is ensured.
diff --git a/docs/parsing_stack_traces.md b/docs/parsing_stack_traces.md
new file mode 100644
index 00000000000..84dd8b3cd34
--- /dev/null
+++ b/docs/parsing_stack_traces.md
@@ -0,0 +1,63 @@
+# Parsing Stack Traces
+
+## `addr2line`
+
+[`addr2line`][1] is a utility to translate addresses into filenames and line numbers.
+
+```
+addr2line -e mongod -ifC <offset>
+```
+
+
+## `c++filt`
+
+Use [`c++filt`][2] to demangle function names by pasting the whole stack trace to stdin.
+
+
+## Finding the Right Binary
+
+To find the correct binary for a specific log you need to:
+
+1. Get the commit from the header of the logs.
+2. Use git to locate that commit and check for the surrounding "version bump" commit.
+3. Download and open the binary:
+
+```
+curl -O http://s3.amazonaws.com/downloads.mongodb.org/linux/mongodb-linux-x86_64-debugsymbols-1.x.x.tgz
+```
+
+You can also get the debugsymbols archive for official builds through [the Downloads page][3]. In the
+Archived Releases section, click on the appropriate platform link to view the available archives.
+Select the appropriate debug symbols archive.
+
+### Example: Reading the Log
+
+Note that the log has lines like this:
+
+```
+/home/abc/mongod(_ZN5mongo15printStackTraceERSo+0x27) [0x689280]
+```
+
+You want to use the address in between the brackets `0x689280`. Note that you will get more than one
+stack frame for the address if the code is inlined.
+
+### Example: Using `addr2line`
+
+Actual example from a v1.8.1 64-bit Linux build:
+
+```
+$ curl http://downloads.mongodb.org/linux/mongodb-linux-x86_64-debugsymbols-1.8.1.tgz > out.tgz
+$ tar -xzf out.tgz
+$ cd mongodb-linux-x86_64-debugsymbols-1.8.1/
+$ cd bin
+$ addr2line --help
+$ addr2line -i -e mongod 0x6d6a74
+/mnt/home/buildbot/slave/Linux_64bit_V1.8/mongo/db/repl/health.cpp:394
+$ addr2line -i -e mongod 0x6d0694
+/mnt/home/buildbot/slave/Linux_64bit_V1.8/mongo/db/repl/rs.h:385
+/mnt/home/buildbot/slave/Linux_64bit_V1.8/mongo/db/repl/replset_commands.cpp:111
+```
+
+[1]: https://sourceware.org/binutils/docs/binutils/addr2line.html
+[2]: https://sourceware.org/binutils/docs-2.17/binutils/c_002b_002bfilt.html
+[3]: https://www.mongodb.com/download-center
diff --git a/docs/string_manipulation.md b/docs/string_manipulation.md
new file mode 100644
index 00000000000..ed881784b06
--- /dev/null
+++ b/docs/string_manipulation.md
@@ -0,0 +1,31 @@
+# String Manipulation
+
+For string manipulation, use the util/mongoutils/str.h library.
+
+## `str.h`
+
+`util/mongoutils/str.h` provides string helper functions for each manipulation.
+
+`str::stream()` is quite useful for assembling strings inline:
+```
+uassert(12345, str::stream() << "bad ns:" << ns, isOk);
+```
+
+## `StringData`
+
+```
+/** A StringData object wraps a 'const std::string&' or a 'const char*' without
+ * copying its contents. The most common usage is as a function argument that
+ * takes any of the two forms of strings above. Fundamentally, this class tries
+ * to work around the fact that string literals in C++ are char[N]'s.
+ *
+ * Important: the object StringData wraps must remain alive while the StringData
+ * is.
+*/
+class StringData {
+```
+
+See also [`bson/string_data.h`][1].
+
+
+[1]: ../src/mongo/base/string_data.h