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
* Outline
* Outline to sections
* Bump checkout version in workflow and make it possible to fetch history
* Fix bash script for generating contributors file
---------
Co-authored-by: Erik Stenman <[email protected]>
Co-authored-by: Tobias Lindahl <[email protected]>
Copy file name to clipboardexpand all lines: chapters/debugging.asciidoc
+129-30
Original file line number
Diff line number
Diff line change
@@ -9,48 +9,98 @@ still welcome to submit your feedback using a GitHub Issue. You can
9
9
use the same mechanism to suggest sections that you believe should be
10
10
included in this chapter, too.
11
11
12
-
=== Preliminary Outline
13
12
14
-
* Introduction
15
-
* debugger
16
-
* dbg
17
-
* redbug
18
-
* Crash dumps
19
-
* ...
20
13
21
14
=== Introduction
15
+
In long-running, 24/7 systems, the occasional bug or unwanted feature is bound to emerge. This chapter goes into the various methods for finding and fixing bugs without disrupting the services in progress. As a reader, you will explore testing techniques, tools, and frameworks that aid in testing and debugging your code. We'll also shed light on some common bug sources, such as deadlocks, message overflow, and memory issues, providing guidance on identifying and resolving these problems.
22
16
23
-
Debugging is the _art_ of identifying and removing errors
24
-
(i.e. _bugs_) from software. This section covers the most common
25
-
Erlang debugging tools and techniques. Even if step-by-step debugging
exist in Erlang, the most effective debugging techniques in Erlang are
29
-
the ones based on the so-called Erlang _tracing facilities_, which
30
-
will be discussed in detail in chapter xref:CH-Tracing[]. This chapter
31
-
also covers the concept of _Crash Dump_, a readable text file
32
-
generated by the Erlang Runtime System when an unrecoverable error is
33
-
detected, for example when the system runs out of memory or when an
34
-
emulator limit is reached. _Crash Dumps_ can are extremely precious
35
-
for post-mortem analysis of Erlang nodes and you will learn how to
36
-
read and interpret them.
37
-
38
-
=== debugger
17
+
Debugging is the process of identifying and eliminating errors, or "bugs," from software. While Erlang offers step-by-step debugging tools like the link:http://erlang.org/doc/apps/debugger/debugger_chapter.html[_Debugger_], the most effective debugging methods often rely on Erlang's tracing facilities. These facilities will be thoroughly discussed in Chapter xref:CH-Tracing[].
39
18
40
-
TODO
19
+
This chapter also explores the concept of "Crash Dumps," which are human-readable text files generated by the Erlang Runtime System when an unrecoverable error occurs, such as running out of memory or reaching an emulator limit. Crash Dumps are invaluable for post-mortem analysis of Erlang nodes, and you will learn how to interpret and understand them.
20
+
21
+
In addition to the aforementioned topics, this chapter will also provide an overview of various other essential aspects of debugging in Erlang systems. We will discuss different testing methodologies, including EUnit and Common Test, which are crucial for ensuring the reliability and robustness of your code. The importance of mocking in testing will be examined, along with its best practices.
22
+
23
+
Moreover, we will address common sources of bugs, such as deadlocks, mailbox overflow, and memory issues, and provide guidance on how to identify and resolve these problems. You will become acquainted with the "let it crash" principle and the ways to effectively implement it within your system. You'll gain insights into the workings of exceptions and supervisor tree design.
24
+
25
+
We'll also touch upon Erlang debugger usage, the role of redbug in making debugging easier and safer on live systems, and the basics of utilizing gdb for ERTS-level debugging. Furthermore, you will become familiar with dtrace and systemtap, possibly even picking up some debugging philosophy along the way.
26
+
27
+
By the end of this chapter, you'll be equipped with the knowledge to systematically test your system and its individual components. You will be able to identify common mistakes and problems, and wield the debugger effectively.
28
+
29
+
30
+
31
+
=== Testing tools
32
+
In this chapter, we will delve into the world of testing and explore how to ensure the reliability and robustness of your Erlang code. We will start with EUnit, a popular testing framework that makes it easy to write and run tests on your applications.
33
+
34
+
==== EUnit
35
+
EUnit is an Erlang unit testing framework that allows you to test individual program units. These units can range from functions and modules to processes and even whole applications. EUnit helps you write, run, and analyze the results of tests, ensuring your code is correct and reliable.
36
+
37
+
===== Basics and setup
38
+
To use EUnit in your Erlang module, include the following line after the -module declaration:
39
+
40
+
41
+
[source,erlang]
42
+
----
43
+
-include_lib("eunit/include/eunit.hrl").
44
+
----
45
+
46
+
This line provides access to EUnit's features and exports a `test()` function for running all the unit tests in your module.
47
+
48
+
===== Writing test cases and test suites
49
+
To create a simple test function, define a function with a name ending in `_test()` that takes no arguments. It should succeed by returning a value or fail by throwing an exception.
50
+
51
+
Use pattern matching with = to create more advanced test cases. For example:
52
+
53
+
[source,erlang]
54
+
----
55
+
reverse_nil_test() -> [] = lists:reverse([]).
56
+
----
57
+
58
+
Alternatively, you can use the `?assert(Expression)` macro to write test cases that evaluate expressions:
59
+
60
+
[source,erlang]
61
+
----
62
+
length_test() -> ?assert(length([1,2,3]) =:= 3).
63
+
----
64
+
65
+
===== Running tests and analyzing results
66
+
If you've included the EUnit declaration in your module, compile the module and run the automatically exported `test()` function. For example, if your module is named `m`, call `m:test()` to run EUnit on all the tests in the module.
67
+
68
+
EUnit can also run tests using the `eunit:test/1` function. For instance, calling `eunit:test(m)` is equivalent to calling `m:test()`.
41
69
42
-
=== dbg
70
+
To separate your test code from your normal code, write the test functions in a module named `m_tests` if your module is named `m`. When you ask EUnit to test the module `m`, it will also look for the module `m_tests` and run those tests.
43
71
72
+
EUnit captures standard output from test functions, so if your test code writes to the standard output, the text will not appear on the console. To bypass this, use the EUnit debugging macros or write to the user output stream, like `io:format(user, "~w", [Term])`.
73
+
74
+
For more information on checking the output produced by the unit under test, see the link:https://www.erlang.org/doc/apps/eunit/chapter.html[EUnit documentation] on macros for checking output.
75
+
76
+
77
+
==== Common Test
78
+
TODO
79
+
===== Basics and setup
44
80
TODO
81
+
===== Writing test cases and test suites
82
+
TODO
83
+
===== Running tests and analyzing results
84
+
TODO
85
+
86
+
=== Debugging Tools and Techniques
45
87
46
-
=== Redbug
88
+
==== The Erlang debugger (dbg)
89
+
===== Getting started with dbg
90
+
===== Tracing and breakpoints
91
+
===== Analyzing debugger output
92
+
93
+
94
+
95
+
96
+
==== Redbug
47
97
48
98
_Redbug_ is a debugging utility which allows you to easily interact
49
99
with the Erlang _tracing facilities_. It is an external library and
50
100
therefore it has to be installed separately. One of the best Redbug
51
101
features is its ability to shut itself down in case of overload.
52
102
53
-
==== Installing Redbug
103
+
===== Installing Redbug
54
104
55
105
You can clone redbug via:
56
106
@@ -85,7 +135,9 @@ automatically at every startup:
85
135
code:add_patha("/path/to/redbug/ebin").
86
136
----
87
137
88
-
==== Using Redbug
138
+
139
+
140
+
===== Using Redbug
89
141
90
142
Redbug is safe to be used in production, thanks to a self-protecting
91
143
mechanism against overload, which kills the tool in case too many
@@ -325,6 +377,53 @@ available options for redbug, you can ask the tool itself:
325
377
18> redbug:help().
326
378
----
327
379
328
-
=== Crash Dumps
380
+
==== Crash dumps
381
+
===== Understanding and reading crash dumps
382
+
===== Investigating why crash dumps may not be generated
383
+
384
+
==== Debugging the Runtime System
385
+
===== Using GDB
386
+
====== Basics of GDB for Erlang
387
+
====== Using GDB macros
388
+
389
+
===== SystemTap and DTrace
390
+
====== Introduction to SystemTap and DTrace
391
+
====== Using SystemTap and DTrace with Erlang
392
+
393
+
394
+
395
+
=== Mocking
396
+
==== Overview and benefits
397
+
==== Using mocks in Erlang tests
398
+
==== Best practices for mocking
399
+
400
+
=== Property Based Testing
401
+
==== QuickCheck and PropEr
402
+
403
+
=== The Usual Suspects: Common Sources of Bugs
404
+
==== Deadlocks
405
+
===== Identifying and diagnosing deadlocks
406
+
===== Techniques for resolving deadlocks
407
+
==== Mailbox overflow
408
+
===== Causes and symptoms
409
+
===== Preventing and resolving mailbox overflow issues
410
+
==== Memory issues
411
+
===== Identifying memory leaks
412
+
===== Managing binary memory usage
413
+
===== Optimizing memory usage in Erlang systems
414
+
415
+
=== Let it Crash Principle
416
+
417
+
===== Overview and rationale
418
+
419
+
===== Exceptions in Erlang
420
+
421
+
===== Designing systems with supervisor trees
422
+
423
+
424
+
=== Debugging Philosophy
425
+
==== Systematic approaches to debugging
426
+
==== Learning from mistakes and improving code quality
0 commit comments