__FILE__,__LINE__,FUNCTION__ implementation of code-tracking Debugging (Linux C language programming)

Source: Internet
Author: User

[Email protected]:~/cpropram/2# cat global.h//header file
#ifndef Clobal_h
#define Global_h
#include <stdio.h>
int Funca (void);
int funcb (void);
#endif
[Email protected]:~/cpropram/2# cat funca.c//function A
#include "global.h"
int Funca (void)
{
printf ("This is function\n");
return 0;
}
[Email protected]:~/cpropram/2# cat FUNCB.C//function B
#include "global.h"
int funcb (void)
{
printf ("This is function\n");
return 0;
}
[Email protected]:~/cpropram/2# gcc-wall funca.c FUNCB.C main.c//co-compilation
[Email protected]:~/cpropram/2#./a.out//Run
This is main
This isfunction
This is main
The IS function
This is main

The same result is difficult to see there is a mistake, the following we use __FILE__,__LINE__,__FUNCTION__ to add code, see what is the difference between them.
Add the __file__,__line__,__function__ to the MAIL.C.
[Email protected]:~/cpropram/2# cat MAIN.C
#include "global.h"
int main (int argc, char **argv)
{
printf ("%s (%d)-%s:this is main\n", __file__,__line__,__function__);
Funca ();
printf ("%s (%d)-%s:this is main\n", __file__,__line__,__function__);
FUNCB ();
printf ("%s (%d)-%s:this is main\n", __file__,__line__,__function__);
return 0;
}
[Email protected]:~/cpropram/2# gcc-wall funca.c FUNCB.C main.c
[Email protected]:~/cpropram/2#./a.out
MAIN.C (4)-main:this is main
The IS function
MAIN.C (6)-main:this is main
The IS function
MAIN.C (8)-main:this is main

The above results main.c (4)-main:this is main means that the fourth line in the MIAN.C source code is printed inside the main function.
In that case, it's convenient for programmers to debug their own programs!
To make it easier to use it, we can define it by using the macro in the Global.h code.
[Email protected]:~/cpropram/2# cat global.h
#ifndef Clobal_h
#define Global_h
#include <stdio.h>
int Funca (void);
int funcb (void);
#define DEBUGFMT "%s (%d)-%s"
#define Debugargs __file__,__line__,__function__
#endif
[Email protected]:~/cpropram/2# cat FUNCA.C
#include "global.h"
int Funca (void)
{
printf (debugfmt "This is function\n", Debugargs);
return 0;
}
[Email protected]:~/cpropram/2# cat FUNCB.C
#include "global.h"
int funcb (void)
{
printf (debugfmt "This is function\n", Debugargs);
return 0;
}
[Email protected]:~/cpropram/2# cat MAIN.C
#include "global.h"
int main (int argc, char **argv)
{
printf (debugfmt "This is main\n", Debugargs);
Funca ();
printf (debugfmt "This is main\n", Debugargs);
FUNCB ();
printf (debugfmt "This is main\n", Debugargs);
return 0;
}
[Email protected]:~/cpropram/2# gcc-wall funca.c FUNCB.C main.c
[Email protected]:~/cpropram/2#./a.out
MAIN.C (4)-mainthis is main
FUNCA.C (4)-funca this is function
MAIN.C (6)-mainthis is main
FUNCB.C (4)-FUNCB this is function
MAIN.C (8)-mainthis is main
[Email protected]:~/cpropram/2#

This is the simple implementation of code tracking debugging by defining __FILE__,__LINE__,FUNCTION__ macros:)

Here is a header file that can be used for debugging
#ifndef _gold_debug_h
#define _gold_debug_h

#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif
#endif/* __cplusplus */

#define Gi_debug

#ifdef Gi_debug

#define GI_DEBUG_POINT () printf ("\n\n[file:%s line:%d] fun:%s\n\n", __file__, __line__, __function__)
#define DBG_PRINTF (Arg ...) printf (ARG);

