Skip to content

Commit 9e13297

Browse files
committed
Typo and Consistency Fixes in Debugging Chapter
1 parent f786bca commit 9e13297

1 file changed

Lines changed: 27 additions & 23 deletions

File tree

chapters/debugging.asciidoc

Lines changed: 27 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,15 @@
44
=== Introduction
55
This chapter goes into the various methods for finding and fixing bugs without disrupting the services in progress. We 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.
66

7-
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[]. In this chapter We will touch on system level tracing with dtrace and systemtap.
7+
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 xref:CH-Tracing[]. In this chapter We will touch on system level tracing with DTrace and SystemTap.
88

99
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.
1010

1111
In addition to these topics, this chapter will also 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.
1212

1313
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.
1414

15-
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 possibly even picking up some debugging philosophy along the way.
15+
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 possibly even pick up some debugging philosophy along the way.
1616

1717

1818
=== Debugging Philosophy
@@ -49,7 +49,7 @@ Check **process message queues** using:
4949
process_info(Pid, messages).
5050
```
5151
A long message queue could indicate a performance bottleneck.
52-
52+
5353
Inspect **ETS tables** and memory usage:
5454
```erlang
5555
ets:info(my_table, size).
@@ -163,7 +163,7 @@ process_request({error, _}) -> handle_error().
163163

164164
===== **4. Implementing Fail-Fast Mechanisms**
165165

166-
Erlang’s **Let It Crash** philosophy means processes should **fail quickly** when an error occurs instead of propagating invalid state.
166+
Erlang’s **Let It Crash** philosophy means processes should **fail quickly** when an error occurs instead of propagating invalid state.
167167

168168
Example: Enforcing fail-fast behavior with guards:
169169
```erlang
@@ -273,7 +273,7 @@ Memory leaks in Erlang often stem from:
273273
- **Unbounded message queues**: Processes that receive but never consume messages.
274274
- **Binary data accumulation**: Large binaries can cause high memory fragmentation.
275275

276-
===== How to detect memory leaks
276+
===== How to Detect Memory Leaks
277277

278278
Check individual process memory usage:
279279
```erlang
@@ -306,7 +306,7 @@ erlang:garbage_collect(Pid).
306306
```
307307
This reclaims memory used by binaries if the process is no longer referencing them.
308308
This can be important in relaying processes that are not using the binaries anymore,
309-
but they hang on to a reference to them. Remember that binaries are reference counted
309+
but they hang on to a reference to them. Remember that binaries are reference counted
310310
and live across processes.
311311

312312
**Monitor binary memory allocation**:
@@ -324,7 +324,7 @@ Erlang provides several **system flags** that control heap allocation behavior.
324324
- Helps avoid frequent heap expansions if a process is expected to handle large amounts of data.
325325
- Default is typically **233 words**, but increasing it slightly (e.g., **256** or **512**) can improve performance for processes that grow quickly.
326326

327-
**Example Usage**
327+
**Example Usage**:
328328
You can configure this setting for a process using:
329329
```erlang
330330
spawn_opt(fun() -> my_function() end, [{min_heap_size, 512}]).
@@ -512,12 +512,11 @@ Example trace output:
512512
```
513513
This allows you to track how values change throughout execution.
514514

515-
=== The next-genation debugger: EDB
515+
=== The Next-Generation Debugger: EDB
516516

517-
The Erlang Debugger (EDB) is a modern, feature-rich debugger for Erlang applications. It provides a language server interface for setting breakpoints, inspecting variables, and stepping through code execution. See https://whatsapp.github.io/edb/
517+
The Erlang Debugger (EDB) is a modern, feature-rich debugger for Erlang applications. It provides a language server interface for setting breakpoints, inspecting variables, and stepping through code execution. See https://github.com/WhatsApp/edb
518518

519-
In order to use EDB, you need to build Erlang from source with EDB support.
520-
Future versions of Erlang OTP might be shipped with EDB support.
519+
In order to use EDB prior to OTP 28, you need to build Erlang from source with EDB support.
521520
Here is a guide on how to build Erlang from source with EDB support:
522521

523522
```bash
@@ -540,6 +539,7 @@ _build/default/bin/edb dap
540539
This command launches EDB, allowing it to interface with your development environment through the DAP, providing a robust debugging experience.
541540

