- Update developers-handbook.

PR:		docs/101388
Submitted by:	chinsan.tw at gmail.com
This commit is contained in:
Vanilla I. Shu 2006-08-05 04:48:56 +00:00
parent 118b730e80
commit 20e88e096a
Notes: svn2git 2020-12-08 03:00:23 +00:00
svn path=/head/; revision=28413
2 changed files with 124 additions and 201 deletions

View file

@ -73,11 +73,9 @@
<sect1 id="introduction-layout">
<title><filename class="directory">/usr/src</filename> 的架構</title>
<para>
完整的 FreeBSD 原始碼都在公開的 CVS repository 中。
<para>完整的 FreeBSD 原始碼都在公開的 CVS repository 中。
通常 FreeBSD 原始碼都會裝在 <filename class="directory">/usr/src</filename>
而且包含下列子目錄:
</para>
而且包含下列子目錄:</para>
<para>
<informaltable frame="none" pgwide="1">

View file

@ -23,94 +23,77 @@
<title>程式開發工具</title>
<sect1 id="tools-synopsis"><title>概敘</title>
<para>
本章將介紹如何使用一些 FreeBSD 所提供的程式開發工具(programing tools)
<para>本章將介紹如何使用一些 FreeBSD 所提供的程式開發工具(programing tools)
本章所介紹的工具程式在其他版本的 &unix; 上也可使用,
在此 <emphasis>並不會</emphasis> 嘗試描述寫程式時的每個細節,
本章大部分篇幅都是假設你以前沒有或只有少數的寫程式經驗,
不過,還是希望大多數的程式開發人員都能從中重新得到一些啟發。
</para>
不過,還是希望大多數的程式開發人員都能從中重新得到一些啟發。</para>
</sect1>
<sect1 id="tools-intro"><title>簡介</title>
<para>
FreeBSD 提供一個非常棒的開發環境,
<para>FreeBSD 提供一個非常棒的開發環境,
比如說像是 C、C++、Fortran 和 assembler(組合語言)的編譯器(compiler),
在 FreeBSD 中都已經包含在基本的系統中了
更別提 Perl 和其他標準 &unix; 工具,像是<command>sed</command> 以及 <command>awk</command>
如果你還是覺得不夠FreeBSD在 Ports collection 中還提供其他的編譯器和直譯器(interpreter),
FreeBSD 相容許多標準,像是 <acronym>&posix;</acronym> 和 <acronym>ANSI</acronym> C
當然還有它所繼承的 BSD 傳統。
所以在 FreeBSD 上寫的程式不需修改或頂多稍微修改,就可以在許多平台上編譯、執行。
</para>
所以在 FreeBSD 上寫的程式不需修改或頂多稍微修改,就可以在許多平台上編譯、執行。</para>
<para>
無論如何,就算你從來沒在 &unix; 平台上寫過程式也可以徹底感受到FreeBSD 令人無法抗拒的迷人魔力。
<para>無論如何,就算你從來沒在 &unix; 平台上寫過程式也可以徹底感受到FreeBSD 令人無法抗拒的迷人魔力。
本章的目標就是協助你快速上手,而暫時不需深入太多進階主題,
並且講解一些基礎概念,以讓你可以瞭解我們在講些什麼。
</para>
並且講解一些基礎概念,以讓你可以瞭解我們在講些什麼。</para>
<para>
本章內容並不要求你得有程式開發經驗,或者你只有一點點的經驗而已。
<para>本章內容並不要求你得有程式開發經驗,或者你只有一點點的經驗而已。
不過,我們假設你已經會 &unix; 系統的基本操作,
而且更重要的是,請保持樂於學習的心態!
</para>
而且更重要的是,請保持樂於學習的心態!</para>
</sect1>
<sect1 id="tools-programming">
<title>Programming 概念</title>
<para>
簡單的說,程式只是一堆指令的集合體;而這些指令是用來告訴電腦應該要作那些事情。
<para>簡單的說,程式只是一堆指令的集合體;而這些指令是用來告訴電腦應該要作那些事情。
有時候,指令的執行取決於前一個指令的結果而定。
本章將會告訴你有 2 個主要的方法,讓你可以對電腦下達這些指示(instruction) 或 <quote>命令(commands)</quote>。
第一個方法就是 <firstterm>直譯器(interpreter)</firstterm>
而第二個方法是 <firstterm>編譯器(compiler)</firstterm>。
由於對於電腦而言,人類語言的語意過於模糊而太難理解,
因此命令(commands)就常會以一種(或多種)程式語言寫成,用來指示電腦所要執行的特定動作為何。
</para>
因此命令(commands)就常會以一種(或多種)程式語言寫成,用來指示電腦所要執行的特定動作為何。</para>
<sect2>
<title>直譯器</title>
<para>
使用直譯器時,所使用的程式語言就像變成一個會和你互動的環境。
<para>使用直譯器時,所使用的程式語言就像變成一個會和你互動的環境。
當在命令提示列上打上命令時,直譯器會即時執行該命令。
在比較複雜的程式中,可以把所有想下達的命令統統輸入到某檔案裡面去,
然後呼叫直譯器去讀取該檔案,並且執行你寫在這個檔案中的指令。
如果所下的指令有錯誤產生,大多數的直譯器會進入偵錯模式(debugger)
並且顯示相關錯誤訊息,以便對程式除錯。
</para>
並且顯示相關錯誤訊息,以便對程式除錯。</para>
<para>
這種方式好處在於:可以立刻看到指令的執行結果,以及錯誤也可迅速修正。
相對的,最大的壞處便是當你想把你寫的程式分享給其他人時,這些人必須要有跟你一樣的直譯器。
而且別忘了,他們也要會使用直譯器直譯程式才行。
當然使用者也不希望不小心按錯鍵,就進入偵錯模式而不知所措。
就執行效率而言,直譯器會使用到很多的記憶體,
而且這類直譯式程式,通常並不會比編譯器所編譯的程式的更有效率。
</para>
<para>這種方式好處在於:可以立刻看到指令的執行結果,以及錯誤也可迅速修正。
相對的,最大的壞處便是當你想把你寫的程式分享給其他人時,這些人必須要有跟你一樣的直譯器。
而且別忘了,他們也要會使用直譯器直譯程式才行。
當然使用者也不希望不小心按錯鍵,就進入偵錯模式而不知所措。
就執行效率而言,直譯器會使用到很多的記憶體,
而且這類直譯式程式,通常並不會比編譯器所編譯的程式的更有效率。</para>
<para>
筆者個人認為,如果你之前沒有學過任何程式語言,最好先學學習直譯式語言(interpreted languages)
像是 LispSmalltalkPerl 和 Basic 都是,&unix; 的 shell 像是 <command>sh</command> 和 <command>csh</command>
它們本身就是直譯器,事實上,很多人都在它們自己機器上撰寫各式的 shell <quote>script</quote>
來順利完成各項 <quote>housekeeping(維護)</quote> 任務。
&unix; 使用哲學之一就是提供大量的小工具,
並使用 shell script 來組合運用這些小工具,以便工作更有效率。
<para>筆者個人認為,如果你之前沒有學過任何程式語言,最好先學學習直譯式語言(interpreted languages)
像是 LispSmalltalkPerl 和 Basic 都是,&unix; 的 shell 像是 <command>sh</command> 和 <command>csh</command>
它們本身就是直譯器,事實上,很多人都在它們自己機器上撰寫各式的 shell <quote>script</quote>
來順利完成各項 <quote>housekeeping(維護)</quote> 任務。
&unix; 的使用哲學之一就是提供大量的小工具,
並使用 shell script 來組合運用這些小工具,以便工作更有效率。</para>
</sect2>
<sect2>
<title>FreeBSD 提供的直譯器</title>
<para>
下面這邊有份 &os; Ports Collection 所提供的直譯器清單,還有討論一些比較受歡迎的直譯式語言</para>
<para>下面這邊有份 &os; Ports Collection 所提供的直譯器清單,還有討論一些比較受歡迎的直譯式語言</para>
<para>
至於如何使用 Ports Collection 安裝的說明,可參閱 FreeBSD Handbook 中的
<para>至於如何使用 Ports Collection 安裝的說明,可參閱 FreeBSD Handbook 中的
<ulink url="&url.books.handbook;/ports-using.html">Ports章節</ulink>。
<variablelist>
<varlistentry>
@ -146,8 +129,7 @@
,此外 CMUCL(包含一個已經最佳化的編譯器)
以及其他簡化版的 LISP 直譯器(比如以 C 語言寫的 SLisp只用幾百行程式碼就實作大多數 Common Lisp 的功能)
則是分別收錄在 <filename role="package">lang/cmucl</filename> 以及
<filename role="package">lang/slisp</filename>。
</para>
<filename role="package">lang/slisp</filename>。</para>
</listitem>
</varlistentry>
@ -169,8 +151,7 @@
<listitem>
<para>Scheme 是 LISP 的另一分支Scheme 的特點就是比 Common LISP 還要簡潔有力。
由於 Scheme 簡單,所以很多大學拿來當作第一堂程式語言教學教材。
而且對於研究人員來說也可以快速的開發他們所需要的程式。
</para>
而且對於研究人員來說也可以快速的開發他們所需要的程式。</para>
<para>Scheme 收錄在 <filename role="package">lang/elk</filename>
Elk Scheme 直譯器(由麻省理工學院所發展的 Scheme 直譯器)收錄在
@ -208,8 +189,7 @@
<para>Python 是物件導向的直譯式語言,
Python 的擁護者總是宣稱 Python 是最好入門的程式語言。
雖然 Python 可以很簡單的開始,但是不代表它就會輸給其他直譯式語言(像是 Perl 和 Tcl)
事實證明 Python 也可以拿來開發大型、複雜的應用程式。
</para>
事實證明 Python 也可以拿來開發大型、複雜的應用程式。</para>
<para>&os; Ports Collection 收錄在 <filename role="package">lang/python</filename>。</para>
</listitem>
@ -245,9 +225,9 @@
<title>編譯器</title>
<para>編譯器和直譯器兩者相比的話,有些不同,首先就是必須先把程式碼統統寫入到檔案裡面,
然後必須執行編譯器來試著編譯程式,如果編譯器不接受所寫的程式,那就必須一直修改程式,
直到編譯器接受且把你的程式編譯成執行檔。
此外,也可以在提示命令列,或在除錯器中執行你編譯好的程式看看它是否可以運作。
然後必須執行編譯器來試著編譯程式,如果編譯器不接受所寫的程式,那就必須一直修改程式,
直到編譯器接受且把你的程式編譯成執行檔。
此外,也可以在提示命令列,或在除錯器中執行你編譯好的程式看看它是否可以運作。
<footnote>
<para>如果在提示命令列下執行,那麼有可能會產生 core dump。</para>
</footnote></para>
@ -260,8 +240,7 @@
而編譯器與直譯器最大的差別在於:當你想把你寫好的程式拿到另外一台機器上跑時,
你只要將編譯器編譯出來的可執行檔,拿到新機器上便可以執行,
而直譯器則必須要求新機器上,必須要有跟另一台機器上相同的直譯器,
才能組譯執行你的程式!
</para>
才能組譯執行你的程式!</para>
<para>編譯式的程式語言包含 Pascal、C 和 C++
C 和 C++ 不是一個親和力十足的語言,但是很適合具有經驗的 Programmer。
@ -271,8 +250,10 @@
<filename role="package">lang/gpc</filename> 和 <filename role="package">lang/fpc</filename> 中找到。</para>
<para>如果你用不同的程式來寫編譯式程式,那麼不斷地編輯-編譯-執行-除錯的這個循環肯定會很煩人,
為了更簡化、方便程式開發流程,很多商業編譯器廠商開始發展所謂的 <acronym>IDE</acronym>(Integrated Development Environments) 開發環境,
FreeBSD 預設並沒有把 IDE 整合進 base system 中,但是你可透過 <filename role="package">devel/kdevelop</filename> 安裝 kdevelop
為了更簡化、方便程式開發流程,很多商業編譯器廠商開始發展所謂的 <acronym>IDE</acronym>
(Integrated Development Environments) 開發環境,
FreeBSD 預設並沒有把 IDE 整合進 base system 中,
但是你可透過 <filename role="package">devel/kdevelop</filename> 安裝 kdevelop
或使用 <application>Emacs</application> 來體驗 IDE 開發環境。
在後面的 <xref linkend="emacs"> 專題將介紹,如何以 <application>Emacs</application> 來作為 IDE 開發環境。</para>
</sect2>
@ -338,7 +319,7 @@
<para>幸運的是,你可以不用理會以上細節,編譯器都會自動完成。
因為 <command>cc</command> 只是是個前端程式(front end),它會依照正確的參數來呼叫相關程式幫你處理。
只需打:
只需打:</para>
<screen>&prompt.user; <userinput>cc foobar.c</userinput></screen>
<para>上述指令會把 <filename>foobar.c</filename> 開始編譯,並完成上述動作。
@ -362,7 +343,7 @@
<listitem>
<para><option>-o</option> 編譯後的執行檔檔名,如果沒有使用這選項的話,
編譯好的程式預設檔名將會是 <filename>a.out</filename>
編譯好的程式預設檔名將會是 <filename>a.out</filename>
<footnote>
<para>至於 <option>-o</option> 的原因,則是一團歷史迷霧了。</para>
@ -398,8 +379,7 @@
<term><option>-g</option></term>
<listitem>
<para>
<option>-g</option> 將會把一些給 gdb 用的除錯訊息包進去執行檔裡面,所謂的除錯訊息例如:
<para><option>-g</option> 將會把一些給 gdb 用的除錯訊息包進去執行檔裡面,所謂的除錯訊息例如:
程式在第幾行出錯、那個程式第幾行做什麼函式呼叫等等。除錯資訊<emphasis>非常</emphasis>好用。
但缺點就是:對於程式來說,額外的除錯訊息會讓編譯出來的程式比較肥些。
<option>-g</option> 的適用時機在於:當程式還在開發時使用就好,
@ -426,13 +406,12 @@
<listitem>
<para><option>-O</option> 會產生最佳化的執行檔,
編譯器會使用一些技巧,來讓程式可以跑的比未經最佳化的程式還快,
你可以在大寫 O 後面加上數字來指明你想要的最佳化層級。
但是最佳化還是會有一些錯誤,舉例來說在當在 FreeBSD 2.10 release 中使用 <command>cc</command>
且指定 <option>-O2</option> 時,在某些情形下會產生錯誤的執行檔。</para>
編譯器會使用一些技巧,來讓程式可以跑的比未經最佳化的程式還快,
可以在大寫 O 後面加上數字來指明想要的最佳化層級。
但是最佳化還是會有一些錯誤,舉例來說在 FreeBSD 2.10 release 中用 <command>cc</command>
且指定 <option>-O2</option> 時,在某些情形下會產生錯誤的執行檔。</para>
<para>只有當要釋出發行版本、或者加速程式時,才需要使用最佳化選項。
</para>
<para>只有當要釋出發行版本、或者加速程式時,才需要使用最佳化選項。</para>
<informalexample>
<screen>&prompt.user; <userinput>cc -O -o foobar foobar.c</userinput>
@ -444,11 +423,9 @@
</varlistentry>
</variablelist>
<para>
以下三個參數將會強迫 <command>cc</command> 確認程式碼是否符合一些國際標準的規範,
<para>以下三個參數將會強迫 <command>cc</command> 確認程式碼是否符合一些國際標準的規範,
也就是通常說的 <acronym>ANSI</acronym> 標準,
而 <acronym>ANSI</acronym> 嚴格來講屬 <acronym>ISO</acronym> 標準。
</para>
而 <acronym>ANSI</acronym> 嚴格來講屬 <acronym>ISO</acronym> 標準。</para>
<variablelist>
<varlistentry>
@ -501,15 +478,14 @@
<para>告訴 gcc 在連結(linking)程式時你需要用到的函式庫名稱。</para>
<para>最常見的情況就是,當你在程式中使用了 C 數學函式庫,
跟其他作業平台不一樣的是,這些數學函式都不在標準函式庫(library)中,
跟其他作業平台不一樣的是,這函示學函式都不在標準函式庫(library)中,
因此編譯器並不知道這函式庫名稱,你必須告訴編譯器要加上它才行。</para>
<para>規則很簡單,如果有個函式庫叫做 <filename>lib<replaceable>something</replaceable>/a</filename>
<para>規則很簡單,如果有個函式庫叫做 <filename>lib<replaceable>something</replaceable>.a</filename>
就必須在編譯時加上參數 <option>-l<replaceable>something</replaceable></option> 才行。
舉例來說,數學函式庫叫做 <filename>libm.a</filename>
所以你必須給 <command>cc</command> 的參數就是 <option>-lm</option>。
一般情況下,通常會把這參數必須放在指令的最後。
</para>
一般情況下,通常會把這參數必須放在指令的最後。</para>
<informalexample>
<screen>&prompt.user; <userinput>cc -o foobar foobar.c -lm</userinput>
@ -522,42 +498,34 @@
<option>-lstdc++</option>。
如果你的 FreeBSD 是 2.2(含)以後版本,
你可以用指令 <command>c++</command> 來取代 <command>cc</command>。
在 FreeBSD 上 <command>c++</command> 也可以用 <command>g++</command> 取代。
</para>
在 FreeBSD 上 <command>c++</command> 也可以用 <command>g++</command> 取代。</para>
<informalexample>
<screen>&prompt.user; <userinput>cc -o foobar foobar.cc -lg++</userinput> <lineannotation>For FreeBSD 2.1.6 and earlier</lineannotation>
&prompt.user; <userinput>cc -o foobar foobar.cc -lstdc++</userinput> <lineannotation>For FreeBSD 2.2 and later</lineannotation>
<screen>&prompt.user; <userinput>cc -o foobar foobar.cc -lg++</userinput> <lineannotation>適用 FreeBSD 2.1.6 或更早期的版本</lineannotation>
&prompt.user; <userinput>cc -o foobar foobar.cc -lstdc++</userinput> <lineannotation>適用 FreeBSD 2.2 及之後的版本</lineannotation>
&prompt.user; <userinput>c++ -o foobar foobar.cc</userinput>
</screen>
</informalexample>
<para>Each of these will both produce an executable
<filename>foobar</filename> from the C++ source file
<filename>foobar.cc</filename>. Note that, on &unix;
systems, C++ source files traditionally end in
<filename>.C</filename>, <filename>.cxx</filename> or
<filename>.cc</filename>, rather than the
&ms-dos; style
<filename>.cpp</filename> (which was already used for
something else). <command>gcc</command> used to rely on
this to work out what kind of compiler to use on the
source file; however, this restriction no longer applies,
so you may now call your C++ files
<filename>.cpp</filename> with impunity!</para>
<para>上述指令都會從原始檔 <filename>foobar.cc</filename> 編譯產生名為 <filename>fooboar</filename> 的執行檔。
這邊要提醒的是在 &unix; 系統中 C++ 程式傳統都以 <filename>.C</filename>、
<filename>.cxx</filename> 或者是 <filename>.cc</filename> 作為副檔名,
而非 &ms-dos; 那種以 <filename>.cpp</filename> 作為副檔名的命名方式(不過也越來越普遍了)。
<command>gcc</command> 會依副檔名來決定用哪一種編譯器編譯,
然而,現在已經不再限制副檔名了,
所以可以自由的使用 <filename>.cpp</filename> 作為 C++ 程式碼的副檔名!</para>
</listitem>
</varlistentry>
</variablelist>
<sect2>
<title>Common <command>cc</command> Queries and Problems</title>
<title>常見的 <command>cc</command> 問題</title>
<qandaset>
<qandaentry>
<question>
<para>I am trying to write a program which uses the
<function>sin()</function> function and I get an error
like this. What does it mean?</para>
<para>我用 <function>sin()</function> 函示撰寫我的程式,
但是有個錯誤訊息(如下),這代表著?</para>
<informalexample>
<screen>/var/tmp/cc0143941.o: Undefined symbol `_sin' referenced from text segment
@ -566,10 +534,8 @@
</question>
<answer>
<para>When using mathematical functions like
<function>sin()</function>, you have to tell
<command>cc</command> to link in the math library, like
so:</para>
<para>當使用 <function>sin()</function> 這類的數學函示時,
你必須告訴 cc 要和數學函式庫作連結(linking),就像這樣:</para>
<informalexample>
<screen>&prompt.user; <userinput>cc -o foobar foobar.c -lm</userinput>
@ -580,9 +546,7 @@
<qandaentry>
<question>
<para>All right, I wrote this simple program to practice
using <option>-lm</option>. All it does is raise 2.1 to
the power of 6.</para>
<para>好吧,我試著寫些簡單的程式,來練習使用 -lm 選項(該程式會運算 2.1 的 6 次方)</para>
<informalexample>
<programlisting>#include &lt;stdio.h&gt;
@ -597,15 +561,14 @@ int main() {
</programlisting>
</informalexample>
<para>and I compiled it as:</para>
<para>然後進行編譯:</para>
<informalexample>
<screen>&prompt.user; <userinput>cc temp.c -lm</userinput>
</screen>
</informalexample>
<para>like you said I should, but I get this when I run
it:</para>
<para>編譯後執行程式,得到下面這結果:</para>
<informalexample>
<screen>&prompt.user; <userinput>./a.out</userinput>
@ -613,30 +576,24 @@ int main() {
</screen>
</informalexample>
<para>This is <emphasis>not</emphasis> the right answer!
What is going on?</para>
<para>很明顯的,程式結果<emphasis>不是</emphasis>正確答案,到底是哪邊出錯?</para>
</question>
<answer>
<para>When the compiler sees you call a function, it
checks if it has already seen a prototype for it. If it
has not, it assumes the function returns an
<type>int</type>, which is definitely not what you want
here.</para>
<para>當編譯器發現你呼叫一個函示時,它會確認該函示的回傳值類型(prototype)
如果沒有特別指明,則預設的回傳值類型為 <type>int(整數)</type>。
很明顯的,你的程式所需要的並不是回傳值類別為 <type>int</type>。</para>
</answer>
</qandaentry>
<qandaentry>
<question>
<para>So how do I fix this?</para>
<para>那如何才可以修正剛所說的問題?</para>
</question>
<answer>
<para>The prototypes for the mathematical functions are in
<filename>math.h</filename>. If you include this file,
the compiler will be able to find the prototype and it
will stop doing strange things to your
calculation!</para>
<para>數學函示的回傳值類型(prototype)會定義在 <filename>math.h</filename>
如果你有 include 這檔,編譯器就會知道該函示的回傳值類型,如此一來該運算就會得到正確的結果!</para>
<informalexample>
<programlisting>#include &lt;math.h&gt;
@ -647,8 +604,7 @@ int main() {
</programlisting>
</informalexample>
<para>After recompiling it as you did before, run
it:</para>
<para>加了上述內容之後,再重新編譯,最後執行:</para>
<informalexample>
<screen>&prompt.user; <userinput>./a.out</userinput>
@ -656,27 +612,21 @@ int main() {
</screen>
</informalexample>
<para>If you are using any of the mathematical functions,
<emphasis>always</emphasis> include
<filename>math.h</filename> and remember to link in the
math library.</para>
<para>如果有用到數學函式,<emphasis>請確定</emphasis>要有 include <filename>math.h</filename> 這檔,
而且記得要和數學函式庫作連結。</para>
</answer>
</qandaentry>
<qandaentry>
<question>
<para>I compiled a file called
<filename>foobar.c</filename> and I cannot find an
executable called <filename>foobar</filename>. Where has
it gone?</para>
<para>已經編譯好 <filename>foobar.c</filename>
但是編譯後找不到 <filename>foobar</filename> 執行檔。 該去哪邊找呢?</para>
</question>
<answer>
<para>Remember, <command>cc</command> will call the
executable <filename>a.out</filename> unless you tell it
differently. Use the
<option>-o&nbsp;<replaceable>filename</replaceable></option>
option:</para>
<para>記得,除非有指定編譯結果的執行檔檔名,否則預設的執行檔檔名是 a.out。
用 <option>-o&nbsp;<replaceable>filename</replaceable></option> 參數,
就可以達到所想要的結果,比如:</para>
<informalexample>
<screen>&prompt.user; <userinput>cc -o foobar foobar.c</userinput>
@ -687,108 +637,88 @@ int main() {
<qandaentry>
<question>
<para>OK, I have an executable called
<filename>foobar</filename>, I can see it when I run
<command>ls</command>, but when I type in
<command>foobar</command> at the command prompt it tells
me there is no such file. Why can it not find
it?</para>
<para>好,有個編譯好的程式叫做 <filename>foobar</filename>
用 <command>ls</command> 指令時可以看到,
但執行時,訊息卻說卻沒有這檔案。為什麼?</para>
</question>
<answer>
<para>Unlike &ms-dos;, &unix; does not
look in the current directory when it is trying to find
out which executable you want it to run, unless you tell
it to. Either type <command>./foobar</command>, which
means <quote>run the file called
<filename>foobar</filename> in the current
directory</quote>, or change your <envar>PATH</envar>
environment
variable so that it looks something like</para>
<para>與 &ms-dos; 不同的是,除非有指定執行檔的路徑,
否則 &unix; 系統並不會在目前的目錄下尋找你想執行的檔案。
在指令列下打 <command>./foobar</command> 代表
<quote>執行在這個目錄底下名為 <filename>foobar</filename> 的程式</quote>
或者也可以更改 <envar>PATH</envar> 環境變數設定如下,以達成類似效果:</para>
<informalexample>
<screen>bin:/usr/bin:/usr/local/bin:.
</screen>
</informalexample>
<para>The dot at the end means <quote>look in the current
directory if it is not in any of the
others</quote>.</para>
<para>上一行最後的 "." 代表<quote>如果在前面寫的其他目錄找不到,就找目前的目錄</quote>。</para>
</answer>
</qandaentry>
<qandaentry>
<question>
<para>I called my executable <filename>test</filename>,
but nothing happens when I run it. What is going
on?</para>
<para>試著執行 <filename>test</filename> 執行檔,
但是卻沒有任何事發生,到底是哪裡出錯了?</para>
</question>
<answer>
<para>Most &unix; systems have a program called
<command>test</command> in <filename>/usr/bin</filename>
and the shell is picking that one up before it gets to
checking the current directory. Either type:</para>
<para>大多數的 &unix; 系統都會在路徑 <filename>/usr/bin</filename> 擺放執行檔。
除非有指定使用在目前目錄內的 <filename>test</filename>,否則 shell 會優先選擇位在
<filename>/usr/bin</filename> 的 <filename>test</filename>
要指定檔名的話,作法類似:</para>
<informalexample>
<screen>&prompt.user; <userinput>./test</userinput>
</screen>
</informalexample>
<para>or choose a better name for your program!</para>
<para>為了避免上述困擾,請為你的程式取更好的名稱吧!</para>
</answer>
</qandaentry>
<qandaentry>
<question>
<para>I compiled my program and it seemed to run all right
at first, then there was an error and it said something
about <errorname>core dumped</errorname>. What does that
mean?</para>
<para>當執行我寫的程式時剛開始正常,
接下來卻出現 <errorname>core dumped</errorname> 錯誤訊息。這錯誤訊息到底代表什麼?</para>
</question>
<answer>
<para>The name <firstterm>core dump</firstterm> dates back
to the very early days of &unix;, when the machines used
core memory for storing data. Basically, if the program
failed under certain conditions, the system would write
the contents of core memory to disk in a file called
<filename>core</filename>, which the programmer could
then pore over to find out what went wrong.</para>
<para>關於 <firstterm>core dumped</firstterm> 這個名稱的由來,
可以追溯到早期的 &unix; 系統開始使用 core memory 對資料排序時。
基本上當程式在很多情況下發生錯誤後,
作業系統會把 core memory 中的資訊寫入 <filename>core</filename> 這檔案中,
以便讓 programmer 知道程式到底是為何出錯。</para>
</answer>
</qandaentry>
<qandaentry>
<question>
<para>Fascinating stuff, but what I am supposed to do
now?</para>
<para>真是太神奇了!程式居然發生 <errorname>core dumped</errorname> 了,該怎麼辦?</para>
</question>
<answer>
<para>Use <command>gdb</command> to analyze the core (see
<xref linkend="debugging">).</para>
<para>請用 <command>gdb</command> 來分析 core 結果(詳情請參考 <xref linkend="debugging">)。</para>
</answer>
</qandaentry>
<qandaentry>
<question>
<para>When my program dumped core, it said something about
a <errorname>segmentation fault</errorname>. What is
that?</para>
<para>當程式已經把 core memory 資料 dump 出來後,
同時也出現另一個錯誤 <errorname>segmentation fault</errorname> 這意思是?</para>
</question>
<answer>
<para>This basically means that your program tried to
perform some sort of illegal operation on memory; &unix;
is designed to protect the operating system and other
programs from rogue programs.</para>
<para>基本上,這個錯誤表示你的程式在記憶體中試著做一個嚴重的非法運作(illegal operation)
&unix; 就是被設計來保護整個作業系統免於被惡質的程式破壞,所以才會告訴你這個訊息。</para>
<para>Common causes for this are:</para>
<para>最常造成<quote>segmentation fault</quote>的原因通常為:</para>
<itemizedlist>
<listitem>
<para>Trying to write to a <symbol>NULL</symbol>
pointer, eg</para>
<para>試著對一個 <symbol>NULL</symbol> 的指標(pointer)作寫入的動作,如</para>
<programlisting>char *foo = NULL;
strcpy(foo, "bang!");
@ -796,25 +726,21 @@ strcpy(foo, "bang!");
</listitem>
<listitem>
<para>Using a pointer that has not been initialized,
eg</para>
<para>使用一個尚未初始化(initialized)的指標,如:</para>
<programlisting>char *foo;
strcpy(foo, "bang!");
</programlisting>
<para>The pointer will have some random value that,
with luck, will point into an area of memory that
is not available to your program and the kernel will
kill your program before it can do any damage. If
you are unlucky, it will point somewhere inside your
own program and corrupt one of your data structures,
causing the program to fail mysteriously.</para>
<para>尚未初始化的指標的初始值將會是隨機的,如果你夠幸運的話,
這個指標的初始值會指向 kernel 已經用到的記憶體位置,
kernel 會結束掉這個程式以確保系統運作正常。如果你不夠幸運,
初始指到的記憶體位置是你程式必須要用到的資料結構(data structures)的位置,
當這個情形發生時程式將會當的不知其所以然。</para>
</listitem>
<listitem>
<para>Trying to access past the end of an array,
eg</para>
<para>試著寫入超過陣列(array)元素個數,如:</para>
<programlisting>int bar[20];
bar[27] = 6;
@ -822,8 +748,7 @@ bar[27] = 6;
</listitem>
<listitem>
<para>Trying to store something in read-only memory,
eg</para>
<para>試著讀寫在唯讀記憶體(read-only memory)中的資料,如:</para>
<programlisting>char *foo = "My string";
strcpy(foo, "bang!");