#define GI_ASSERT (expr) \
do{\
if (! ( expr)) {\
printf ("\nassert failed at:\n >file name:%s\n >function:%s\n >line No.:%d\n >condition:%s\n", \
__file__,__function__, __line__, #expr);
} \
}while (0);

/* Debug macro, for pausing */
#define Gi_debug_pause () \
Do \
{               \
Gi_debug_point (); \
printf ("Pause for debug, press ' Q ' to exit!\n"); \
char c; \
while ((c = GetChar ())) \
{             \
if (' q ' = = c) \
{           \
GetChar (); \
Break \
}           \
}             \
}while (0);
#define GI_DEBUG_PAUSE_ARG (ARG ...) \
Do \
{               \
printf (ARG); \
Gi_debug_pause () \
}while (0);


#define GI_DEBUG_ASSERT (expression) \
if (! ( expression)) \
{                                  \
printf ("[assert],%s,%s:%d\n", __file__, __function__, __line__);
Exit (-1); \
}
#else
#define Gi_assert (expr)
#define Gi_debug_pause ()
#define GI_DEBUG_PAUSE_ARG (ARG ...)
#define GI_DEBUG_POINT ()
#define DBG_PRINTF (Arg ...)
#define GI_DEBUG_ASSERT (expression)

#endif

#ifdef __cplusplus
#if __cplusplus
}
#endif
#endif/* __cplusplus */


#endif

C Language Common macro definitions

01: Prevent a header file from being repeatedly included
#ifndef Comdef_h
#define Comdef_h
Header file Contents
#endif
02: Redefine some types to prevent differences in the number of types of bytes produced due to different platforms and compilers, facilitating portability.
typedef unsigned char Boolean; /* Boolean value type. */
typedef unsigned long int uint32; /* Unsigned-bit value */
typedef unsigned short uint16; /* Unsigned-bit value */
typedef unsigned char uint8; /* Unsigned 8 bit value */
typedef signed Long int int32; /* Signed-bit value */
typedef signed short Int16; /* Signed-bit value */
typedef signed CHAR int8; /* Signed 8 bit value */

The following is not recommended for use
typedef unsigned char byte; /* Unsigned 8 bit value type. */
typedef unsigned short word; /* unsinged-bit value type. */
typedef unsigned long DWORD; /* Unsigned-bit value type. */
typedef unsigned char uint1; /* Unsigned 8 bit value type. */
typedef unsigned short Uint2; /* Unsigned-bit value type. */
typedef unsigned long uint4; /* Unsigned-bit value type. */
typedef signed Char Int1; /* Signed 8 bit value type. */
typedef signed short Int2; /* Signed-bit value type. */
typedef long int int4; /* Signed-bit value type. */
typedef signed Long SINT31; /* Signed-bit value */
typedef signed short sint15; /* Signed-bit value */
typedef signed Char SINT7; /* Signed 8 bit value */

03: Get a Byte or a word on the specified address
#define MEM_B (x) (* (BYTE *) (x))
#define MEM_W (x) (* ((Word *) (x)))

04: Find maximum and minimum values
#define MAX (x, y) ((> (y))? (x): (y))
#define MIN (x, Y) ((() < (y))? (x): (y))

05: Gets the offset of a field in the struct (struct)
#define FPOS (Type,field) ((DWORD) & ((type *) 0)->field)

06: Get the number of bytes occupied by field in a struct
#define FSIZ (Type,field) sizeof (((type *) 0)->field)

07: Convert two bytes to a word in LSB format
#define FLIPW (Ray) (((Word) (Ray) [0]) + (Ray) [1])

08: Convert a Word to two bytes in LSB format
#define FLOPW (Ray,val) (Ray) [0] = ((val)/256); (Ray) [1] = ((val) & 0xFF)

09: Get the address of a variable (word width)
#define B_PTR (Var) ((BYTE *) (void *) & (Var))
#define W_PTR (Var) ((Word *) (void *) & (Var))

10: Get the high and low bytes of a word
#define WORD_LO (XXX) ((byte) ((WORD) (XXX) & 255))
#define WORD_HI (XXX) ((byte) ((WORD) (XXX) >> 8))