542541
Current State and Stability
542+
543543
At the time of writing, EDB is an early-stage, rapidly evolving tool. Its integration and usability, while promising, can still be challenging, particularly regarding IDE setup, node connections, and environment compatibility. Stability can vary significantly depending on OTP versions and developer tooling choices.
544544

545545
=== Crash Dumps in Erlang
@@ -599,18 +599,21 @@ This dump suggests that the system crashed due to a memory allocation failure (`
599599
===== Key Sections in a Crash Dump
600600

601601
1. Slogan
602+
602603
Indicates the reason for the crash. Common slogans include:
603604
- `eheap_alloc: Cannot allocate X bytes of memory` (Memory exhaustion)
604-
- `Init terminating in do_boot ()` (Pobably an error in the boot script)
605+
- `Init terminating in do_boot ()` (Probably an error in the boot script)
605606
- `Could not start kernel pid` (Probably a bad argument in config)
606607

607608
2. System Information
609+
608610
Contains details about the runtime:
609611
- `System version`: The Erlang/OTP version and build details
610612
- `Compiled`: When the system was built
611613
- `Taints`: Whether external native code (NIFs) are running
612614

613615
3. Memory Usage
616+
614617
Displays the memory distribution:
615618

616619
- `Total`: Total memory usage
@@ -620,16 +623,19 @@ This dump suggests that the system crashed due to a memory allocation failure (`
620623
- `Code`: Loaded code memory footprint
621624

622625
4. Process List
626+
623627
Provides details about active processes, this section is crucial for identifying:
624628

625629
- Processes consuming excessive memory (`Stack+Heap` size)
626630
- Processes stuck in an infinite loop (`Reductions` count abnormally high)
627631
- Message queue overload (`Messages` field growing indefinitely)
628632

629633
5. Ports and Drivers
634+
630635
This lists open ports and drivers, which can be useful if external system interactions (files, sockets, databases) are suspected as crash causes.
631636

632637
6. Loaded Modules
638+
633639
This helps determine if dynamically loaded code (e.g., via `code:load_file/1`) caused the crash.
634640

635641

@@ -704,14 +710,14 @@ help you inspect the state of the system at the point of the crash.
704710

705711
=== Debugging the Runtime System
706712

707-
Understanding and diagnosing issues within the Erlang runtime system (BEAM) can be challenging due to its complexity. However, utilizing tools like the GNU Debugger (GDB) can significantly aid in this process. This section provides an overview of using GDB to debug the BEAM, including setting up the environment and employing GDB macros to streamline the debugging workflow.
713+
Understanding and diagnosing issues within the Erlang runtime system (ERTS) can be challenging due to its complexity. However, utilizing tools like the GNU Debugger (GDB) can significantly aid in this process. This section provides an overview of using GDB to debug the BEAM, including setting up the environment and employing GDB macros to streamline the debugging workflow.
708714

709715
[[Using-GDB]]
710716
==== Using GDB
711717

712718
GDB is a powerful tool for debugging applications at the machine level, offering insights into the execution of compiled programs. When applied to the BEAM, GDB allows developers to inspect the state of the Erlang virtual machine during execution or after a crash.
713719

714-
To effectively use GDB with the BEAM, it's beneficial to compile the Erlang runtime system with debugging symbols. This compilation provides detailed information during debugging sessions.
720+
To effectively use GDB with the BEAM, it's beneficial to compile the Erlang runtime system with debugging symbols. This compilation provides detailed information during debugging sessions.
715721

716722
See <<Alternative Beam emulator builds>> for instructions on compiling and running
717723
a version of Erlang with debugging information.
@@ -743,10 +749,10 @@ bin/cerl -rcore <core file>
743749
```
744750

745751
NOTE: If you are comfortable with using the Emacs editor, you can use
746-
`cerl` with the flags `-gdb` and `-core` (no leading `r`), which launch an
752+
`cerl` with the flags `-gdb` and `-core` (no leading `r`), which launches an
747753
Emacs instance to work as an IDE for the debugging session. (By setting
748754
`EMACS=emacsclient` first, you can even make it run in an existing Emacs if
749-
you have done a `M-x server-start`.) See the
755+
you have done an `M-x server-start`.) See the
750756
https://www.gnu.org/software/emacs/manual/html_node/emacs/GDB-Graphical-Interface.html[Emacs
751757
GDB documentation] for more details.
752758

@@ -770,7 +776,7 @@ gdb bin/x86_64-unknown-linux-gnu/beam.debug.smp 3140019
770776
since those are just shell scripts that set up the proper environment
771777
variables for the BEAM executable.)
772778

773-
Your OS might by default restrict attaching to running processes - even
779+
Your OS might by default restrict attaching to running processeseven
774780
those you own. How to reconfigure this is out of scope for this book.
775781

776782

@@ -793,7 +799,7 @@ etp-process-info <process_pointer>
793799
```
794800
Replace `<process_pointer>` with the actual pointer to the process control block (PCB) you're interested in. These macros simplify the process of extracting meaningful data from the BEAM's internal structures.
795801

796-
For a comprehensive guide on debugging the BEAM using GDB and employing these macros, refer to link:https://max-au.com/2022/03/29/debugging-the-beam/[Debugging the BEAM] and link:https://www.erlang.org/doc/system/debugging.html#debug-emulator[Debug emulator documentation]. These resources provide in-depth instructions and examples to assist you in effectively diagnosing and resolving issues within the Erlang runtime system.
802+
For a comprehensive guide on debugging the BEAM using GDB and employing these macros, refer to link:https://max-au.com/2022/03/29/debugging-the-beam/[Debugging the BEAM] and link:https://www.erlang.org/doc/system/debugging.html#debug-emulator[Debug emulator] documentation. These resources provide in-depth instructions and examples to assist you in effectively diagnosing and resolving issues within the Erlang runtime system.
797803

798804

799805
==== SystemTap and DTrace
@@ -807,7 +813,7 @@ Using these tools with Erlang can provide deep insights into the behavior of the
807813
SystemTap and DTrace operate by inserting dynamically generated probes into running kernel and user-space applications. These probes capture real-time data, allowing developers to inspect and analyze program execution without stopping or modifying the application.
808814

809815
- **SystemTap**: Developed for Linux, SystemTap enables monitoring of kernel events, user-space programs, and runtime behavior using scripting. It is commonly used for profiling, fault detection, and system introspection.
810-
816+
811817
- **DTrace**: Originally developed by Sun Microsystems for Solaris, DTrace provides similar tracing capabilities with a robust scripting language. It is widely used on macOS, FreeBSD, and SmartOS.
812818

813819
Both tools allow developers to measure function execution times, trace system calls, inspect memory usage, and capture event-based data critical for optimizing performance and debugging complex applications.
@@ -821,7 +827,7 @@ To use SystemTap and DTrace with Erlang, you need to enable the necessary tracin
821827
SystemTap scripts rely on user-space markers embedded in the BEAM emulator. These markers allow SystemTap to hook into various internal events. To use SystemTap with Erlang:
822828

823829
- **Ensure SystemTap is installed** (on Linux distributions such as Ubuntu, Fedora, or CentOS):
824-
830+
825831
```sh
826832
sudo apt-get install systemtap systemtap-sdt-dev
827833
```
@@ -865,7 +871,7 @@ This allows developers to observe function calls, detect bottlenecks, and debug
865871

866872
DTrace integrates directly with the BEAM runtime, offering deep visibility into system operations. It allows tracing function calls, memory allocation, garbage collection, and inter-process communication.
867873

868-
Dtrace works best on Solaris. There is a Linux version bundled with systemtap, but it is not as powerful as the Solaris version.
874+
Dtrace works best on Solaris. There is a Linux version bundled with SystemTap, but it is not as powerful as the Solaris version.
869875

870876
On macOS, DTrace is pre-installed. On Ubuntu, it can be installed via:
871877

@@ -897,5 +903,3 @@ sudo dtrace -s my_script.d
897903
```
898904

899905
This provides a non-intrusive way to monitor the internal behavior of the BEAM virtual machine in real-time.
900-
901-

0 commit comments

Comments
 (0)