921 lines
60 KiB
HTML
921 lines
60 KiB
HTML
|
|
|||
|
<!DOCTYPE html>
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
<html lang="en">
|
|||
|
<head>
|
|||
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
|||
|
|
|||
|
<title>10.2. Documentation and Debugging — Computer Systems Fundamentals</title>
|
|||
|
|
|||
|
<link rel="stylesheet" href="_static/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous" />
|
|||
|
<link rel="stylesheet" href="_static/css/pygments.css" type="text/css" />
|
|||
|
<link rel="stylesheet" href="_static/css/normalize.css" type="text/css" />
|
|||
|
<link rel="stylesheet" href="../../../JSAV/css/JSAV.css" type="text/css" />
|
|||
|
<link rel="stylesheet" href="../../../lib/odsaMOD-min.css" type="text/css" />
|
|||
|
<link rel="stylesheet" href="_static/css/jquery-1.11.4-smoothness-ui.css" type="text/css" />
|
|||
|
<link rel="stylesheet" href="../../../lib/odsaStyle-min.css" type="text/css" />
|
|||
|
<link rel="stylesheet" href="_static/css/csf.css" type="text/css" />
|
|||
|
|
|||
|
<style>
|
|||
|
.underline { text-decoration: underline; }
|
|||
|
</style>
|
|||
|
|
|||
|
<script type="text/javascript">
|
|||
|
var DOCUMENTATION_OPTIONS = {
|
|||
|
URL_ROOT: './',
|
|||
|
VERSION: '0.4.1',
|
|||
|
COLLAPSE_INDEX: false,
|
|||
|
FILE_SUFFIX: '.html',
|
|||
|
HAS_SOURCE: true
|
|||
|
};
|
|||
|
</script>
|
|||
|
|
|||
|
<script type="text/x-mathjax-config">
|
|||
|
MathJax.Hub.Config({
|
|||
|
tex2jax: {
|
|||
|
inlineMath: [['$','$'], ['\\(','\\)']],
|
|||
|
displayMath: [ ['$$','$$'], ["\\[","\\]"] ],
|
|||
|
processEscapes: true
|
|||
|
},
|
|||
|
"HTML-CSS": {
|
|||
|
scale: "80"
|
|||
|
}
|
|||
|
});
|
|||
|
</script>
|
|||
|
<link rel="shortcut icon" href="_static/favicon.ico"/>
|
|||
|
<link rel="index" title="Index" href="genindex.html" />
|
|||
|
<link rel="search" title="Search" href="search.html" />
|
|||
|
<link rel="index" title="Computer Systems Fundamentals" href="index.html" />
|
|||
|
<link rel="next" title="3. Basic Types and Pointers" href="BasicTypes.html" />
|
|||
|
<link rel="prev" title="1. C Language Reintroduction" href="CLangOverview.html" />
|
|||
|
|
|||
|
</head><body>
|
|||
|
|
|||
|
<nav class="navbar navbar-expand-md navbar-dark navbar-custom fixed-top">
|
|||
|
|
|||
|
<a class="navbar-brand py-0" href="index.html"><img src="_static/CSF-Logo-Square-Text.png" alt="OpenCSF Logo" height="40em" class="py-1 px-2 mb-0 align-center rounded-lg bg-white" /></a>
|
|||
|
<!-- Show a navbar toggler on mobile -->
|
|||
|
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#defaultNavbars" aria-controls="defaultNavbars" aria-expanded="false" aria-label="Toggle navigation">
|
|||
|
<span class="navbar-toggler-icon"></span>
|
|||
|
</button>
|
|||
|
<div class="collapse navbar-collapse" id="defaultNavbars">
|
|||
|
<ul class="navbar-nav mr-auto">
|
|||
|
<li class="nav-item dropdown">
|
|||
|
<a class="nav-link dropdown-toggle jmu-gold rounded" href="Debugging.html#" id="navbarDropdownChapters" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">Contents</a>
|
|||
|
<div class="dropdown-menu scrollable-menu" role="menu" aria-labelledby="navbarDropdownChapters">
|
|||
|
<a class="dropdown-item" tabindex="-1" href="Debugging.html#"><b>Chapter 1</b></a>
|
|||
|
<a class="dropdown-item" href="IntroConcSysOverview.html"> 1.1. Introduction to Concurrent Systems</a>
|
|||
|
<a class="dropdown-item" href="SysAndModels.html"> 1.2. Systems and Models</a>
|
|||
|
<a class="dropdown-item" href="Themes.html"> 1.3. Themes and Guiding Principles</a>
|
|||
|
<a class="dropdown-item" href="Architectures.html"> 1.4. System Architectures</a>
|
|||
|
<a class="dropdown-item" href="StateModels.html"> 1.5. State Models in UML</a>
|
|||
|
<a class="dropdown-item" href="SequenceModels.html"> 1.6. Sequence Models in UML</a>
|
|||
|
<a class="dropdown-item" href="StateModelImplementation.html"> 1.7. Extended Example: State Model Implementation</a>
|
|||
|
<div class="dropdown-divider"></div>
|
|||
|
<a class="dropdown-item disabled"><b>Chapter 2</b></a>
|
|||
|
<a class="dropdown-item" href="ProcessesOverview.html"> 2.1. Processes and OS Basics</a>
|
|||
|
<a class="dropdown-item" href="Multiprogramming.html"> 2.2. Processes and Multiprogramming</a>
|
|||
|
<a class="dropdown-item" href="KernelMechanics.html"> 2.3. Kernel Mechanics</a>
|
|||
|
<a class="dropdown-item" href="Syscall.html"> 2.4. System Call Interface</a>
|
|||
|
<a class="dropdown-item" href="ProcessCycle.html"> 2.5. Process Life Cycle</a>
|
|||
|
<a class="dropdown-item" href="UnixFile.html"> 2.6. The UNIX File Abstraction</a>
|
|||
|
<a class="dropdown-item" href="EventsSignals.html"> 2.7. Events and Signals</a>
|
|||
|
<a class="dropdown-item" href="Extended2Processes.html"> 2.8. Extended Example: Listing Files with Processes</a>
|
|||
|
<div class="dropdown-divider"></div>
|
|||
|
<a class="dropdown-item disabled"><b>Chapter 3</b></a>
|
|||
|
<a class="dropdown-item" href="IPCOverview.html"> 3.1. Concurrency with IPC</a>
|
|||
|
<a class="dropdown-item" href="IPCModels.html"> 3.2. IPC Models</a>
|
|||
|
<a class="dropdown-item" href="Pipes.html"> 3.3. Pipes and FIFOs</a>
|
|||
|
<a class="dropdown-item" href="MMap.html"> 3.4. Shared Memory With Memory-mapped Files</a>
|
|||
|
<a class="dropdown-item" href="POSIXvSysV.html"> 3.5. POSIX vs. System V IPC</a>
|
|||
|
<a class="dropdown-item" href="MQueues.html"> 3.6. Message Passing With Message Queues</a>
|
|||
|
<a class="dropdown-item" href="ShMem.html"> 3.7. Shared Memory</a>
|
|||
|
<a class="dropdown-item" href="IPCSems.html"> 3.8. Semaphores</a>
|
|||
|
<a class="dropdown-item" href="Extended3Bash.html"> 3.9. Extended Example: Bash-lite: A Simple Command-line Shell</a>
|
|||
|
<div class="dropdown-divider"></div>
|
|||
|
<a class="dropdown-item disabled"><b>Chapter 4</b></a>
|
|||
|
<a class="dropdown-item" href="SocketsOverview.html"> 4.1. Networked Concurrency</a>
|
|||
|
<a class="dropdown-item" href="FiveLayer.html"> 4.2. The TCP/IP Internet Model</a>
|
|||
|
<a class="dropdown-item" href="NetApps.html"> 4.3. Network Applications and Protocols</a>
|
|||
|
<a class="dropdown-item" href="Sockets.html"> 4.4. The Socket Interface</a>
|
|||
|
<a class="dropdown-item" href="TCPSockets.html"> 4.5. TCP Socket Programming: HTTP</a>
|
|||
|
<a class="dropdown-item" href="UDPSockets.html"> 4.6. UDP Socket Programming: DNS</a>
|
|||
|
<a class="dropdown-item" href="AppBroadcast.html"> 4.7. Application-Layer Broadcasting: DHCP</a>
|
|||
|
<a class="dropdown-item" href="Extended4CGI.html"> 4.8. Extended Example: CGI Web Server</a>
|
|||
|
<div class="dropdown-divider"></div>
|
|||
|
<a class="dropdown-item disabled"><b>Chapter 5</b></a>
|
|||
|
<a class="dropdown-item" href="InternetOverview.html"> 5.1. The Internet and Connectivity</a>
|
|||
|
<a class="dropdown-item" href="AppLayer.html"> 5.2. Application Layer: Overlay Networks</a>
|
|||
|
<a class="dropdown-item" href="TransLayer.html"> 5.3. Transport Layer</a>
|
|||
|
<a class="dropdown-item" href="NetSec.html"> 5.4. Network Security Fundamentals</a>
|
|||
|
<a class="dropdown-item" href="NetLayer.html"> 5.5. Network Layer: IP</a>
|
|||
|
<a class="dropdown-item" href="LinkLayer.html"> 5.6. Link Layer</a>
|
|||
|
<a class="dropdown-item" href="Wireless.html"> 5.7. Wireless Connectivity: Wi-Fi, Bluetooth, and Zigbee</a>
|
|||
|
<a class="dropdown-item" href="Extended5DNS.html"> 5.8. Extended Example: DNS client</a>
|
|||
|
<div class="dropdown-divider"></div>
|
|||
|
<a class="dropdown-item disabled"><b>Chapter 6</b></a>
|
|||
|
<a class="dropdown-item" href="ThreadsOverview.html"> 6.1. Concurrency with Multithreading</a>
|
|||
|
<a class="dropdown-item" href="ProcVThreads.html"> 6.2. Processes vs. Threads</a>
|
|||
|
<a class="dropdown-item" href="RaceConditions.html"> 6.3. Race Conditions and Critical Sections</a>
|
|||
|
<a class="dropdown-item" href="POSIXThreads.html"> 6.4. POSIX Thread Library</a>
|
|||
|
<a class="dropdown-item" href="ThreadArgs.html"> 6.5. Thread Arguments and Return Values</a>
|
|||
|
<a class="dropdown-item" href="ImplicitThreads.html"> 6.6. Implicit Threading and Language-based Threads</a>
|
|||
|
<a class="dropdown-item" href="Extended6Input.html"> 6.7. Extended Example: Keyboard Input Listener</a>
|
|||
|
<a class="dropdown-item" href="Extended6Primes.html"> 6.8. Extended Example: Concurrent Prime Number Search</a>
|
|||
|
<div class="dropdown-divider"></div>
|
|||
|
<a class="dropdown-item disabled"><b>Chapter 7</b></a>
|
|||
|
<a class="dropdown-item" href="SynchOverview.html"> 7.1. Synchronization Primitives</a>
|
|||
|
<a class="dropdown-item" href="CritSect.html"> 7.2. Critical Sections and Peterson's Solution</a>
|
|||
|
<a class="dropdown-item" href="Locks.html"> 7.3. Locks</a>
|
|||
|
<a class="dropdown-item" href="Semaphores.html"> 7.4. Semaphores</a>
|
|||
|
<a class="dropdown-item" href="Barriers.html"> 7.5. Barriers</a>
|
|||
|
<a class="dropdown-item" href="Condvars.html"> 7.6. Condition Variables</a>
|
|||
|
<a class="dropdown-item" href="Deadlock.html"> 7.7. Deadlock</a>
|
|||
|
<a class="dropdown-item" href="Extended7Events.html"> 7.8. Extended Example: Event Log File</a>
|
|||
|
<div class="dropdown-divider"></div>
|
|||
|
<a class="dropdown-item disabled"><b>Chapter 8</b></a>
|
|||
|
<a class="dropdown-item" href="SynchProblemsOverview.html"> 8.1. Synchronization Patterns and Problems</a>
|
|||
|
<a class="dropdown-item" href="SynchDesign.html"> 8.2. Basic Synchronization Design Patterns</a>
|
|||
|
<a class="dropdown-item" href="ProdCons.html"> 8.3. Producer-Consumer Problem</a>
|
|||
|
<a class="dropdown-item" href="ReadWrite.html"> 8.4. Readers-Writers Problem</a>
|
|||
|
<a class="dropdown-item" href="DiningPhil.html"> 8.5. Dining Philosophers Problem and Deadlock</a>
|
|||
|
<a class="dropdown-item" href="CigSmokers.html"> 8.6. Cigarette Smokers Problem and the Limits of Semaphores and Locks</a>
|
|||
|
<a class="dropdown-item" href="Extended8ModExp.html"> 8.7. Extended Example: Parallel Modular Exponentiation</a>
|
|||
|
<div class="dropdown-divider"></div>
|
|||
|
<a class="dropdown-item disabled"><b>Chapter 9</b></a>
|
|||
|
<a class="dropdown-item" href="ParallelDistributedOverview.html"> 9.1. Parallel and Distributed Systems</a>
|
|||
|
<a class="dropdown-item" href="ParVConc.html"> 9.2. Parallelism vs. Concurrency</a>
|
|||
|
<a class="dropdown-item" href="ParallelDesign.html"> 9.3. Parallel Design Patterns</a>
|
|||
|
<a class="dropdown-item" href="Scaling.html"> 9.4. Limits of Parallelism and Scaling</a>
|
|||
|
<a class="dropdown-item" href="DistTiming.html"> 9.5. Timing in Distributed Environments</a>
|
|||
|
<a class="dropdown-item" href="DistDataStorage.html"> 9.6. Reliable Data Storage and Location</a>
|
|||
|
<a class="dropdown-item" href="DistConsensus.html"> 9.7. Consensus in Distributed Systems</a>
|
|||
|
<a class="dropdown-item" href="Extended9Blockchain.html"> 9.8. Extended Example: Blockchain Proof-of-Work</a>
|
|||
|
<div class="dropdown-divider"></div>
|
|||
|
<a class="dropdown-item disabled"><b>Appendix A</b></a>
|
|||
|
<a class="dropdown-item" href="CLangOverview.html"> A.1. C Language Reintroduction</a>
|
|||
|
<a class="dropdown-item" href="Debugging.html"> A.2. Documentation and Debugging</a>
|
|||
|
<a class="dropdown-item" href="BasicTypes.html"> A.3. Basic Types and Pointers</a>
|
|||
|
<a class="dropdown-item" href="Arrays.html"> A.4. Arrays, Structs, Enums, and Type Definitions</a>
|
|||
|
<a class="dropdown-item" href="Functions.html"> A.5. Functions and Scope</a>
|
|||
|
<a class="dropdown-item" href="Pointers.html"> A.6. Pointers and Dynamic Allocation</a>
|
|||
|
<a class="dropdown-item" href="Strings.html"> A.7. Strings</a>
|
|||
|
<a class="dropdown-item" href="FunctionPointers.html"> A.8. Function Pointers</a>
|
|||
|
<a class="dropdown-item" href="Files.html"> A.9. Files</a>
|
|||
|
</div>
|
|||
|
</li>
|
|||
|
|
|||
|
|
|||
|
|
|||
|
</ul>
|
|||
|
</div>
|
|||
|
|
|||
|
<ul class="navbar-nav flex-row ml-md-auto d-none d-md-flex">
|
|||
|
<li class="nav-item"><a class="nav-link jmu-gold" href="https://w3.cs.jmu.edu/kirkpams/OpenCSF/Books/csf/source/Debugging.rst"
|
|||
|
target="_blank" rel="nofollow">Show Source</a></li>
|
|||
|
|
|||
|
</ul>
|
|||
|
</nav>
|
|||
|
|
|||
|
|
|||
|
<div class="container center">
|
|||
|
«  <a id="prevmod" href="CLangOverview.html">10.1. C Language Reintroduction</a>
|
|||
|
  ::  