11: Returns a multiple of the nearest 8 that is larger than X
#define RND8 (x) (((((x) + 7)/8) * 8)

12: Convert one letter to uppercase
#define UPCASE (c) (((c) >= ' A ' && (c) <= ' Z ')? ((c)-0x20): (c))

13: Determine if a character is a number that is 10 in value
#define DECCHK (c) ((c) >= ' 0 ' && (c) <= ' 9 ')

14: Determine if a character is a number that is 16 in value
#define HEXCHK (c) (((c) >= ' 0 ' && (c) <= ' 9 ') ((c) >= ' A ' && (c) <= ' F ') \
((c) >= ' A ' && (c) <= ' F '))

15: One way to prevent overflow
#define INC_SAT (Val) (Val= (Val) +1> (val))? (val) +1: (val))

16: Returns the number of array elements
#define ARR_SIZE (a) (sizeof ((a))/sizeof ((a[0)))

17: Returns the value of an unsigned N-tailed Mod_by_power_of_two (X,n) =x% (2^n)
#define Mod_by_power_of_two (Val, mod_by) ((DWORD) (VAL) & (DWORD) ((mod_by)-1))

18: Input and output processing for IO space mapping in storage space structure
#define INP (Port) (* (Volatile byte *) (port))
#define INPW (Port) (* (volatile word *) (port))
#define INPDW (Port) (* (volatile DWORD *) (port))
#define OUTP (Port,val) (* (Volatile byte *) (port)) = ((Byte) (val))
#define OUTPW (Port, Val) (* (volatile word *) (port)) = ((Word) (val))
#define OUTPDW (Port, Val) (* (volatile DWORD *) (port)) = ((DWORD) (Val)))

19: Debug with some macro tracking
The ANSI standard describes five predefined macro names. They are:
__line__
__file__
__date__
__time__
__stdc__
__cplusplus is also defined in C + +.

If the compiler is not standard, it is possible to support only a few of the macro names above, or not at all. Remember that the compiler may also provide other predefined macro names.

__LINE__ and __FILE__ macros indicate that, #line指令可以改变它的值, simply speaking, when compiled, they contain the current number of lines and file names of the program.

The __DATE__ macro directive contains a string of months/days/years, indicating the date when the source file was translated to the code.
The __TIME__ macro directive contains the time that the program was compiled. Time is represented by a string, in the form: minutes: seconds
The meaning of the __STDC__ macro directive is defined at compile time. In general, if __STDC__ is already defined, the compiler will only accept standard C + + code that does not contain any non-standard extensions. If the implementation is standard, the macro __stdc__ contains a decimal constant of 1. If it contains any other number, the implementation is non-standard.
__cplusplus A compiler that is consistent with standard C + + defines it as a value that contains at least 6. Compilers that are inconsistent with standard C + + will use a numeric value that has 5 bits or less.


You can define macros, for example:
When the _DEBUG is defined, the output data information and the file where the
#ifdef _DEBUG
#define DEBUGMSG (msg,date) printf (msg);p rintf ("%d%d%d", Date,_line_,_file_)
#else
#define DEBUGMSG (Msg,date)
#endif


20: Macro definition prevents errors with parentheses contained.
For example:
Problematic definition: #define Dump_write (ADDR,NR) {memcpy (BUFP,ADDR,NR); BUFP + = nr;}
Definitions that should be used: #difne do (A, b) do{a+b;a++;} while (0)
For example:
if (addr)
Dump_write (ADDR,NR);
Else
Do_somethong_else ();
After the macro expands, it becomes this:
if (addr)
{memcpy (BUFP,ADDR,NR); BUFP + = nr;};
Else
Do_something_else ();

GCC considers that the IF statement has ended when it encounters the ";" in front of else, so that the later else is not in the IF statement. With the definition of do{} while (0), there is no problem in any case. Instead #difne do (A, b) do{a+b;a++;} while (0) is defined without error in any case.

__FILE__,__LINE__,FUNCTION__ implementation of code-tracking Debugging (Linux C language programming)

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.