Go to the first, previous, next, last section, table of contents.


Coding

ÄÚµù

This chapter covers topics that are lower-level than the major algorithms of GDB.

ÀÌ ÀåÀº GDBÀÇ ÁÖ¿ä ¾Ë°í¸®Áòº¸´Ù ´õ ÇÏÀ§ ·¹º§ ÁÖÁ¦µé¿¡ ´ëÇØ ´Ù·é´Ù.

Cleanups

Cleanups are a structured way to deal with things that need to be done later. When your code does something (like malloc some memory, or open a file) that needs to be undone later (e.g., free the memory or close the file), it can make a cleanup. The cleanup will be done at some future point: when the command is finished, when an error occurs, or when your code decides it's time to do cleanups.

CleanupÀº ³ªÁß¿¡ ÇÒ ÇÊ¿ä°¡ ÀÖ´Â °ÍµéÀ» ´Ù·ç±â À§ÇÑ ±¸Á¶È­µÈ ¹æ¹ýÀÌ´Ù. ¿©·¯ºÐÀÇ Äڵ尡 ³ªÁß¿¡(e.g., ¸Þ¸ð¸®¸¦ free Çϰųª fileÀ» ´Ý°Å³ª)ÇÒ ÇÊ¿ä°¡ ¾ø´Â °Í(e.g., ¸Þ¸ð¸®¸¦ malloc Çϰųª fileÀ» ¿­°Å³ª)À» ÇÒ¶§, ±×°ÍÀº cleanupÀ» ¸¸µé¼ö ÀÖ´Ù. cleanupÀº ¸î¸î ¹Ì·¡ ½ÃÁ¡¿¡¼­ ÇàÇØÁø´Ù; ¸í·É¾î¸¦ ¸¶ÃÆÀ»¶§, ¿¡·¯°¡ ÀϾ¶§, Äڵ尡 cleanupÀ» ÇؾßÇÒ¶§¶ó°í °áÁ¤ÇÒ¶§.

You can also discard cleanups, that is, throw them away without doing what they say. This is only done if you ask that it be done.

¿©·¯ºÐÀº cleanupÀ» ¹ö¸±¼ö ÀÖ´Ù. Áï, ¸»ÇÏ´Â °ÍÀ» ÇÏ´Â°Í ¾øÀÌ ¦i¾Æ ¹ö¸±¼ö ÀÖµû. ÀÌ°ÍÀº ¸¸ÀÏ ¿©·¯ºÐÀÌ ÇؾßÇϴ°ÍÀ» ¹°¾îº»´Ù¸é ÇàÇØÁø´Ù.

Syntax:

¹®¹ý:

struct cleanup *old_chain;
Declare a variable which will hold a cleanup chain handle.

cleanup chain ÇÚµéÀ» °¡Áö´Â º¯¼ö¸¦ ¼±¾ðÇÑ´Ù.

old_chain = make_cleanup (function, arg);
Make a cleanup which will cause function to be called with arg (a char *) later. The result, old_chain, is a handle that can be passed to do_cleanups or discard_cleanups later. Unless you are going to call do_cleanups or discard_cleanups yourself, you can ignore the result from make_cleanup.

³ªÁß¿¡ arg (a char *)¿Í ÇÔ²² È£ÃâµÇ´Â function¸¦ ¾ß±âÇÏ´Â cleanupÀ» ¸¸µç´Ù. ±× °á°ú old_chainÀº do_cleanups³ª discard_cleanups¿¡ Àü´ÞµÉ¼ö ÀÖ´Â ÇÚµéÀÌ´Ù. ¸¸ÀÏ ¿©·¯ºÐÀÌ do_cleanups³ª discard_cleanups¸¦ È£ÃâÇÏÁö ¾Ê´Â´Ù¸é, ¿©·¯ºÐÀº make_cleanup¿¡¼­ÀÇ °á°ú¸¦ ¹«½ÃÇÒ¼ö ÀÖ´Ù.

do_cleanups (old_chain);
Perform all cleanups done since make_cleanup returned old_chain. E.g.:

¸ðµç cleanupÀ» ÇÑ´Ù. ¿Ö³ÄÇϸé make_cleanup°¡ old_chain¸¦ ¹ÝȯÇϱ⠶§¹®ÀÌ´Ù. E.g.:

make_cleanup (a, 0); 
old = make_cleanup (b, 0); 
do_cleanups (old);
will call b() but will not call a(). The cleanup that calls a() will remain in the cleanup chain, and will be done later unless otherwise discarded.

b()´Â È£ÃâÇÏÁö¸¸ a()´Â È£ÃâÇÏÁö ¾Ê´Â´Ù. a()¸¦ È£ÃâÇÏ´Â cleanupÀº cleanup chain¿¡ ³²¾Æ ÀÖÀ¸¸ç ¹ö·ÁÁöÁö ¾Ê´Â´Ù¸é ³ªÁß¿¡ ÇàÇØÁø´Ù.

discard_cleanups (old_chain);
Same as do_cleanups except that it just removes the cleanups from the chain and does not call the specified functions.

chain¿¡¼­ cleanupÀ» Á¦°ÅÇÏ°í ÁöÁ¤µÈ ÇÔ¼ö¸¦ È£ÃâÇÏÁö ¾Ê´Â´Ù´Â Á¡À» Á¦¿ÜÇÏ°í do_cleanups¿Í °°´Ù.