|
|||
|
<a class="uplink" href="index.html">Contents</a>
|
|||
|
  ::  
|
|||
|
<a id="nextmod" href="BasicTypes.html">10.3. Basic Types and Pointers</a>  »
|
|||
|
|
|||
|
</div>
|
|||
|
<br />
|
|||
|
|
|||
|
|
|||
|
|
|||
|
<script type="text/javascript" src="_static/js/jquery-2.1.4.min.js"></script>
|
|||
|
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
|
|||
|
<script type="text/javascript" src="_static/js/jquery-1.11.4-ui.min.js"></script>
|
|||
|
<script type="text/javascript" src="_static/js/forge-0.7.0.min.js"></script>
|
|||
|
<script type="text/javascript" src="../../../JSAV/lib/jquery.transit.js"></script>
|
|||
|
<script type="text/javascript" src="../../../JSAV/lib/raphael.js"></script>
|
|||
|
<script type="text/javascript" src="../../../JSAV/build/JSAV-min.js"></script>
|
|||
|
<script type="text/javascript" src="_static/js/config.js"></script>
|
|||
|
<script type="text/javascript" src="../../../lib/odsaUtils-min.js"></script>
|
|||
|
<script type="text/javascript" src="../../../lib/odsaMOD-min.js"></script>
|
|||
|
<script type="text/javascript" src="_static/js/d3-4.13.0.min.js"></script>
|
|||
|
<script type="text/javascript" src="_static/js/d3-selection-multi.v1.min.js"></script>
|
|||
|
<script type="text/javascript" src="../../../lib/dataStructures.js"></script>
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
<div class="container">
|
|||
|
|
|||
|
<script>ODSA.SETTINGS.DISP_MOD_COMP = true;ODSA.SETTINGS.MODULE_NAME = "Debugging";ODSA.SETTINGS.MODULE_LONG_NAME = "Documentation and Debugging";ODSA.SETTINGS.MODULE_CHAPTER = "Appendix A"; ODSA.SETTINGS.BUILD_DATE = "2021-06-14 17:15:25"; ODSA.SETTINGS.BUILD_CMAP = false;JSAV_OPTIONS['lang']='en';JSAV_EXERCISE_OPTIONS['code']='java';</script><div class="section" id="documentation-and-debugging">
|
|||
|
<h1>10.2. Documentation and Debugging<a class="headerlink" href="Debugging.html#documentation-and-debugging" title="Permalink to this headline">¶</a></h1>
|
|||
|
<p>The Internet provides many ways to find documentation via web searches that lead to Stack Overflow.
|
|||
|
This approach can be helpful when the provided code is easily adaptable, but it can also be
|
|||
|
frustrating when the explanation is incomplete or incorrect. <a class="footnote-reference" href="Debugging.html#f51" id="id1">[1]</a> In particular, solutions found
|
|||
|
in this way can often demonstrate what the correct approach is but not clearly identify the source
|
|||
|
of the error or misunderstanding. System manuals (referred as man pages to in the UNIX tradition)
|
|||
|
and command-line debuggers can become powerful tools when learned.</p>
|
|||
|
<div class="section" id="man-pages">
|
|||
|
<h2>10.2.1. Man Pages<a class="headerlink" href="Debugging.html#man-pages" title="Permalink to this headline">¶</a></h2>
|
|||
|
<p>Throughout this book, we have generally adhered to the POSIX.1-2017 specification for the C
|
|||
|
programming interface (also known officially as IEEE Std 1003.1, 2017 Edition and The Open Group
|
|||
|
Technical Standard Base Specifications, Issue 7). This specification is published freely online by
|
|||
|
The Open Group at:</p>
|
|||
|
<blockquote>
|
|||
|
<div><ul class="simple">
|
|||
|
<li><a class="reference external" href="https://publications.opengroup.org/standards/unix/c181">https://publications.opengroup.org/standards/unix/c181</a></li>
|
|||
|
<li><a class="reference external" href="https://pubs.opengroup.org/onlinepubs/9699919799/">https://pubs.opengroup.org/onlinepubs/9699919799/</a></li>
|
|||
|
</ul>
|
|||
|
</div></blockquote>
|
|||
|
<p>Often, however, it is convenient or even necessary to access the system manual directly from the
|
|||
|
command line. For instance, recall that macOS is a UNIX OS based on BSD UNIX, while Linux is a
|
|||
|
UNIX-like OS that was developed independently. As such, there are slight differences between the C
|
|||
|
interfaces (particularly in relation to IPC) between the two. When these differences arise, it is
|
|||
|
necessary to consult the documentation that is specific to that particular OS. The <code class="docutils literal notranslate"><span class="pre">man</span></code>
|
|||
|
command-line utility provides that interface. Documentation for any C function or system call can
|
|||
|
(generally, with an exception described below) be found by typing <code class="docutils literal notranslate"><span class="pre">man</span></code> followed by the name of
|
|||
|
the function. To get started with <code class="docutils literal notranslate"><span class="pre">man</span></code>, you can read its own <code class="docutils literal notranslate"><span class="pre">man</span></code> page (use arrows to move
|
|||
|
up/down and press <code class="docutils literal notranslate"><span class="pre">'q'</span></code> to quit):</p>
|
|||
|
<div class="highlight-none border border-dark rounded-lg bg-light px-2 mb-3 notranslate"><div class="highlight bg-light"><pre class="mb-0"><span></span>$ man man
|
|||
|
</pre></div>
|
|||
|
</div>
|
|||
|
<p>One issue that arises with man pages is that there are naming conflicts between command-line
|
|||
|
utilities and C functions. These conflicts can be resolved by specifying the <em>section</em> of the
|
|||
|
manual as an integer parameter before the function name. The most common sections of interest for
|
|||
|
systems programming are sections 1 (executable programs and command-line utilities), 2 (system calls
|
|||
|
provided by the kernel), and 3 (C standard library functions that are not system calls). As an
|
|||
|
example, compare the following two <code class="docutils literal notranslate"><span class="pre">man</span></code> page entries; the former brings up the page for the
|
|||
|
<code class="docutils literal notranslate"><span class="pre">bash</span> <span class="pre">mkdir</span></code> command, while the latter brings up the C function documentation):</p>
|
|||
|
<div class="highlight-none border border-dark rounded-lg bg-light px-2 mb-3 notranslate"><div class="highlight bg-light"><pre class="mb-0"><span></span>$ man mkdir
|
|||
|
$ man 2 mkdir
|
|||
|
</pre></div>
|
|||
|
</div>
|
|||
|
<p>The header of the <code class="docutils literal notranslate"><span class="pre">man</span></code> page indicates a more precise naming convention to indicate the section
|
|||
|
under consideration. Using the examples above, the default behavior for man <code class="docutils literal notranslate"><span class="pre">mkdir</span></code> is to find
|
|||
|
<code class="docutils literal notranslate"><span class="pre">mkdir(1)</span></code>, the command-line utility, as opposed to <code class="docutils literal notranslate"><span class="pre">mkdir(2)</span></code>, the system call. Besides a
|
|||
|
header and footer that document the function’s section of the manual, the structure for <code class="docutils literal notranslate"><span class="pre">man</span></code>
|
|||
|
pages for C functions generally follows a specified format (may not contain all of these fields):</p>
|
|||
|
<center>
|
|||
|
<div class="col-md-10">
|
|||
|
<table class="table table-bordered">
|
|||
|
<thead class="jmu-dark-purple-bg text-light">
|
|||
|
<tr>
|
|||
|
<th class="py-0 center">Field title</th>
|
|||
|
<th class="py-0 center">Purpose of the field</th>
|
|||
|
</tr>
|
|||
|
</thead>
|
|||
|
<tbody>
|
|||
|
<tr>
|
|||
|
<td class="py-0"><code>NAME</code></td>
|
|||
|
<td class="py-0">Quick description of the function or utility</td>
|
|||
|
</tr>
|
|||
|
<tr>
|
|||
|
<td class="py-0"><code>LIBRARY</code></td>
|
|||
|
<td class="py-0">Which libraries must be linked to the compiled code (sometimes included as part of the <code>SYNOPSIS</code>)</td>
|
|||
|
</tr>
|
|||
|
<tr>
|
|||
|
<td class="py-0"><code>SYNOPSIS</code></td>
|
|||
|
<td class="py-0">Required header <code>#include</code> statements and the function prototype</td>
|
|||
|
</tr>
|
|||
|
<tr>
|
|||
|
<td class="py-0"><code>DESCRIPTION</code></td>
|
|||
|
<td class="py-0">A detailed description of what the function does, with key usage issues or considerations highlighted </td>
|
|||
|
</tr>
|
|||
|
<tr>
|
|||
|
<td class="py-0"><code>RETURN VALUES</code></td>
|
|||
|
<td class="py-0">How to interpret possible values returned from the function</td>
|
|||
|
</tr>
|
|||
|
<tr>
|
|||
|
<td class="py-0"><code>ERRORS</code></td>
|
|||
|
<td class="py-0">A list of constants that the function might assign to <code>errno</code> when an error occurs; these constants begin with <code>'E'</code> and are printed in brackets</td>
|
|||
|
</tr>
|
|||
|
<tr>
|
|||
|
<td class="py-0"><code>SEE ALSO</code></td>
|
|||
|
<td class="py-0">Other functions that serve related purposes</td>
|
|||
|
</tr>
|
|||
|
<tr>
|
|||
|
<td class="py-0"><code>STANDARDS</code></td>
|
|||
|
<td class="py-0">Which POSIX standard defines the function</td>
|
|||
|
</tr>
|
|||
|
<tr>
|
|||
|
<td class="py-0"><code>HISTORY</code></td>
|
|||
|
<td class="py-0">When was the function introduced to UNIX</td>
|
|||
|
</tr>
|
|||
|
<tr>
|
|||
|
<td class="py-0"><code>BUGS</code></td>
|
|||
|
<td class="py-0">Possible input sources that cause known bugs</td>
|
|||
|
</tr>
|
|||
|
</tbody>
|
|||
|
</table>
|
|||
|
</div>
|
|||
|
<div class="col-md-10 center">
|
|||
|
Table A.1: Common fields of a <code>man</code> page
|
|||
|
</div>
|
|||
|
</center>
|
|||
|
<br /><p>Beyond just providing information about what the function is or does, these sections provide hints
|
|||
|
for how to deal with errors. Specifically, when a problem arises with compilation or a run-time
|
|||
|
crash occurs, the following <code class="docutils literal notranslate"><span class="pre">man</span></code> page fields provide a quick solution:</p>
|
|||
|
<blockquote>
|
|||
|
<div><ul class="simple">
|
|||
|
<li><code class="docutils literal notranslate"><span class="pre">SYNOPSIS</span></code> – Many functions rely on a particular <code class="docutils literal notranslate"><span class="pre">struct</span></code> declaration that is defined in a
|
|||
|
standard header file. This field enumerates all of the headers that are required to be set as
|
|||
|
<code class="docutils literal notranslate"><span class="pre">#include</span></code> statements to use the function. This field is also particularly helpful for making
|
|||
|
sure that arguments are being passed in the correct order.</li>
|
|||
|
<li><code class="docutils literal notranslate"><span class="pre">LIBRARY</span></code> – Some functions require linking to additional libraries. For instance, the <code class="docutils literal notranslate"><span class="pre">pow()</span></code>
|
|||
|
function (used to calculate raising a base to some power) is in the C math library; some systems
|
|||
|
require explicitly linking executables with the <code class="docutils literal notranslate"><span class="pre">-lm</span></code> flag for <code class="docutils literal notranslate"><span class="pre">gcc</span></code>.</li>
|
|||
|
<li><code class="docutils literal notranslate"><span class="pre">RETURN</span> <span class="pre">VALUES</span></code> – Some functions return a simple binary value to indicate success or failure,
|
|||
|
while others return a quantitative value (such as the number of bytes read). Treating return values
|
|||
|
incorrectly can lead to many bugs in systems code.</li>
|
|||
|
<li><code class="docutils literal notranslate"><span class="pre">ERRORS</span></code> – Many functions use a generic return value to indicate an error has occurred. For
|
|||
|
instance, <code class="docutils literal notranslate"><span class="pre">read()</span></code> returns -1 to indicate that the requested operation failed; the global
|
|||
|
variable <code class="docutils literal notranslate"><span class="pre">errno</span></code> is set to explain why the failure occurred. In the case of <code class="docutils literal notranslate"><span class="pre">read(2)</span></code>, the
|
|||
|
possible errors include <code class="docutils literal notranslate"><span class="pre">EAGAIN</span></code> (file is marked for non-blocking I/O, but no data is ready to
|
|||
|
read), <code class="docutils literal notranslate"><span class="pre">EINTR</span></code> (the device was interrupted by a signal), <code class="docutils literal notranslate"><span class="pre">EINVAL</span></code> (the file descriptor was
|
|||
|
negative), or <code class="docutils literal notranslate"><span class="pre">EBADF</span></code> (the file descriptor is not open for reading). Comparing <code class="docutils literal notranslate"><span class="pre">errno</span></code> with
|
|||
|
these constants in the case of a failure to read can be an important clue in debugging.</li>
|
|||
|
</ul>
|
|||
|
</div></blockquote>
|
|||
|
<p>One last note about <code class="docutils literal notranslate"><span class="pre">man</span></code> pages is that non-standard libraries typically provide an interface that
|
|||
|
can be consulted as above. The primary difference is that these libraries might be installed in
|
|||
|
places that the man command does not know to check. The <code class="docutils literal notranslate"><span class="pre">-M</span></code> flag can fix this problem. As an
|
|||
|
example, on macOS, the Homebrew <a class="footnote-reference" href="Debugging.html#f52" id="id2">[2]</a> utility can be used to install OpenSSL. The default behavior
|
|||
|
of Homebrew is to install such libraries in <code class="docutils literal notranslate"><span class="pre">/usr/local/opt</span></code>, which is not searched by <code class="docutils literal notranslate"><span class="pre">man</span></code>. As
|
|||
|
such, the documentation for OpenSSL functions can be found by specifying the path as follows:</p>
|
|||
|
<div class="highlight-none border border-dark rounded-lg bg-light px-2 mb-3 notranslate"><div class="highlight bg-light"><pre class="mb-0"><span></span>$ man -M /usr/local/opt/openssl/share/man EVP_EncryptInit
|
|||
|
</pre></div>
|
|||
|
</div>
|
|||
|
</div>
|
|||
|
<div class="section" id="debugging-with-gdb">
|
|||
|
<h2>10.2.2. Debugging with GDB<a class="headerlink" href="Debugging.html#debugging-with-gdb" title="Permalink to this headline">¶</a></h2>
|
|||
|
<p>One hurdle that all programmers must overcome is that errors and crashes indicate that there is a
|
|||
|
difference between what the code <em>does</em> and what the code <em>should do</em> (or rather, what the
|
|||
|
programmer <em>thinks</em> the code should do). Debugging is the art of bridging this gap. When a program
|
|||
|
crashes or produces obviously incorrect output, the programmer must figure out where in the code
|
|||
|
this gap exists and what is causing it. The GNU debugger (GDB) is a powerful tool that can help to
|
|||
|
bridge this gap. Besides just stepping through code, GDB provides a number of built-in tools that
|
|||
|
can assist with debugging. More documentation on GDB can be found at:</p>
|
|||
|
<blockquote>
|
|||
|
<div><ul class="simple">
|
|||
|
<li><a class="reference external" href="https://www.gnu.org/software/gdb/documentation/">https://www.gnu.org/software/gdb/documentation/</a></li>
|
|||
|
</ul>
|
|||
|
</div></blockquote>
|
|||
|
<div class="section" id="breakpoints-and-watchpoints">
|
|||
|
<h3>10.2.2.1. Breakpoints and Watchpoints<a class="headerlink" href="Debugging.html#breakpoints-and-watchpoints" title="Permalink to this headline">¶</a></h3>
|
|||
|
<p>In the systems programming field, particularly with languages like C, the lack of exception handling
|
|||
|
makes debugging challenging. Often, the only indication that the error has occurred is the
|
|||
|
notoriously vague “Segmentation fault.” To get started with GDB, we will use it to examine
|
|||
|
<a class="reference external" href="Debugging.html#cla-1">Code Listing A.1</a>.</p>
|
|||
|
<div class="highlight-c border border-dark rounded-lg bg-light px-0 mb-3 notranslate" id="cla-1"><table class="highlighttable"><tr><td class="linenos px-0 mx-0"><div class="linenodiv"><pre class="mb-0"> 1
|
|||
|
2
|
|||
|
3
|
|||
|
4
|
|||
|
5
|
|||
|
6
|
|||
|
7
|
|||
|
8
|
|||
|
9
|
|||
|
10
|
|||
|
11
|
|||
|
12
|
|||
|
13
|
|||
|
14
|
|||
|
15
|
|||
|
16
|
|||
|
17
|
|||
|
18
|
|||
|
19
|
|||
|
20
|
|||
|
21
|
|||
|
22</pre></div></td><td class="code"><div class="highlight bg-light"><pre class="mb-0"><span></span><span class="cm">/* Code Listing A.1:</span>
|
|||
|
<span class="cm"> Code for tracing watchpoints and breakpoints in GDB </span>
|
|||
|
<span class="cm"> */</span>
|
|||
|
|
|||
|
<span class="cp">#include</span> <span class="cpf"><stdio.h></span><span class="cp"></span>
|
|||
|
|
|||
|
<span class="kt">int</span>
|
|||
|
<span class="nf">helper</span> <span class="p">(</span><span class="kt">int</span> <span class="n">input</span><span class="p">)</span>
|
|||
|
<span class="p">{</span>
|
|||
|
<span class="k">return</span> <span class="n">input</span> <span class="o">+</span> <span class="mi">1</span><span class="p">;</span>
|
|||
|
<span class="p">}</span>
|
|||
|
|
|||
|
<span class="kt">int</span>
|
|||
|
<span class="nf">main</span> <span class="p">(</span><span class="kt">int</span> <span class="n">argc</span><span class="p">)</span>
|
|||
|
<span class="p">{</span>
|
|||
|
<span class="kt">int</span> <span class="n">x</span> <span class="o">=</span> <span class="n">argc</span><span class="p">;</span>
|
|||
|
<span class="kt">int</span> <span class="n">y</span> <span class="o">=</span> <span class="n">helper</span> <span class="p">(</span><span class="n">x</span><span class="p">);</span>
|
|||
|
<span class="n">x</span> <span class="o">=</span> <span class="mi">10</span><span class="p">;</span>
|
|||
|
<span class="n">printf</span> <span class="p">(</span><span class="s">"x = %d; y = %d</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span> <span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="p">);</span>
|
|||
|
|
|||
|
<span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
|
|||
|
<span class="p">}</span>
|
|||
|
</pre></div>
|
|||
|
</td></tr></table></div>
|
|||
|
<p>To get started with GDB, we must compile our program with the <code class="docutils literal notranslate"><span class="pre">-g</span></code> flag for <code class="docutils literal notranslate"><span class="pre">gcc</span></code>, indicating
|
|||
|
that we want to include debugging symbols. Without debugging symbols, we cannot refer to variables
|
|||
|
or (in certain circumstances) functions by their names. In the example code above, the steps to
|
|||
|
compile it, run it (without GDB), and run it again (with GDB) are as follows (note that GDB requires
|
|||
|
passing the <code class="docutils literal notranslate"><span class="pre">--args</span></code> option if there are command-line arguments):</p>
|
|||
|
<div class="highlight-none border border-dark rounded-lg bg-light px-2 mb-3 notranslate"><div class="highlight bg-light"><pre class="mb-0"><span></span>$ gcc -g -o watch watch.c
|
|||
|
$ ./watch 5
|
|||
|
x = 10; y = 3
|
|||
|
$ gdb --args ./watch 5
|
|||
|
GNU gdb (Ubuntu 8.1-0ubuntu3.2) 8.1.0.20180409-git
|
|||
|
</pre></div>
|
|||
|
</div>
|
|||
|
<p>The following GDB session illustrates how to use <em>watchpoints</em> and <em>breakpoints</em>. In
|
|||
|
GDB, we can set a watchpoint on a variable and be notified any time that variable’s value changes.
|
|||
|
(In fact, we can set watchpoints for any arbitrary memory location, but that is beyond our current
|
|||
|
scope.) We can set a breakpoint for a function name and be notified any time that function is
|
|||
|
called. In this first GDB session, we set a breakpoint for the <code class="docutils literal notranslate"><span class="pre">helper()</span></code> function and a
|
|||
|
watchpoint for the <code class="docutils literal notranslate"><span class="pre">x</span></code> variable in <code class="docutils literal notranslate"><span class="pre">main()</span></code>.</p>
|
|||
|
<div class="highlight-none border border-dark rounded-lg bg-light px-0 mb-3 notranslate"><table class="highlighttable"><tr><td class="linenos px-0 mx-0"><div class="linenodiv"><pre class="mb-0"> 1
|
|||
|
2
|
|||
|
3
|
|||
|
4
|
|||
|
5
|
|||
|
6
|
|||
|
7
|
|||
|
8
|
|||
|
9
|
|||
|
10
|
|||
|
11
|
|||
|
12
|
|||
|
13
|
|||
|
14
|
|||
|
15
|
|||
|
16</pre></div></td><td class="code"><div class="highlight bg-light"><pre class="mb-0"><span></span>GNU gdb (Ubuntu 8.1-0ubuntu3.2) 8.1.0.20180409-git
|
|||
|
[GDB license info omitted...]
|
|||
|
Reading symbols from ./watch...done.
|
|||
|
(gdb) start
|
|||
|
Temporary breakpoint 1 at 0x661: file watch.c, line 12.
|
|||
|
Starting program: /home/csf/watch
|
|||
|
|
|||
|
Temporary breakpoint 1, main (argc=2) at watch.c:12
|
|||
|
13 int x = 5;
|
|||
|
(gdb) break helper
|
|||
|
Breakpoint 2 at 0x555555554651: file watch.c, line 6.
|
|||
|
(gdb) watch x
|
|||
|
Hardware watchpoint 3: x
|
|||
|
(gdb) watch input
|
|||
|
No symbol "input" in current context.
|
|||
|
(gdb)
|
|||
|
</pre></div>
|
|||
|
</td></tr></table></div>
|
|||
|
<p>For simplicity, we have omitted the several lines of introductory text that GDB shows regarding its
|
|||
|
license and documentation. The GDB command prompts are shown as bolded lines, where <code class="docutils literal notranslate"><span class="pre">(gdb)</span></code>
|
|||
|
indicates the prompt and our input is shown afterwards. On line 4 of this session, we use the
|
|||
|
<code class="docutils literal notranslate"><span class="pre">start</span></code> command to begin the program’s execution, which will pause when the <code class="docutils literal notranslate"><span class="pre">main()</span></code> function
|
|||
|
begins execution. When GDB executes lines of code as the result of a command, it displays the next
|
|||
|
line of code that will be executed in the future. So on line 9, GDB is indicating that it paused
|
|||
|
just before line 12 of <a class="reference external" href="Debugging.html#cla-1">Code Listing A.1</a>, which initializes the <code class="docutils literal notranslate"><span class="pre">x</span></code> variable.</p>
|
|||
|
<p>Lines 10 and 12 of the GDB session set up the breakpoint and watchpoint with their respective
|
|||
|
commands, <code class="docutils literal notranslate"><span class="pre">break</span></code> and <code class="docutils literal notranslate"><span class="pre">watch</span></code>. Note that these commands require the target symbols to be visible
|
|||
|
by GDB when they are run. That means that the program must be compiled with debugging symbols
|
|||
|
included and the variable must be in scope. On line 14 of this GDB session, we cannot set a
|
|||
|
watchpoint for the <code class="docutils literal notranslate"><span class="pre">input</span></code> variable, which is only defined within the scope of the <code class="docutils literal notranslate"><span class="pre">helper()</span></code>
|
|||
|
function; GDB is currently executing inside the <code class="docutils literal notranslate"><span class="pre">main()</span></code> function scope.</p>
|
|||
|
<p>The main commands to execute code in GDB are <code class="docutils literal notranslate"><span class="pre">step</span></code>, <code class="docutils literal notranslate"><span class="pre">next</span></code>, and <code class="docutils literal notranslate"><span class="pre">continue</span></code>. The <code class="docutils literal notranslate"><span class="pre">step</span></code> and
|
|||
|
<code class="docutils literal notranslate"><span class="pre">next</span></code> commands (not shown here) would simply execute the next line of code. In the session above,
|
|||
|
running either of these commands would execute the line 12 of <a class="reference external" href="Debugging.html#cla-1">Code Listing A.1</a>, which sets the
|
|||
|
variable <code class="docutils literal notranslate"><span class="pre">x</span></code> to 5. The difference between these two commands arises when the next line of code is
|
|||
|
a function call. The <code class="docutils literal notranslate"><span class="pre">step</span></code> command would <em>step into</em> the called function’s body, whereas the
|
|||
|
<code class="docutils literal notranslate"><span class="pre">next</span></code> command treats the function call as an opaque box, executing the entire function as one
|
|||
|
step. Based on the previous session, we use the <code class="docutils literal notranslate"><span class="pre">continue</span></code> command, which allows the program to
|
|||
|
run until it is interrupted.</p>
|
|||
|
<div class="highlight-none border border-dark rounded-lg bg-light px-0 mb-3 notranslate"><table class="highlighttable"><tr><td class="linenos px-0 mx-0"><div class="linenodiv"><pre class="mb-0"> 1
|
|||
|
2
|
|||
|
3
|
|||
|
4
|
|||
|
5
|
|||
|
6
|
|||
|
7
|
|||
|
8
|
|||
|
9
|
|||
|
10
|
|||
|
11
|
|||
|
12
|
|||
|
13
|
|||
|
14
|
|||
|
15
|
|||
|
16
|
|||
|
17
|
|||
|
18
|
|||
|
19
|
|||
|
20
|
|||
|
21
|
|||
|
22
|
|||
|
23
|
|||
|
24
|
|||
|
25
|
|||
|
26</pre></div></td><td class="code"><div class="highlight bg-light"><pre class="mb-0"><span></span>(gdb) continue
|
|||
|
Continuing.
|
|||
|
|
|||
|
Hardware watchpoint 3: x
|
|||
|
|
|||
|
Old value = 0
|
|||
|
New value = 2
|
|||
|
main () at watch.c:13
|
|||
|
14 int y = helper (x);
|
|||
|
(gdb) continue
|
|||
|
Continuing.
|
|||
|
|
|||
|
Breakpoint 2, helper (input=2) at watch.c:6
|
|||
|
7 return input + 1;
|
|||
|
(gdb) continue
|
|||
|
Continuing.
|
|||
|
|
|||
|
Hardware watchpoint 3: x
|
|||
|
|
|||
|
Old value = 2
|
|||
|
New value = 10
|
|||
|
main () at watch.c:15
|
|||
|
16 printf ("x = %d; y = %d\n", x, y);
|
|||
|
(gdb) print x
|
|||
|
$1 = 10
|
|||
|
(gdb)
|
|||
|
</pre></div>
|
|||
|
</td></tr></table></div>
|
|||
|
<p>In this session, we can observe the effects of the watchpoint and breakpoint that we set previously.
|
|||
|
When GDB encounters code that changes the value of a variable being observed with a watchpoint, it
|
|||
|
will pause the execution to indicate the old and new values (<code class="docutils literal notranslate"><span class="pre">x</span></code> has changed from 0 to 5), as well
|
|||
|
as the next line of code when execution resumes (line 13 to call the <code class="docutils literal notranslate"><span class="pre">helper()</span></code> function). By
|
|||
|
continuing a second time (line 10), this session encounters the breakpoint when the execution of
|
|||
|
<code class="docutils literal notranslate"><span class="pre">helper()</span></code> begins. Using breakpoints like this makes it easy to skip over large chunks of code and
|
|||
|
pausing right before the execution of a function that we wish to focus on. Line 15 of this session
|
|||
|
performs another continue, pausing on line 15 of the code; as <code class="docutils literal notranslate"><span class="pre">x</span></code>’s value changes from 5 to 10,
|
|||
|
the watchpoint is triggered again. Finally, note that we can also print in-scope variables at any
|
|||
|
point to observe their current value (line 24).</p>
|
|||
|
<p>To illustrate the end of a GDB session, we execute the <code class="docutils literal notranslate"><span class="pre">continue</span></code> command two more times. The
|
|||
|
first continue causes an interrupt to arise when the <code class="docutils literal notranslate"><span class="pre">return</span></code> from <code class="docutils literal notranslate"><span class="pre">main()</span></code> occurs. Once this
|
|||
|
<code class="docutils literal notranslate"><span class="pre">return</span></code> happens, the variable <code class="docutils literal notranslate"><span class="pre">x</span></code> no longer exists, so the watchpoint can be deleted (lines 5
|
|||
|
and 6). Note that this deletion implies GDB can distinguish between the variable being temporarily
|
|||
|
out of scope (as <code class="docutils literal notranslate"><span class="pre">x</span></code> is not in scope while <code class="docutils literal notranslate"><span class="pre">helper()</span></code> is executing) and being no longer needed.
|
|||
|
Lines 7 – 9 of this session can be ignored here, as it is simply GDB informing us (indirectly) that
|
|||
|
the source code containing the next line to execute cannot be found; this typically happens when GDB
|
|||
|
pauses during the executing of the C standard library, as these libraries are not compiled with
|
|||
|
debugging symbols included. The last continue (line 10) runs the program until it finishes, with
|
|||
|
line 12 informing us that the process has been terminated.</p>
|
|||
|
<div class="highlight-none border border-dark rounded-lg bg-light px-0 mb-3 notranslate"><table class="highlighttable"><tr><td class="linenos px-0 mx-0"><div class="linenodiv"><pre class="mb-0"> 1
|
|||
|
2
|
|||
|
3
|
|||
|
4
|
|||
|
5
|
|||
|
6
|
|||
|
7
|
|||
|
8
|
|||
|
9
|
|||
|
10
|
|||
|
11
|
|||
|
12
|
|||
|
13</pre></div></td><td class="code"><div class="highlight bg-light"><pre class="mb-0"><span></span>(gdb) continue
|
|||
|
Continuing.
|
|||
|
x = 10; y = 6
|
|||
|
|
|||
|
Watchpoint 3 deleted because the program has left the block in
|
|||
|
which its expression is valid.
|
|||
|
__libc_start_main (main=0x555555554659 <main>, argc=2, argv=0x7fffffffea18, init=<optimized out>,
|
|||
|
fini=<optimized out>, rtld_fini=<optimized out>, stack_end=0x7fffffffea08) at ../csu/libc-start.c:344
|
|||
|
344 ../csu/libc-start.c: No such file or directory.
|
|||
|
(gdb) continue
|
|||
|
Continuing.
|
|||
|
[Inferior 1 (process 16005) exited normally]
|
|||
|
(gdb)
|
|||
|
</pre></div>
|
|||
|
</td></tr></table></div>
|
|||
|
</div>
|
|||
|
<div class="section" id="backtrace">
|
|||
|
<h3>10.2.2.2. Backtrace<a class="headerlink" href="Debugging.html#backtrace" title="Permalink to this headline">¶</a></h3>
|
|||
|
<p>One significant source of frustration for systems programming is the lack of information regarding
|
|||
|
segmentation faults. <em>Backtrace</em> is an essential tool for debugging segmentation faults, such
|
|||
|
as the code shown in <a class="reference external" href="Debugging.html#cla-2">Code Listing A.2</a>.</p>
|
|||
|
<div class="highlight-c border border-dark rounded-lg bg-light px-0 mb-3 notranslate" id="cla-2"><table class="highlighttable"><tr><td class="linenos px-0 mx-0"><div class="linenodiv"><pre class="mb-0"> 1
|
|||
|
2
|
|||
|
3
|
|||
|
4
|
|||
|
5
|
|||
|
6
|
|||
|
7
|
|||
|
8
|
|||
|
9
|
|||
|
10
|
|||
|
11
|
|||
|
12
|
|||
|
13
|
|||
|
14
|
|||
|
15
|
|||
|
16
|
|||
|
17</pre></div></td><td class="code"><div class="highlight bg-light"><pre class="mb-0"><span></span><span class="cm">/* Code Listing A.2:</span>
|
|||
|
<span class="cm"> Dereferencing a NULL pointer to trigger a segmentation fault</span>
|
|||
|
<span class="cm"> */</span>
|
|||
|
|
|||
|
<span class="kt">void</span>
|
|||
|
<span class="nf">segfault</span> <span class="p">(</span><span class="kt">int</span> <span class="n">value</span><span class="p">)</span>
|
|||
|
<span class="p">{</span>
|
|||
|
<span class="kt">int</span> <span class="o">*</span><span class="n">nullptr</span> <span class="o">=</span> <span class="p">(</span><span class="kt">int</span> <span class="o">*</span><span class="p">)</span> <span class="n">value</span><span class="p">;</span>
|
|||
|
<span class="o">*</span><span class="n">ptr</span> <span class="o">=</span> <span class="mi">5</span><span class="p">;</span>
|
|||
|
<span class="p">}</span>
|
|||
|
|
|||
|
<span class="kt">int</span>
|
|||
|
<span class="nf">main</span> <span class="p">(</span><span class="kt">void</span><span class="p">)</span>
|
|||
|
<span class="p">{</span>
|
|||
|
<span class="n">segfault</span> <span class="p">();</span>
|
|||
|
<span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
|
|||
|
<span class="p">}</span>
|
|||
|
</pre></div>
|
|||
|
</td></tr></table></div>
|
|||
|
<p>Compiling and running this program would produce the following unhelpful results: <a class="footnote-reference" href="Debugging.html#f53" id="id5">[3]</a></p>
|
|||
|
<div class="highlight-none border border-dark rounded-lg bg-light px-2 mb-3 notranslate"><div class="highlight bg-light"><pre class="mb-0"><span></span>$ gcc -g -o segfault segfault.c
|
|||
|
segfault.c: In function ‘segfault’:
|
|||
|
segfault.c:4:18: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
|
|||
|
int *nullptr = (int *) value;
|
|||
|
^
|
|||
|
$ ./segfault
|
|||
|
Segmentation fault
|
|||
|
</pre></div>
|
|||
|
</div>
|
|||
|
<p>Diagnosing and fixing segmentation faults can be very difficult. One reason is that the message above provides
|
|||
|
no information about what line of code was executing when the segmentation fault occurred. Many
|
|||
|
programmers, particularly novices, try to address this with “<code class="docutils literal notranslate"><span class="pre">printf()</span></code> debugging,” the ad hoc
|
|||
|
approach of adding <code class="docutils literal notranslate"><span class="pre">printf()</span></code> statements to the code. This approach is inefficient and ineffective
|
|||
|
for a number of reasons. First, it requires re-editing and re-compiling the program. Second, adding
|
|||
|
any code, including <code class="docutils literal notranslate"><span class="pre">printf()</span></code>, <strong>changes the program</strong>. In some cases, this seemingly innocuous
|
|||
|
change will cause the segmentation fault to disappear—but only if the <code class="docutils literal notranslate"><span class="pre">printf()</span></code> stays in the
|
|||
|
code; removing the <code class="docutils literal notranslate"><span class="pre">printf()</span></code> brings the segmentation fault back. Lastly, adding code increases
|
|||
|
the opportunity for bugs to cause misleading results. For instance, changing the <code class="docutils literal notranslate"><span class="pre">main()</span></code> of <a class="reference external" href="Debugging.html#cla-2">Code
|
|||
|
Listing A.2</a> to that shown in <a class="reference external" href="Debugging.html#cla-3">Code Listing A.3</a> will produce identical results;
|
|||
|
without a <code class="docutils literal notranslate"><span class="pre">'\n'</span></code>, the <code class="docutils literal notranslate"><span class="pre">STDOUT</span></code> buffer will not be flushed and the message in the <code class="docutils literal notranslate"><span class="pre">printf()</span></code>
|
|||
|
will never be displayed to the screen.</p>
|
|||
|
<div class="highlight-c border border-dark rounded-lg bg-light px-0 mb-3 notranslate" id="cla-3"><table class="highlighttable"><tr><td class="linenos px-0 mx-0"><div class="linenodiv"><pre class="mb-0"> 1
|
|||
|
2
|
|||
|
3
|
|||
|
4
|
|||
|
5
|
|||
|
6
|
|||
|
7
|
|||
|
8
|
|||
|
9
|
|||
|
10
|
|||
|
11</pre></div></td><td class="code"><div class="highlight bg-light"><pre class="mb-0"><span></span><span class="cm">/* Code Listing A.3:</span>
|
|||
|
<span class="cm"> Printing without newlines may prevent the display of the message</span>
|
|||
|
<span class="cm"> */</span>
|
|||
|
|
|||
|
<span class="kt">int</span>
|
|||
|
<span class="nf">main</span> <span class="p">(</span><span class="kt">void</span><span class="p">)</span>
|
|||
|
<span class="p">{</span>
|
|||
|
<span class="n">printf</span> <span class="p">(</span><span class="s">"Hello from main()"</span><span class="p">);</span>
|
|||
|
<span class="n">segfault</span> <span class="p">();</span>
|
|||
|
<span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
|
|||
|
<span class="p">}</span>
|
|||
|
</pre></div>
|
|||
|
</td></tr></table></div>
|
|||
|
<p>GDB’s <code class="docutils literal notranslate"><span class="pre">backtrace</span></code> utility provides a more efficient and effective approach to debugging. Line 10
|
|||
|
of this GDB session informs us that GDB encountered a segmentation fault (<code class="docutils literal notranslate"><span class="pre">SIGSEGV)</span></code> while
|
|||
|
executing line 5 of <a class="reference external" href="Debugging.html#cla-2">Code Listing A.2</a>. Line 11 also provides information about the
|
|||
|
function that was executing at the time (<code class="docutils literal notranslate"><span class="pre">segfault()</span></code>), and what its current input arguments were
|
|||
|
(<code class="docutils literal notranslate"><span class="pre">value=0</span></code>). That information might be enough if the function is only called once or if the
|
|||
|
relationship between the arguments and the segmentation fault is clear. However, it is often the
|
|||
|
case that more context is needed; in order to debug the segmentation fault, we need to know what
|
|||
|
specific call—including the arguments passed and where it was called from—produced these results.
|
|||
|
This information is provided by <code class="docutils literal notranslate"><span class="pre">backtrace</span></code>, which shows the sequence of function calls that led
|
|||
|
to the segmentation fault.</p>
|
|||
|
<div class="highlight-none border border-dark rounded-lg bg-light px-0 mb-3 notranslate"><table class="highlighttable"><tr><td class="linenos px-0 mx-0"><div class="linenodiv"><pre class="mb-0"> 1
|
|||
|
2
|
|||
|
3
|
|||
|
4
|
|||
|
5
|
|||
|
6
|
|||
|
7
|
|||
|
8
|
|||
|
9
|
|||
|
10
|
|||
|
11
|
|||
|
12
|
|||
|
13
|
|||
|
14
|
|||
|
15
|
|||
|
16</pre></div></td><td class="code"><div class="highlight bg-light"><pre class="mb-0"><span></span>(gdb) start
|
|||
|
Temporary breakpoint 1 at 0x61b: file segfault.c, line 11.
|
|||
|
Starting program: /home/csf/segfault
|
|||
|
|
|||
|
Temporary breakpoint 1, main () at segfault.c:11
|
|||
|
11 segfault (0);
|
|||
|
(gdb) continue
|
|||
|
Continuing.
|
|||
|
|
|||
|
Program received signal SIGSEGV, Segmentation fault.
|
|||
|
0x000055555555460e in segfault (value=0) at segfault.c:5
|
|||
|
5 *nullptr = 5;
|
|||
|
(gdb) backtrace
|
|||
|
#0 0x000055555555460e in segfault (value=0) at segfault.c:5
|
|||
|
#1 0x0000555555554625 in main () at segfault.c:11
|
|||
|
(gdb)
|
|||
|
</pre></div>
|
|||
|
</td></tr></table></div>
|
|||
|
<p>Lines 14 and 15 show that the segmentation fault occurred while executing line 5 of <a class="reference external" href="Debugging.html#cla-2">Code Listing
|
|||
|
A.2</a>. This line exists within the <code class="docutils literal notranslate"><span class="pre">segfault()</span></code> function, which was specifically called
|
|||
|
with the argument <code class="docutils literal notranslate"><span class="pre">value=0</span></code>. The call to <code class="docutils literal notranslate"><span class="pre">segfault(0)</span></code> occurred on line 11 of the code, which
|
|||
|
exists as part of the call to <code class="docutils literal notranslate"><span class="pre">main()</span></code>. Unless the contents of the stack have become corrupted
|
|||
|
(which go beyond our discussion here), this history will show the full trace <a class="footnote-reference" href="Debugging.html#f54" id="id9">[4]</a> back to the
|
|||
|
<code class="docutils literal notranslate"><span class="pre">main()</span></code> context. That information provides more context that the programmer can use to determine
|
|||
|
what might be the root cause of the segmentation fault.</p>
|
|||
|
</div>
|
|||
|
<div class="section" id="tracing-multiple-processes">
|
|||
|
<h3>10.2.2.3. Tracing multiple processes<a class="headerlink" href="Debugging.html#tracing-multiple-processes" title="Permalink to this headline">¶</a></h3>
|
|||
|
<p>Debugging segmentation faults—and other bugs—with multiple processes can be particularly
|
|||
|
challenging. For one thing, the asynchronous timing of the execution might intersperse output
|
|||
|
messages in odd ways. Even more frustrating, messages written to the <code class="docutils literal notranslate"><span class="pre">STDERR</span></code> stream are also lost
|
|||
|
unless the output streams are specifically linked. Consider the example shown in <a class="reference external" href="Debugging.html#cla-4">Code Listing A.4</a>, which uses a slight variant on the same <code class="docutils literal notranslate"><span class="pre">segfault()</span></code> function from <a class="reference external" href="Debugging.html#cla-2">Code Listing A.2</a>.</p>
|
|||
|
<div class="highlight-c border border-dark rounded-lg bg-light px-0 mb-3 notranslate" id="cla-4"><table class="highlighttable"><tr><td class="linenos px-0 mx-0"><div class="linenodiv"><pre class="mb-0"> 1
|
|||
|
2
|
|||
|
3
|
|||
|
4
|
|||
|
5
|
|||
|
6
|
|||
|
7
|
|||
|
8
|
|||
|
9
|
|||
|
10
|
|||
|
11
|
|||
|
12
|
|||
|
13
|
|||
|
14
|
|||
|
15
|
|||
|
16
|
|||
|
17
|
|||
|
18
|
|||
|
19
|
|||
|
20
|
|||
|
21
|
|||
|
22
|
|||
|
23
|
|||
|
24
|
|||
|
25
|
|||
|
26
|
|||
|
27
|
|||
|
28
|
|||
|
29
|
|||
|
30</pre></div></td><td class="code"><div class="highlight bg-light"><pre class="mb-0"><span></span><span class="cm">/* Code Listing A.4:</span>
|
|||
|
<span class="cm"> The child's "Segmentation fault" will not appear on screen</span>
|
|||
|
<span class="cm"> */</span>
|
|||
|
|
|||
|
<span class="cp">#include</span> <span class="cpf"><assert.h></span><span class="cp"></span>
|
|||
|
<span class="cp">#include</span> <span class="cpf"><stdio.h></span><span class="cp"></span>
|
|||
|
<span class="cp">#include</span> <span class="cpf"><sys/wait.h></span><span class="cp"></span>
|
|||
|
<span class="cp">#include</span> <span class="cpf"><unistd.h></span><span class="cp"></span>
|
|||
|
|
|||
|
<span class="kt">void</span>
|
|||
|
<span class="nf">segfault</span> <span class="p">(</span><span class="kt">int</span> <span class="o">*</span><span class="n">ptr</span><span class="p">)</span>
|
|||
|
<span class="p">{</span>
|
|||
|
<span class="o">*</span><span class="n">ptr</span> <span class="o">=</span> <span class="mi">5</span><span class="p">;</span>
|
|||
|
<span class="p">}</span>
|
|||
|
|
|||
|
<span class="kt">int</span>
|
|||
|
<span class="nf">main</span> <span class="p">(</span><span class="kt">void</span><span class="p">)</span>
|
|||
|
<span class="p">{</span>
|
|||
|
<span class="kt">int</span> <span class="o">*</span><span class="n">nullptr</span> <span class="o">=</span> <span class="nb">NULL</span><span class="p">;</span>
|
|||
|
<span class="kt">pid_t</span> <span class="n">child</span> <span class="o">=</span> <span class="n">fork</span> <span class="p">();</span>
|
|||
|
<span class="n">assert</span> <span class="p">(</span><span class="n">child</span> <span class="o">>=</span> <span class="mi">0</span><span class="p">);</span>
|
|||
|
|
|||
|
<span class="k">if</span> <span class="p">(</span><span class="n">child</span> <span class="o">==</span> <span class="mi">0</span><span class="p">)</span>
|
|||
|
<span class="n">segfault</span> <span class="p">(</span><span class="n">nullptr</span><span class="p">);</span>
|
|||
|
<span class="k">else</span>
|
|||
|
<span class="n">wait</span> <span class="p">(</span><span class="nb">NULL</span><span class="p">);</span>
|
|||
|
|
|||
|
<span class="n">printf</span> <span class="p">(</span><span class="s">"Goodbye</span><span class="se">\n</span><span class="s">"</span><span class="p">);</span>
|
|||
|
<span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
|
|||
|
<span class="p">}</span>
|
|||
|
</pre></div>
|
|||
|
</td></tr></table></div>
|
|||
|
<p>As with the previous cases, running this code should result in a segmentation fault. However, the
|
|||
|
results would actually look as follows:</p>
|
|||
|
<div class="highlight-none border border-dark rounded-lg bg-light px-2 mb-3 notranslate"><div class="highlight bg-light"><pre class="mb-0"><span></span>$ gcc -g -o forkfault forkfault.c
|
|||
|
$ ./forkfault
|
|||
|
Goodbye
|
|||
|
</pre></div>
|
|||
|
</div>
|
|||
|
<p>In this case, the parent process calls <code class="docutils literal notranslate"><span class="pre">fork()</span></code> to create a child process. Based on the
|
|||
|
nondeterministic timing of process scheduling, either the parent continues executing or the child
|
|||
|
runs first. This nondeterminism is not an issue here, though; if the parent runs, it calls
|
|||
|
<code class="docutils literal notranslate"><span class="pre">wait()</span></code> until the child runs to completion. Consequently, when the parent executes the
|
|||
|
<code class="docutils literal notranslate"><span class="pre">printf()</span></code> call on line 24, the child has been guaranteed to run to completion; that child process
|
|||
|
definitely terminated with a segmentation fault because of the code on line 13. The reason the
|
|||
|
child’s error message does not appear on the terminal is that the child process’s <code class="docutils literal notranslate"><span class="pre">STDERR</span></code> output
|
|||
|
stream is thrown away.</p>
|
|||
|
<p>To debug these kinds of errors in multiple processes, GDB allows you to specify which process to
|
|||
|
follow when a <code class="docutils literal notranslate"><span class="pre">fork()</span></code> occurs. Specifically, the default behavior is that GDB will follow the
|
|||
|
parent; if you use next or continue to move past a <code class="docutils literal notranslate"><span class="pre">fork()</span></code>, GDB will show a message about a new
|
|||
|
process but continue executing the parent. To change this behavior, the set command can be used to
|
|||
|
change GDB’s <code class="docutils literal notranslate"><span class="pre">follow-fork-mode</span></code> setting as shown below. Based on this new setting, GDB will switch
|
|||
|
to the child process after the call to <code class="docutils literal notranslate"><span class="pre">fork()</span></code>; additional GDB commands will be sent to the child
|
|||
|
process rather than the parent.</p>
|
|||
|
<div class="highlight-none border border-dark rounded-lg bg-light px-2 mb-3 notranslate"><div class="highlight bg-light"><pre class="mb-0"><span></span>(gdb) start
|
|||
|
Temporary breakpoint 2 at 0x6f7: file forkfault.c, line 15.
|
|||
|
Starting program: /home/csf/forkfault
|
|||
|
|
|||
|
Breakpoint 1, main () at forkfault.c:15
|
|||
|
15 int *nullptr = NULL;
|
|||
|
(gdb) set follow-fork-mode child
|
|||
|
(gdb) continue
|
|||
|
Continuing.
|
|||
|
[New process 9666]
|
|||
|
|
|||
|
Thread 2.1 "forkfault" received signal SIGSEGV, Segmentation fault.
|
|||
|
[Switching to process 9666]
|
|||
|
0x0000555555554726 in segfault (ptr=0x0) at forkfault.c:9
|
|||
|
9 *ptr = 5;
|
|||
|
(gdb) backtrace
|
|||
|
#0 0x0000555555554726 in segfault (ptr=0x0) at forkfault.c:9
|
|||
|
#1 0x000055555555477e in main () at forkfault.c:20
|
|||
|
(gdb)
|
|||
|
</pre></div>
|
|||
|
</div>
|
|||
|
<p>The full GDB manual provides much more information about debugging multiple processes. One
|
|||
|
particularly useful command is <code class="docutils literal notranslate"><span class="pre">info</span> <span class="pre">proc</span></code>, which can be used to examine information about the
|
|||
|
status of a process, including any memory map regions, memory usage, number of threads, and many
|
|||
|
others. Information on <code class="docutils literal notranslate"><span class="pre">info</span> <span class="pre">proc</span></code> can be found at:</p>
|
|||
|
<blockquote>
|
|||
|
<div><ul class="simple">
|
|||
|
<li><a class="reference external" href="https://sourceware.org/gdb/current/onlinedocs/gdb/Process-Information.html">https://sourceware.org/gdb/current/onlinedocs/gdb/Process-Information.html</a></li>
|
|||
|
</ul>
|
|||
|
</div></blockquote>
|
|||
|
<table class="docutils footnote" frame="void" id="f51" rules="none">
|
|||
|
<colgroup><col class="label" /><col /></colgroup>
|
|||
|
<tbody valign="top">
|
|||
|
<tr><td class="label"><a class="fn-backref" href="Debugging.html#id1">[1]</a></td><td>The use of web searches and sites like Stack Overflow also raise serious ethical concerns
|
|||
|
about attribution and plagiarism. Reusing others’ code, particularly without properly citing these
|
|||
|
sources or documenting that the use is permitted, can lead to legal ramifications in professional
|
|||
|
practice and to academic misconduct charges.</td></tr>
|
|||
|
</tbody>
|
|||
|
</table>
|
|||
|
<table class="docutils footnote" frame="void" id="f52" rules="none">
|
|||
|
<colgroup><col class="label" /><col /></colgroup>
|
|||
|
<tbody valign="top">
|
|||
|
<tr><td class="label"><a class="fn-backref" href="Debugging.html#id2">[2]</a></td><td>Homebrew can be installed from <code class="docutils literal notranslate"><span class="pre">https://brew.sh</span></code>. Once Homebrew is installed, the OpenSSL library can be installed by running <code class="docutils literal notranslate"><span class="pre">brew</span> <span class="pre">install</span> <span class="pre">openssl</span></code>.</td></tr>
|
|||
|
</tbody>
|
|||
|
</table>
|
|||
|
<table class="docutils footnote" frame="void" id="f53" rules="none">
|
|||
|
<colgroup><col class="label" /><col /></colgroup>
|
|||
|
<tbody valign="top">
|
|||
|
<tr><td class="label"><a class="fn-backref" href="Debugging.html#id5">[3]</a></td><td>First, note that the compiler tries to help us avoid the segmentation fault. Warnings are
|
|||
|
quite frequently an indication that the code is syntactically legal but semantically wrong.
|
|||
|
Technically, we’re allowed to do something, but it’s probably not going to work out correctly.</td></tr>
|
|||
|
</tbody>
|
|||
|
</table>
|
|||
|
<table class="docutils footnote" frame="void" id="f54" rules="none">
|
|||
|
<colgroup><col class="label" /><col /></colgroup>
|
|||
|
<tbody valign="top">
|
|||
|
<tr><td class="label"><a class="fn-backref" href="Debugging.html#id9">[4]</a></td><td>This type of trace might look familiar to readers with experience in other languages, such
|
|||
|
as Java or Python. Those languages include built-in exception-handling mechanisms, using the same
|
|||
|
mechanisms that GDB relies on, that provide this information for free.</td></tr>
|
|||
|
</tbody>
|
|||
|
</table>
|
|||
|
</div>
|
|||
|
</div>
|
|||
|
</div>
|
|||
|
|
|||
|
|
|||
|
</div>
|
|||
|
|
|||
|
|
|||
|
|
|||
|
<div class="container">
|
|||
|
|
|||
|
<div class="mt-4 container center">
|
|||
|
«  <a id="prevmod1" href="CLangOverview.html">10.1. C Language Reintroduction</a>
|
|||
|
  ::  
|
|||
|
<a class="uplink" href="index.html">Contents</a>
|
|||
|
  ::  
|
|||
|
<a id="nextmod1" href="BasicTypes.html">10.3. Basic Types and Pointers</a>  »
|
|||
|
</div>
|
|||
|
|
|||
|
|
|||
|
</div>
|
|||
|
|
|||
|
<br />
|
|||
|
|
|||
|
<div class="row jmu-dark-purple-bg">
|
|||
|
<div class="col-md-12">
|
|||
|
<center>
|
|||
|
<a id="contact_us" class="btn button-link-no-blue jmu-gold" rel="nofollow" href="mailto:webmaster@opencsf.org" role="button">Contact Us</a>
|
|||
|
<a id="license" class="btn button-link-no-blue jmu-gold" rel="nofollow" href="https://w3.cs.jmu.edu/kirkpams/OpenCSF/lib/license.html" target="_blank">License</a>
|
|||
|
</center>
|
|||
|
</div>
|
|||
|
</div>
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
<script src="_static/js/popper.js-1.14.7-min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
|
|||
|
<script src="_static/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
|
|||
|
</body>
|
|||
|
</html>
|