Some functions, e.g. fputs_filtered() or error(), specify that they "should not be called when cleanups are not in place". This means that any actions you need to reverse in the case of an error or interruption must be on the cleanup chain before you call these functions, since they might never return to your code (they `longjmp' instead).

¸î¸î ÇÔ¼ö, e.g. fputs_filtered() ³ª error()´Â "cleanupÀÌ Á¦ÀÚ¸®¿¡ ÀÖÁö ¾ÊÀ»¶§ È£ÃâµÇ¾î¼­´Â ¾ÈµÈ´Ù"´Â °ÍÀ» °¡¸®Å²´Ù. ÀÌ°ÍÀº ¿¡·¯³ª ÀÎÅÍ·´¼ÇÀÇ °æ¿ì °Å²Ù·ÎµÇ ÇÊ¿ä°¡ ÀÖ´Â ÇൿÀº ¿©·¯ºÐÀÌ À̵é ÇÔ¼ö¸¦ È£ÃâÇϱâ Àü¿¡ cleanup chain¿¡ ÀÖ¾î¾ß ÇÑ´Ù. ¿Ö³ÄÇÏ¸é ±×°ÍµéÀº Äڵ忡¼­ ¹ÝȯÇÏÁö ¾Ê±â ¶§¹®ÀÌ´Ù.(´ë½Å¿¡ `longjmp')

Wrapping Output Lines

Output Lines ½Î±â

Output that goes through printf_filtered or fputs_filtered or fputs_demangled needs only to have calls to wrap_here added in places that would be good breaking points. The utility routines will take care of actually wrapping if the line width is exceeded.

printf_filtered³ª fputs_filtered, fputs_demangled¸¦ ÅëÇØ °¡´Â Ãâ·ÂÀº ÁÁÀº break Áö¿ªÀÌ °÷¿¡ Ãß°¡µÇ¾î wrap_here¸¦ È£ÃâÇÒ¶§¸¸ ÇÊ¿äÇÏ´Ù. utility ·çƾÀº ¸¸ÀÏ ¶óÀÎ ÆøÀÌ ÃÊ°úµÈ´Ù¸é ½ÇÁ¦ wrappingÀ¸·Î ´Ù·ï¾îÁø´Ù.

The argument to wrap_here is an indentation string which is printed only if the line breaks there. This argument is saved away and used later. It must remain valid until the next call to wrap_here or until a newline has been printed through the *_filtered functions. Don't pass in a local variable and then return!

wrap_here¿¡ ´ëÇÑ ÀÎÀÚ´Â ¸¸ÀÏ ¶óÀÎÀÌ °Å±â¼­ breakµÈ´Ù¸é Ãâ·ÂµÇ´Â µé¿©¾²¿©Áø ¹®ÀÚ¿­ÀÌ´Ù. ÀÌ ÀÎÀÚ´Â ÀúÀåµÇ°í ³ªÁß¿¡ ºÒ·ÁÁø´Ù. wrap_here¿¡ ´ëÇÑ ´ÙÀ½ È£ÃâÀ̳ª ´º ¶óÀÎÀÌ *_filtered ÇÔ¼ö¸¦ ÅëÇØ Ãâ·ÂµÉ´ë±îÁö À¯È¿ÇÏ°Ô À¯ÁöµÇ¾î¾ß ÇÑ´Ù. Áö¿ªº¯¼ö¿¡ Àü´ÞÇÏÁö ¸¶¶ó. ±×¸®°í ¹ÝȯÇÏÁö ¸¶¶ó.

It is usually best to call wrap_here after printing a comma or space. If you call it before printing a space, make sure that your indentation properly accounts for the leading space that will print if the line wraps there.

ÄÞ¸¶³ª ½ºÆäÀ̽º Ãâ·ÂÈÄ wrap_here¸¦ È£ÃâÇϴ°ÍÀÌ °¡Àå ÁÁ´Ù. ¸¸ÀÏ ¿©·¯ºÐÀÌ ½ºÆäÀ̽º Ãâ·ÂÀü¿¡ È£ÃâÇÑ´Ù¸é, µé¿©¾²±â´Â ¸¸ÀÏ ¶óÀÎÀÌ ·¹Çεȴٸé Ãâ·ÂµÉ ¼±Çà ½ºÆäÀ̽º¸¦ ¼³¸íÇÑ´Ù´Â Á¡À» È®½ÇÈ÷ Çضó.

Any function or set of functions that produce filtered output must finish by printing a newline, to flush the wrap buffer, before switching to unfiltered (printf) output. Symbol reading routines that print warnings are a good example.

¾î¶² ÇÔ¼ö³ª ÇÊÅÍµÈ Ãâ·ÂÀ» ¸¸µå´Â ÇÔ¼ö ÁýÇÕÀº wrap buffer¸¦ ºñ¿ì±â À§ÇØ ÇÊÅ͵ÇÁö ¾ÊÀº(printf) Ãâ·ÂÀ¸·Î ¹Ù²î±â Àü¿¡ newline Ãâ·Â½Ã ³¡³ª¾ß ÇÑ´Ù. °æ°í¸¦ Ãâ·ÂÇÏ´Â ½Éº¼ Àб⠷çƾÀÌ ÁÁÀº ¿¹ÀÌ´Ù.

GDB Coding Standards

GDB ÄÚµù Ç¥ÁØ

GDB follows the GNU coding standards, as described in `etc/standards.texi'. This file is also available for anonymous ftp From GNU archive sites. GDB takes a strict interpretation of the standard; in general, when the GNU standard recommends a practice but does not require it, GDB requires it.

GDB´Â `etc/standards.texi'¿¡¼­ ±â¼úÇÑ °Íó·³, GNU ÄÚµù Ç¥ÁØÀ» µû¸¥´Ù. ÀÌ ÆÄÀÏÀº GNU archive site¿¡¼­ anonymous ftp¸¦ ÅëÇØ ÀÌ¿ëÇÒ¼ö ÀÖ´Ù. GDB´Â Ç¥ÁØÀÇ ¾ö°ÝÇÑ Çؼ®À» °¡Áø´Ù.; ÀϹÝÀûÀ¸·Î, GNU Ç¥ÁØÀº ½ÇÁ¦ÀûÀΰÍÀ» ÃßõÇÏÁö¸¸ ±×°ÍÀ» ¿ä±¸ÇÏÁö´Â ¾ÊÁö¸¸, GDB´Â ÀÌ°ÍÀ» ¿ä±¸ÇÑ´Ù.

GDB follows an additional set of coding standards specific to GDB, as described in the following sections.

GDB´Â ´ÙÀ½ ¼½¼Ç¿¡¼­ ±â¼úÇÑ °Íó·³, GDB¿¡ Ãß°¡ÀûÀ¸·Î ƯÁ¤ ÄÚµù Ç¥ÁØÁýÇÕÀ» Çã¿ëÇÑ´Ù.

You can configure with `--enable-build-warnings' or `--enable-gdb-build-warnings' to get GCC to check on a number of these rules. GDB sources ought not to engender any complaints, unless they are caused by bogus host systems. (The exact set of enabled warnings is currently `-Wimplicit -Wreturn-type -Wcomment -Wtrigraphs -Wformat -Wparentheses -Wpointer-arith -Wuninitialized'.

¿©·¯ºÐÀº ÀÌ ±ÔÄ¢ÀÇ ¼ö¸¦ °Ë»çÇϵµ·Ï GCC¸¦ °¡Áö±â À§ÇØ `--enable-build-warnings' ¶Ç´Â `--enable-gdb-build-warnings'¸¦ °¡Áö°í ¼³Á¤ÇÒ¼ö ÀÖ´Ù. GDB ¼Ò½º´Â ¸¸ÀÏ °¡»ó È£½ºÆ® ½Ã½ºÅÛ¿¡ ÀÇÇØ ¾ß±âµÇÁö ¾Ê´Â´Ù¸é, ¾î¶² ºÒÆòµµ ÇÏÁö ¾Ê´Â´Ù. (°¡´ÉÇÑ Á¤È®ÇÑ °æ°í ÁýÇÕÀº ÇöÀç `-Wimplicit -Wreturn-type -Wcomment -Wtrigraphs -Wformat -Wparentheses -Wpointer-arith -Wuninitialized'ÀÌ´Ù.

Formatting

Çü½Ä

The standard GNU recommendations for formatting must be followed strictly.

Çü½ÄÀ» À§ÇÑ Ç¥ÁØ GNU ÃßõÀº ¾ö°ÝÈ÷ µû·ª¾ß ÇÑ´Ù.

Note that while in a definition, the function's name must be in column zero; in a function declaration, the name must be on the same line as the return type.

Á¤ÀÇ¿¡¼­, ÇÔ¼ö ¸íÀº column zero¿¡ ÀÖ¾î¾ß ÇÑ´Ù.; ÇÔ¼ö ¼±¾ð¿¡¼­, À̸§Àº ¹Ýȯ ŸÀÔ°ú °°Àº ¶óÀο¡ ÀÖ¾î¾ß ÇÑ´Ù.

In addition, there must be a space between a function or macro name and the opening parenthesis of its argument list (except for macro definitions, as required by C). There must not be a space after an open paren/bracket or before a close paren/bracket.

°Ô´Ù°¡, ÇÔ¼ö³ª ¸ÅÅ©·Î À̸§°ú ÀÎÀÚ ¸®½ºÆ®ÀÇ ¿­¸° °¡·Î»çÀÌ¿¡´Â ½ºÆäÀ̽º°¡ ÀÖ¾î¾ß ÇÑ´Ù.(C¿¡¼­ ¿ä±¸ÇÑ °Íó·³, ¸ÅÅ©·Î Á¤ÀǸ¦ Á¦¿ÜÇÏ°í). ¿­¸° °ýÈ£/bracket ´ÙÀ½°ú ´ÝÈù paren/bracket Àü¿¡´Â ½ºÆäÀ̽º°¡ À־´Â ¾ÈµÈ´Ù.

While additional whitespace is generally helpful for reading, do not use more than one blank line to separate blocks, and avoid adding whitespace after the end of a program line (as of 1/99, some 600 lines had whitespace after the semicolon). Excess whitespace causes difficulties for diff and patch utilities.

Ãß°¡ÀûÀÎ whitespace´Â ÀϹÝÀûÀ¸·Î Àб⸦ µµ¿ÍÁÖÁö¸¸, blockÀ» ºÐ¸®Çϱâ À§ÇØ Çϳª ÀÌ»óÀÇ ºó¶óÀÎÀ» »ç¿ëÇÏÁö ¸¶¶ó. ±×¸®°í ÇÁ·Î±×·¥ ¶óÀÎ ³¡ ´ÙÀ½¿¡´Â whitespace¸¦ Ãß°¡Çϴ°ÍÀ» ÇÇÇضó.(99/1ó·³, ¸î¸î 600 ¶óÀεéÀº ¼¼¹ÌÄÝ·Ð ´ÙÀ½¿¡ whitespace¸¦ °¡Áø´Ù.) °úµµÇÑ whitespace´Â diff¿Í patch À¯Æ¿¸®Æ¼¿¡ ¾î·Á¿òÀ» ¾ß±âÇÑ´Ù.

Comments

ÁÖ¼®

The standard GNU requirements on comments must be followed strictly.

ÁÖ¼®¿¡¼­ Ç¥ÁØ GNU ¿ä±¸»çÇ×´Â ¾ö°ÝÈ÷ µû·ª¾ß ÇÑ´Ù.

Block comments must appear in the following form, with no `/*'- or `*/'-only lines, and no leading `*':

Block ÁÖ¼®Àº ´ÙÀ½ ÇüÅ·Π³ªÅ¸³ª¾ß Çϸç, ¶óÀδç `/*'³ª `*/'¸¦ ÇÏÁö ¾Ê°í ¾Õ¿¡ `*'µµ ÇÏÁö ¾Ê´Â´Ù:

/* Wait for control to return from inferior to debugger.  If inferior
   gets a signal, we may decide to start it up again instead of
   returning.  That is why there is a loop in this function.  When
   this function actually returns it means the inferior should be left
   stopped and GDB should read more commands.  */

(Note that this format is encouraged by Emacs; tabbing for a multi-line comment works correctly, and M-q fills the block consistently.)

(ÀÌ Çü½ÄÀº Emacs¿¡¼­ ÃßõÇÏ°í ÀÖµû; ´ÙÁß ¶óÀÎ tabbingÀº Àß ÀÛµ¿Çϸç M-q´Â ÀÏ°ü¼º ÀÖ°Ô ºí·°À» ä¿î´Ù.)

Put a blank line between the block comments preceding function or variable definitions, and the definition itself.

¼±Çà ÇÔ¼ö³ª º¯¼ö Á¤ÀÇ¿¡ ´ëÇÑ block ÁÖ¼®°ú Á¤ÀÇ »çÀÌ¿¡ blank ¶óÀÎÀ» ³Ö¾î¶ó.

In general, put function-body comments on lines by themselves, rather than trying to fit them into the 20 characters left at the end of a line, since either the comment or the code will inevitably get longer than will fit, and then somebody will have to move it anyhow.

ÀϹÝÀûÀ¸·Î, ±×°ÍµéÀ» ¶óÀÎ ³¡¿¡¼­ 20 ¹®ÀÚ¸¦ ³²°Ü³õÀº °÷¿¡ ¸ÂÃâ·Á°í Çϴ°ͺ¸´Ù´Â, ¶óÀÎÀ§¿¡ function-body ÁÖ¼®À» ³Ö¾î¶ó. ¿Ö³ÄÇϸé ÁÖ¼®À̳ª ÄÚµå´Â ¸ÂÃß´Â °Í ÀÌ»óÀ¸·Î ´õ ±æ¾îÁö±â ¶§¹®ÀÌ´Ù. ±×¸®°í ´©±º°¡°¡ ¾î¶»°Ôµç ±×°ÍÀ» ¿Å±æ °ÍÀÌ´Ù.

C Usage

C »ç¿ë¹ý

Code must not depend on the sizes of C data types, the format of the host's floating point numbers, the alignment of anything, or the order of evaluation of expressions.

Code´Â C µ¥ÀÌÅÍ Å¸ÀÔÀÇ Å©±â¿Í È£½ºÆ® ºÎµ¿ ¼Ò¼öÁ¡ ¼öÀÇ Çü½Ä, Á¤·Ä ¶Ç´Â Ç¥Çö½ÄÀÇ ¼ø¼­¿¡ ÀÇÁ¸ÇÏÁö ¾Ê´Â´Ù.

Use functions freely. There are only a handful of compute-bound areas in GDB that might be affected by the overhead of a function call, mainly in symbol reading. Most of GDB's performance is limited by the target interface (whether serial line or system call).

ÇÔ¼ö´Â ÀÚÀ¯½º·´°Ô »ç¿ëÇضó. ÁÖ¼Ò ½Éº¼ Àбâ½Ã, ÇÔ¼ö È£ÃâÀÇ ¿À¹öÇìµå·Î ¿µÇâÀ» ¹Þ´Â °ÍÀº GDB³» °æ°è ¿µ¿ª °è»ê¸¸ÀÌ´Ù. ´ëºÎºÐÀÇ GDB ¼º´ÉÀº Ÿ°Ù ÀÎÅÍÆäÀ̽º¿¡ Á¦ÇѵȴÙ.(½Ã¸®¾ó ¶óÀÎÀ̳ª ½Ã½ºÅÛ ÄÝ)

However, use functions with moderation. A thousand one-line functions are just as hard to understand as a single thousand-line function.

±×·¯³ª, ÇÔ¼ö´Â ÀûÀýÈ÷ »ç¿ëÇضó. õ°³ÀÇ ÇÑ ¶óÀÎ ÇÔ¼ö´Â ÇÑ°³ÀÇ Ãµ¶óÀÎ ÇÔ¼ö¸¸Å­ ÀÌÇØÇϱ⠾î·Æ´Ù.

Function Prototypes

ÇÔ¼ö ¿øÇü

Prototypes must be used to declare functions, and may be used to define them. Prototypes for GDB functions must include both the argument type and name, with the name matching that used in the actual function definition.

PrototypesÀº ÇÔ¼ö¸¦ ¼±¾ðÇϱâ À§ÇØ »ç¿ëµÇ¸ç ±×°ÍµéÀ» Á¤ÀÇÇϱâ À§ÇØ »ç¿ëµÈ´Ù. GDB ÇÔ¼ö¸¦ À§ÇÑ PrototypeÀº ½ÇÁ¦ ÇÔ¼ö Á¤Àǽà »ç¿ëµÇ´Â À̸§°ú ÀÏÄ¡µÇ´Â ÀÎÀÚ Å¸ÀÔ°ú À̸§À» Æ÷ÇÔÇØ¾ß ÇÑ´Ù.

All external functions should have a declaration in a header file that callers include, except for _initialize_* functions, which must be external so that `init.c' construction works, but shouldn't be visible to random source files.

¸ðµç ¿ÜºÎ ÇÔ¼öµéÀº _initialize_* ÇÔ¼ö¸¦ Á¦¿ÜÇÏ°í, È£ÃâÀÚ°¡ Æ÷ÇÔÇÏ´Â Çì´õ ÆÄÀϳ» ¼±¾ðµÇ¾î¾ß ÇÑ´Ù. ÀÌ ÇÔ¼öµéÀº `init.c' »ý¼ºÀÚ´Â ÀÛµ¿ÇÏ´Â external À̾î¾ß ÇÏÁö¸¸ ÀÓÀÇÀÇ ¼Ò½º ÆÄÀÏÀ» º¸¾Æ¼­´Â ¾ÈµÈ´Ù.

All static functions must be declared in a block near the top of the source file.

¸ðµç static ÇÔ¼öµéÀº ¼Ò½º ÆÄÀÏÀÇ Å¾ ±Ùó¿¡ ºí·°¿¡ ¼±¾ðµÇ¾î¾ß ÇÑ´Ù.

Clean Design and Portable Implementation

±ò²ûÇÑ µðÀÚÀΰú ȣȯ °¡´ÉÇÑ ¼öÇà

In addition to getting the syntax right, there's the little question of semantics. Some things are done in certain ways in GDB because long experience has shown that the more obvious ways caused various kinds of trouble.

¿ÇÀº ¹®¹ýÀ» °¡Áö´Â°Í ÀÌ¿Ü¿¡, Àǹ̷п¡´Â °ÅÀÇ Àǹ® »çÇ×ÀÌ ¾ø´Ù. ÀϺδ GDB¿¡¼­ È®½ÇÇÑ ¹æ¹ýÀ¸·Î ÇàÇØÁø´Ù. ¿Ö³ÄÇÏ¸é ¿À·¡µÈ °æÇèÀº ¸í¹éÇÑ ¹æ¹ýÀÌ ¿©·¯ Á¾·ùÀÇ ¹®Á¦¸¦ ¾ß±âÇѴٴ°ÍÀ» º¸¿©Áֱ⠶§¹®ÀÌ´Ù.

You can't assume the byte order of anything that comes from a target (including values, object files, and instructions). Such things must be byte-swapped using SWAP_TARGET_AND_HOST in GDB, or one of the swap routines defined in `bfd.h', such as bfd_get_32.

¿©·¯ºÐÀº Ÿ°Ù(value, °´Ã¼ ÆÄÀÏ, ¸í·É¾î¸¦ Æ÷ÇÔÇÏ¿©)¿¡¼­ÀÇ ¹ÙÀÌÆ® ¼ø¼­¸¦ °¡Á¤ÇÒ¼ö ¾ø´Ù. ±×·¯ÇÑ °ÍÀº GDB³» SWAP_TARGET_AND_HOST¸¦ »ç¿ëÇÏ¿© byte-swapÀ̾î¾ß ÇϵçÁö bfd_get_32ó·³ `bfd.h'¿¡ Á¤ÀǵǾî ÀÖ´Â swap routineÁß ÇϳªÀ̾î¾ß ÇÑ´Ù.

You can't assume that you know what interface is being used to talk to the target system. All references to the target must go through the current target_ops vector.

¿©·¯ºÐÀº ¾î¶² ÀÎÅÍÆäÀ̽º°¡ Ÿ°Ù ½Ã½ºÅÛ°ú ¾ê±âÇÒ¶§ »ç¿ëµÇ´ÂÁö¸¦ ¾È´Ù°í °¡Á¤ÇÒ¼ö ¾ø´Ù. Ÿ°Ù ½Ã½ºÅÛ¿¡ ´ëÇÑ ¸ðµç ÂüÁ¶´Â ÇöÀç target_ops¸¦ ÅëÇØ¾ß ÇÑ´Ù.

You can't assume that the host and target machines are the same machine (except in the "native" support modules). In particular, you can't assume that the target machine's header files will be available on the host machine. Target code must bring along its own header files -- written from scratch or explicitly donated by their owner, to avoid copyright problems.

¿©·¯ºÐÀº È£½ºÅ¸¿Í Ÿ°Ù ¸Ó½ÅÀÌ °°Àº ¸Ó½ÅÀ̶ó°í °¡Á¤ÇÒ¼ö ¾ø´Ù.("native" Áö¿ø ¸ðµâÀ» Á¦¿ÜÇÏ°í) Ưº°È÷, ¿©·¯ºÐÀº Ÿ°Ù ¸Ó½Å Çì´õ ÆÄÀÏÀº È£½ºÆ® ¸Ó½Å¿¡¼­ ÀÌ¿ëÇÒ¼ö Àִ°ÍÀ¸·Î °¡Á¤ÇÒ¼ö ¾ø´Ù. Ÿ°Ù ÄÚµå´Â ÀÚ½ÅÀÇ Çì´õÆÄÀÏÀ» °¡Á®¾ß ÇÑ´Ù.--copyright ¹®Á¦¸¦ ÇÇÇϱâ À§ÇØ, scratch³ª ¼ÒÀ¯ÀÚ°¡ ±âÁõÇÑ Çì´õ ÆÄÀÏ.

Insertion of new #ifdef's will be frowned upon. It's much better to write the code portably than to conditionalize it for various systems.

»õ·Î¿î #ifdefÀÇ »ðÀÔÀº ÁÁÁö ¾Ê´Ù. ´Ù¾çÇÑ ½Ã½ºÅÛÀ» À§ÇØ ±×°ÍÀ» Á¶°ÇÈ­ Çϴ°ͺ¸´Ù Äڵ带 ȣȯ¼º ÀÖ°Ô ¾²´Â°ÍÀÌ ´õ ÁÁ´Ù.

New #ifdef's which test for specific compilers or manufacturers or operating systems are unacceptable. All #ifdef's should test for features. The information about which configurations contain which features should be segregated into the configuration files. Experience has proven far too often that a feature unique to one particular system often creeps into other systems; and that a conditional based on some predefined macro for your current system will become worthless over time, as new versions of your system come out that behave differently with regard to this feature.

ƯÁ¤ ÄÄÆÄÀÏ·¯³ª Á¦Á¶ ¾÷ÀÚ³ª ¿ÀÆÛ·¹ÀÌÆÃÀ» Å×½ºÆ®ÇÏ´Â »õ·Î¿î #ifdef´Â ¹Þ¾ÆµéÀϼö ¾ø´Ù. ¸ðµç #ifdefÀº Ư¡µéÀ» À§ÇØ °Ë»çµÇ¾î¾ß ÇÑ´Ù. Ư¡µéÀ» Æ÷ÇÔÇÏ´Â ¼³Á¤ »çÇ׿¡ °üÇÑ Á¤º¸´Â ¼³Á¤ ÆÄÀϵé·Î ³ª´©¾îÁ®¾ß ÇÑ´Ù. Áö±Ý±îÁöÀÇ °æÇèÀº ƯÁ¤ ½Ã½ºÅÛ¿¡¼­ À¯ÀÏÇÑ Æ¯Â¡Àº ´Ù¸¥ ½Ã½ºÅÛ¿¡¼­´Â ¾î±ß³¯¼ö ÀÖ´Ù´Â °ÍÀ» Áõ¸íÇØÁØ´Ù.; ±×¸®°í ½Ã½ºÅÛÀ» À§ÇÑ ±âÁ¤ÀÇ ¸ÅÅ©·Î ±â¹Ý Á¶°ÇµéÀº ½Ã°£ÀÌ Áö³²¿¡ µû¶ó °¡Ä¡°¡ ¾ø¾îÁú¼ö ÀÖ´Ù. ¿Ö³ÄÇÏ¸é ½Ã½ºÅÛÀÇ »õ·Î¿î ¹öÀüÀº ÀÌ Æ¯Â¡¿¡ µû¶ó¼­ ´Ù¸£°Ô ÇൿÇÒ¼ö Àֱ⠶§¹®ÀÌ´Ù.

Adding code that handles specific architectures, operating systems, target interfaces, or hosts, is not acceptable in generic code. If a hook is needed at that point, invent a generic hook and define it for your configuration, with something like:

ƯÁ¤ ¾ÆÅ°ÅØÃÄ, OS, Ÿ°Ù ÀÎÅÍÆäÀ̽º³ª È£½ºÆ®¸¦ Çڵ鸵ÇÏ´Â Äڵ带 Ãß°¡Çϴ°ÍÀº ÀϹÝÀûÀÎ Äڵ忡¼­´Â ¹Þ¾Æµé¿©ÁöÁö ¾Ê´Â´Ù. ¸¸ÀÏ ÈÅÀÌ ±×½ÃÁ¡¿¡¼­ ÇÊ¿äÇÏ´Ù¸é, ÀϹÝÀû ÈÅÀ» ¸¸µé°í ´ÙÀ½°ú °°ÀÌ ¼³Á¤¿¡ ±×°ÍÀ» Á¤ÀÇÇضó.:

#ifdef	WRANGLE_SIGNALS
   WRANGLE_SIGNALS (signo);
#endif

In your host, target, or native configuration file, as appropriate, define WRANGLE_SIGNALS to do the machine-dependent thing. Take a bit of care in defining the hook, so that it can be used by other ports in the future, if they need a hook in the same place.

È£½ºÆ®, Ÿ°Ù ¶Ç´Â native ¼³Á¤ ÆÄÀÏ¿¡¼­, Àû´çÈ÷ ¸Ó½Å ÀÇÁ¸ÀûÀÎ °ÍÀ» ÇÒ¶§´Â WRANGLE_SIGNALS¸¦ Á¤ÀÇÇضó. ÈÅ Á¤Àǽà ÁÖÀÇÇضó. ¸¸ÀÏ °°Àº °÷¿¡ ÈÅÀÌ ÇÊ¿äÇÏ´Ù¸é, ¿Ö³ÄÇÏ¸é ±×°ÍÀº ¹Ì·¡¿¡ ´Ù¸¥ Æ÷Æ®¿¡¼­ »ç¿ëµÉ¼ö Àֱ⠶§¹®ÀÌ´Ù.

If the hook is not defined, the code should do whatever "most" machines want. Using #ifdef, as above, is the preferred way to do this, but sometimes that gets convoluted, in which case use

¸¸ÀÏ ÈÅÀÌ Á¤ÀǵÇÁö ¾Ê¾Ò´Ù¸é, ÄÚµå´Â ´ëºÎºÐÀÇ ¸Ó½ÅÀÌ ¿øÇϴ°ÍÀº ¹«¾ùÀ̵ç ÇØ¾ß ÇÑ´Ù. À§Ã³·³ #ifdef¸¦ »ç¿ëÇÏ´Â °ÍÀº ÀÌ°ÍÀ» Çϴµ¥ ´õ ÁÁÀº ¹æ¹ýÀÌ´Ù. ±×·¯³ª °¡²û µÚ¾ôÈú¼ö ÀÖ´Ù.

#ifndef SPECIAL_FOO_HANDLING
#define SPECIAL_FOO_HANDLING(pc, sp) (0)
#endif

where the macro is used or in an appropriate header file.

¸ÅÅ©·Î°¡ »ç¿ëµÈ °÷À̳ª Àû´çÇÑ Çì´õ ÆÄÀϳ».

Whether to include a small hook, a hook around the exact pieces of code which are system-dependent, or whether to replace a whole function with a hook, depends on the case. A good example of this dilemma can be found in get_saved_register. All machines that GDB 2.8 ran on just needed the FRAME_FIND_SAVED_REGS hook to find the saved registers. Then the SPARC and Pyramid came along, and HAVE_REGISTER_WINDOWS and REGISTER_IN_WINDOW_P were introduced. Then the 29k and 88k required the GET_SAVED_REGISTER hook. The first three are examples of small hooks; the latter replaces a whole function. In this specific case, it is useful to have both kinds; it would be a bad idea to replace all the uses of the small hooks with GET_SAVED_REGISTER, since that would result in much duplicated code. Other times, duplicating a few lines of code here or there is much cleaner than introducing a large number of small hooks.

½Ã½ºÅÛ ÀÇÁ¸ÀûÀÎ Á¤È®ÇÑ ÄÚµå Á¶°¢ ÁÖÀ§ÀÇ ÀÛÀº ÈÅÀ» Æ÷ÇÔÇϵçÁö ÈÅÀ» °¡Áø Àüü ÇÔ¼ö¸¦ ´ëüÇϵçÁö °æ¿ì¿¡ ÀÇÁ¸ÀûÀÌ´Ù. ÀÌ µô·¹¸¶ÀÇ ÁÁÀº ¿¹´Â get_saved_register¿¡¼­ ¹ß°ßµÉ¼ö ÀÖµû. GDB 2.8°¡ µ¹¾Æ°¡´Â ¸ðµç ¸Ó½ÅÀº ÀúÀåµÈ ·¹Áö½ºÅ͸¦ ¹ß°ßÇϱâ À§ÇØ FRAME_FIND_SAVED_REGS ÈÅÀÌ ÇÊ¿äÇÏ´Ù. ±×¸®°í SPARC°ú Pyramid´Â µ¶ÀÚÀûÀ¸·Î ¿Ô°í HAVE_REGISTER_WINDOWS°ú REGISTER_IN_WINDOW_P´Â ¼Ò°³µÇ¾ú´Ù. ±×¸®°í 29k¿Í 88k´Â GET_SAVED_REGISTER ÈÅÀ» ¿ä±¸ÇÑ´Ù. óÀ½ 3°³´Â ÀÛÀº ÈÅÀÇ ¿¹Á¦ÀÌ´Ù; ³ªÁßÀº Àüü ÇÔ¼ö·Î ¹Ù²î¾ú´Ù. Ưº°ÇÑ °æ¿ì¿¡, µÎ Á¾·ù¸¦ °¡Áö´Â °ÍÀÌ À¯¿ëÇÏ´Ù.; GET_SAVED_REGISTERÀ» °¡Áö´Â ÀÛÀº ÈÅÀ» »ç¿ëÇÏ´Â ¸ðµÎ¸¦ ¹Ù²Ù´Â °ÍÀº ÁÁÁö ¾ÊÀº »ý°¢ÀÌ´Ù. ¿Ö³ÄÇÏ¸é ±×°ÍÀº ´ëºÎºÐ Áߺ¹µÈ ÄÚµå °á°úÀ̱⠶§¹®ÀÌ´Ù. ´Ù¸¥ ¶§, ¿©±â Àú±â¿¡¼­ Áߺ¹µÈ ¶óÀεéÀº ¸¹Àº ¼öÀÇ ÀÛÀº ÈÅÀ» ¼Ò°³Çϴ°ͺ¸´Ù ´õ ¸í¹éÇÏ´Ù.

One particularly notorious area where system dependencies tend to creep in is handling of file names. The mainline GDB code assumes Posix semantics of file names: absolute file names begin with a forward slash `/', slashes are used to separate leading directories, case-sensitive file names. These assumptions are not necessarily true on non-Posix systems such as MS-Windows. To avoid system-dependent code where you need to take apart or construct a file name, use the following portable macros:

Ưº°È÷ ½Ã½ºÅÛ ÀÇÁ¸¼ºÀÌ ¹®Á¦°¡ »ý±â±â ½¬¿î ¿µ¿ªÀº ÆÄÀÏ À̸§ Çڵ鸵ÀÌ´Ù. GDB ÄÚµå´Â Posix ÀǹÌÀÇ ÆÄÀÏÀ̸§À¸·Î °¡Á¤ÇÑ´Ù.;Àý´ë ÆÄÀÏ À̸§Àº `/'·Î ½ÃÀÛÇϸç, ½½·¡½¬´Â ¼±Çà µð·ºÅ丮¿¡ »ç¿ëµÇ¸ç, case-sensitive ÆÄÀϸíÀÌ´Ù. ÀÌ·¯ÇÑ °¡Á¤Àº MS-Windows°°ÀÌ ºñ-Posix ½Ã½ºÅÛ¿¡¼­´Â »ç½ÇÀÌ ¾Æ´Ï´Ù. ½Ã½ºÅÛ ÀÇÁ¸ÀûÀÎ Äڵ带 ÇÇÇϱâ À§ÇØ, ¿©·¯ºÐÀº ÆÄÀÏ À̸§À» ºÐÇØÇϰųª ¸¸µé¾î¾ß ÇÒ ÇÊ¿ä°¡ ÀÖÀ¸¸ç, ´ÙÀ½Ã³·³ ȣȯ °¡´ÉÇÑ ¸ÅÅ©·Î¸¦ »ç¿ëÇضó.

HAVE_DOS_BASED_FILE_SYSTEM
This preprocessing symbol is defined to a non-zero value on hosts whose filesystems belong to the MS-DOS/MS-Windows family. Use this symbol to write conditional code which should only be compiled for such hosts.

ÀÌ ÇÁ¸®ÇÁ·Î¼¼½Ì ½Éº¼Àº ÆÄÀÏ ½Ã½ºÅÛÀÌ MS-DOS/MS-Windows °è¿­¿¡ ¼ÓÇϴ ȣ½ºÆ®ÀÇ °æ¿ì¿¡ ºñ zero·Î Á¤ÀǵǾî ÀÖ´Ù. ±×·¯ÇÑ È£½ºÆ®¿¡¼­ ÄÄÆÄÀÏ µÇ¾î¾ßÇÏ´Â Á¶°ÇÀû Äڵ带 ¾²±â À§ÇØ ÀÌ ½Éº¼À» »ç¿ëÇضó.

IS_DIR_SEPARATOR (c
Evaluates to a non-zero value if c is a directory separator character. On Unix and GNU/Linux systems, only a slash `/' is such a character, but on Windows, both `/' and `\' will pass.

¸¸ÀÏ c°¡ µð·ºÅ丮 ºÐ¸® ¹®ÀÚÀ̸é non-zero·Î Æò°¡µÈ´Ù. Unix¿Í GNU/Linux ½Ã½ºÅÛ¿¡¼­, ½½·¡½¬ `/'´Â ±×·± ¹®ÀÚÀ̸ç, Windows¿¡¼­´Â `/'¿Í `\' ¸ðµÎ Åë°úµÈ´Ù.

IS_ABSOLUTE_PATH (file)
Evaluates to a non-zero value if file is an absolute file name. For Unix and GNU/Linux hosts, a name which begins with a slash `/' is absolute. On DOS and Windows, `d:/foo' and `x:\bar' are also absolute file names.

¸¸ÀÏ fileÀÌ Àý´ë ÆÄÀÏÀ̸§ À̶ó¸é non-zero·Î Æò°¡µÈ´Ù. Unix¿Í GNU/Linux È£½ºÆ®¿¡¼­, ½½·¡½¬ `/'·Î ½ÃÀÛÇÏ´Â À̸§Àº Àý´ëÀûÀÌ´Ù. DOS¿Í Window¿¡¼­, `d:/foo'¿Í `x:\bar'´Â ¿ª½Ã Àý´ë ÆÄÀÏÀ̸§ÀÌ´Ù.

FILENAME_CMP (f1, f2)
Calls a function which compares file names f1 and f2 as appropriate for the underlying host filesystem. For Posix systems, this simply calls strcmp; on case-insensitive filesystems it will call strcasecmp instead.

È£½ºÆ® ÆÄÀϽýºÅÛ¿¡ ±Ù°ÅÇÏ¿© ÆÄÀÏ À̸§ f1°ú f2¸¦ ºñ±³ÇÏ´Â ÇÔ¼ö¸¦ È£ÃâÇÑ´Ù. Posix ½Ã½ºÅÛ¿¡¼­, ÀÌ°ÍÀº ´Ü¼øÈ÷ strcmp¸¦ È£ÃâÇÑ´Ù.; case-insensitive ÆÄÀÏ ½Ã½ºÅÛ¿¡¼­´Â ´ë½Å¿¡ strcasecmp¸¦ È£ÃâÇÑ´Ù.

DIRNAME_SEPARATOR
Evaluates to a character which separates directories in PATH-style lists, typically held in environment variables. This character is `:' on Unix, `;' on DOS and Windows.

PATH ½ºÅ¸ÀÏ ¸®½ºÆ®³» µð·ºÅ丮¸¦ ºÐ¸®ÇÏ´Â ¹®ÀÚ¸¦ Æò°¡Çϸç ÀüÇüÀûÀ¸·Î ȯ°æ º¯¼ö¿¡¼­ °¡Á®¿Â´Ù. ÀÌ ¹®ÀÚ´Â Unix¿¡¼­ `:'ÀÌ°í, DOS¿Í Windows¿¡¼­ `;'ÀÌ´Ù.

SLASH_STRING
This evaluates to a constant string you should use to produce an absolute filename from leading directories and the file's basename. SLASH_STRING is "/" on most systems, but might be "\\" for some Windows-based ports.

ÀÌ°ÍÀº ¿©·¯ºÐÀÌ ¼±Çà µð·ºÅ丮¿Í ÆÄÀÏ ±âº» À̸§¿¡¼­ Àý´ë ÆÄÀÏ À̸§À» ¸¸µé±â À§ÇØ »ç¿ëÇØ¾ß ÇÏ´Â »ó¼ö ¹®ÀÚ¿­À» Æò°¡ÇÑ´Ù. SLASH_STRING´Â ´ëºÎºÐÀÇ ½Ã½ºÅÛ¿¡¼­ "/"ÀÌÁö¸¸, ¸î¸î Window ±â¹Ý Æ÷Æ®¿¡¼­ "\\"ÀÌ´Ù.

In addition to using these macros, be sure to use portable library functions whenever possible. For example, to extract a directory or a basename part from a file name, use the dirname and basename library functions (available in libiberty for platforms which don't provide them), instead of searching for a slash with strrchr.

ÀÌµé ¸ÅÅ©·Î¸¦ »ç¿ëÇÏ´Â°Í À§¿¡, °¡´ÉÇÒ¶§´Â ¾ðÁ¦³ª ȣȯ°¡´ÉÇÑ ¶óÀ̺귯¸® ÇÔ¼ö¸¦ »ç¿ëÇØ¾ß ÇÑ´Ù. ¿¹¸¦ µé¾î, µð·ºÅ丮 ÀοëÀ̳ª ÆÄÀÏ À̸§¿¡¼­ ±âº»À̸§À» ºÐ¸®Çϱâ À§ÇØ strrchr¸¦ °¡Áö°í ½½·¡½¬¸¦ ã´Â°Í ´ë½Å¿¡ dirname¿Í basename ¶óÀ̺귯¸® ÇÔ¼ö (±×°ÍµéÀ» Á¦°øÇÏÁö ¾Ê´Â Ç÷§ÆûÀ» À§Çؼ­ libiberty¿¡¼­ ÀÌ¿ë°¡´ÉÇÏ´Ù.)¸¦ »ç¿ëÇضó.

Another way to generalize GDB along a particular interface is with an attribute struct. For example, GDB has been generalized to handle multiple kinds of remote interfaces--not by #ifdefs everywhere, but by defining the target_ops structure and having a current target (as well as a stack of targets below it, for memory references). Whenever something needs to be done that depends on which remote interface we are using, a flag in the current target_ops structure is tested (e.g., target_has_stack), or a function is called through a pointer in the current target_ops structure. In this way, when a new remote interface is added, only one module needs to be touched--the one that actually implements the new remote interface. Other examples of attribute-structs are BFD access to multiple kinds of object file formats, or GDB's access to multiple source languages.

ƯÁ¤ ÀÎÅÍÆäÀ̽º¿¡ µû¶ó GDB¸¦ ÀϹÝÈ­ Çϱâ À§ÇÑ ´Ù¸¥ ¹æ¹ýÀº ±¸ÃÊü ¼Ó¼ºÀÌ´Ù. ¿¹¸¦ µé¾î, GDB´Â ¿©·¯ Á¾·ùÀÇ ¿ø°Ý ÀÎÅÍÆäÀ̽º¸¦ ó¸®ÇϱâÀ§ÇØ ÀϹÝÈ­µÇ¾î ÀÖ´Ù.-- ¸ðµç °÷¿¡¼­ #ifdef°¡ ¾Æ´Ï°í, target_ops ±¸Á¶Ã¼¸¦ Á¤ÀÇÇÏ°í ÇöÀç Ÿ°ÙÀ» °¡Áø´Ù.(¸Þ¸ð¸® ÂüÁ¶¸¦ À§ÇØ, Ÿ°ÙÀÇ ½ºÅÃÀº ±×°Í ¾Æ·¡¿¡µµ) ¿ø°Ý ÀÎÅÍÆäÀ̽º¿¡ ÀÇÁ¸ÇÒ ÇÊ¿ä°¡ ÀÖÀ»¶§´Â ¾ðÁ¦³ª, ¿ì¸®´Â ÇöÀç target_ops structureÀÇ Ç÷¡±×¸¦ °Ë»çÇϰųª ÇöÀç target_ops structure³» Æ÷ÀÎÅ͸¦ È£ÃâÇÒ¶§ ÇÔ¼ö¸¦ »ç¿ëÇÑ´Ù. ÀÌ·± ¹æ¹ýÀ¸·Î, »õ·Î¿î ¿ø°Ý ÀÎÅÍÆäÀ̽º°¡ Ãß°¡µÉ¶§, °Çµå·Á¾ß ÇÏ´Â À¯ÀÏÇÑ ¸ðµâÀº »õ·Î¿î ¿ø°Ý ÀÎÅÍÆäÀ̽º¸¦ ½ÇÁ¦ ¼öÇàÇÏ´Â ¸ðµâÀÌ´Ù. ¼Ó¼º-structÀÇ ´Ù¸¥ ¿¹Á¦´Â ¿©·¯ Á¾·ùÀÇ °´Ã¼ÆÄÀÏ Çü½Ä¿¡ ´ëÇÑ BFD Á¢±ÙÀ̳ª ¿©·¯ ¼Ò½º ¾ð¾î¿¡ ´ëÇÑ GDB Á¢¼ÓÀÌ´Ù.

Please avoid duplicating code. For example, in GDB 3.x all the code interfacing between ptrace and the rest of GDB was duplicated in `*-dep.c', and so changing something was very painful. In GDB 4.x, these have all been consolidated into `infptrace.c'. `infptrace.c' can deal with variations between systems the same way any system-independent file would (hooks, #if defined, etc.), and machines which are radically different don't need to use `infptrace.c' at all.

Áߺ¹ Äڵ带 ÇÇÇضó. ¿¹¸¦ µé¾î, GDB 3.x¿¡¼­ ptrace¿Í GDBÀÇ ³ª¸ÓÁö¿¡¼­ÀÇ ¸ðµç ÄÚµå ÀÎÅÍÆäÀ̽º´Â `*-dep.c'¿¡ Áߺ¹µÇ¸ç ±×·¡¼­ ¹Ù²Ù´Â °ÍÀº ¸Å¿ì °íÅ뽺·´´Ù. GDB 4.x¿¡¼­, À̰͵éÀº ¸ðµÎ `infptrace.c'·Î ÇÕÃÄÁ³´Ù. `infptrace.c'´Â ½Ã½ºÅÛ µ¶¸³ÀûÀÎ ÆÄÀÏÀÌÈÅ, #if defined µî) ÇÕÃÄÁö´Â ½Ã½ºÅÛ »çÀÌÀÇ º¯Á¾À» ´Ù·ç¸ç ±Ùº»ÀûÀ¸·Î ´Ù¸¥ ¸Ó½ÅµéÀº ¸ðµÎ `infptrace.c'¸¦ »ç¿ëÇÒ ÇÊ¿ä°¡ ¾ø´Ù.

Don't put debugging printfs in the code.


Go to the first, previous, next, last section, table of contents.