Linux下打印调试管理

#ifndef _DEBUG_MANAGE_H_
#define _DEBUG_MANAGE_H_

/* 信息的调试级别,数值起小级别越高 */
#define APP_EMERG   "<0>"   /* system is unusable */
#define APP_ALERT   "<1>"   /* action must be taken immediately */
#define APP_CRIT    "<2>"   /* critical conditions */
#define APP_ERR     "<3>"   /* error conditions */
#define APP_WARNING "<4>"   /* warning conditions */
#define APP_NOTICE  "<5>"   /* normal but significant condition */
#define APP_INFO    "<6>"   /* informational */
#define APP_DEBUG   "<7>"   /* debug-level messages */

/* 信息的默认调试级别 */
#define DEFAULT_DBGLEVEL  4

typedef struct debug_opt
{
  char *name;
  int is_can_use;
  int (*debug_init)(void); /* 调试模块的初始化函数 */
  int (*debug_exit)(void); /* 退出函数 */
  int (*debug_print)(char *data); /* 输出函数 */
  struct debug_opt *next;
} debug_opt_t, *debug_t;

int DebugRegister(debug_t node);
void DebugShow(void);
debug_t DebugGet(char *name);
int DebugSetLevel(char *buffer);
int DebugSetChannel(char *buffer);
int DebugInit(void);
int DebugPrint(const char *format, ...);
int DebugChannelInit(void);
int StdoutInit(void);

#endif /* _DEBUG_MANAGE_H_ */

#include "debug_manage.h"
#include <stdio.h>
#include <stdarg.h>
#include <string.h>

static debug_t head;
static int debug_leval_limit = DEFAULT_DBGLEVEL;

int DebugRegister(debug_t node)
{
  debug_t point;

  if(!head)
  {
    head = node;
    head->next = NULL;
  }
  else
  {
    point = head;

    while(point->next)
    {
      point = point->next;
    }
    point->next = node;
    node->next = NULL;
  }

  return 1;
}


void DebugShow(void)
{
  int i = 0;
  debug_t point = head;

  while(point)
  {
    DebugPrint("%02d %s\n", i++, point->name);
    point = point->next;
  }
}

debug_t DebugGet(char * name)
{
  debug_t point = head;

  while(point)
  {
    if(strcmp(point->name, name) == 0)
    {
      return point;
    }
    point = point->next;
  }

  return NULL;
}

int DebugSetLevel(char * buffer)
{
  debug_leval_limit = buffer[9] - '0';
  printf("debug_leval_limit = %d\r\n", debug_leval_limit);

  return 0;
}

int DebugSetChannel(char * buffer)
{
  char *temp, name[100];
  debug_t point;

  temp = strchr(buffer, '=');

  if(!temp)
  {
    return -1;
  }
  else
  {
    strncpy(name, buffer, temp - buffer);
    name[temp - buffer] = '\0';
    point = DebugGet(name);

    if(!point)
    {
      return -1;
    }
    if(temp[1] == '0')
    {
      point->is_can_use = 0;
    }
    else
    {
      point->is_can_use = 1;
    }

    return 0;
  }
}

int DebugPrint(const char * format, ...)
{
  char buffer[1000];
  char *temp;
  va_list list;
  int num;
  debug_t point = head;
  int debug_level = DEFAULT_DBGLEVEL;

  /* 可变参数的处理, 抄自glibc的printf函数 */
  va_start (list, format);
  num = vsprintf (buffer, format, list);
  va_end (list);
  buffer[num] = '\0';

  temp = buffer;

  /* 根据打印级别决定是否打印 */
  if ((buffer[0] == '<') && (buffer[2] == '>'))
  {
    debug_level = buffer[1] - '0';
    if (debug_level >= 0 && debug_level <= 9)
    {
      temp = buffer + 3;
    }
    else
    {
      debug_level = DEFAULT_DBGLEVEL;
    }
  }

  if (debug_level >= debug_leval_limit)
  {
    return -1;
  }

  /* 调用链表中所有isCanUse为1的结构体的DebugPrint函数
   * 用来输出调试信息
   */
  while (point)
  {
    if (point->is_can_use)
    {
      point->debug_print(temp);
    }
    point = point->next;
  }

  return 0;
}

int DebugChannelInit(void)
{
  debug_t point = head;

  while(point)
  {
    if(point->is_can_use && point->debug_init)
    {
      point->debug_init();
    }

    point = point->next;
  }

  return 0;
}

static int stdout_debug_print(char *data)
{
  printf("%s", data);

  return strlen(data);
}

static debug_opt_t debug_stdout =
{
  .name = "stdout",
  .is_can_use = 1,
  .debug_print = stdout_debug_print,
};


int StdoutInit(void)
{
  return DebugRegister(&debug_stdout);
}


int DebugInit(void)
{
  int error;

  error = StdoutInit();
// error |= NetPrintInit();

  return error;
}

int main(void)
{
  int error = DebugInit();

  printf("error: %d\n", error);
  DebugPrint("---------------\n");

  return 0;
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Segmentation fault(简称SIGSEGV,段错误)是指程序访问了不该访问或不能访问的内存地址,导致程序异常终止。在Linux系统下,这种错误通常会导致程序崩溃并输出错误消息"Segmentation fault"。 造成这种错误的原因有很多,例如: - 尝试访问空指针 - 尝试访问不属于该进程的内存 - 尝试读写只读内存 - 由于缓冲区溢出导致的程序错误 - …… 如果您在Linux系统下遇到了Segmentation fault错误,可以尝试使用GDB调试器进行调试,以确定错误的具体原因。 ### 回答2: 在Linux操作系统中,出现"Segmentation fault"(即内存分段错误)通常是指程序访问了不存在或不可访问的内存地址,从而导致程序崩溃。这个错误通常是由于以下几个原因引起的: 1. 空指针引用:当程序中的指针没有被正确初始化或者指向了无效的内存地址时,对该指针进行访问就会导致Segmentation Fault错误。 2. 内存越界:当程序访问数组或者其他数据结构时,如果超出了其所分配的内存范围,就会出现Segmentation Fault错误。 3. 堆栈溢出:当程序递归调用层数过多,或者使用了过多的局部变量,导致栈空间不足时,会触发段错误。 4. 动态内存管理错误:当使用动态内存分配函数(如malloc、calloc等)分配内存后,忘记释放或者错误释放该内存,会导致Segmentation Fault错误。 要解决Segmentation Fault错误,我们可以通过以下方法进行排查和修复: 1. 检查代码:仔细检查代码,查找是否有空指针引用、越界访问或者内存释放错误等问题。 2. 使用调试器:借助调试器(如gdb),可以在出现Segmentation Fault错误时进行调试,通过查看变量地址、回溯调用栈等信息,定位问题所在。 3. 加入调试输出:在可能出错的位置添加调试输出语句,打印相关变量的值,以便更好地理解问题出现的原因。 4. 检查内存管理:仔细检查动态内存分配的使用情况,确保正确分配和释放内存。 再次强调,Segmentation Fault错误是一种常见的运行时错误,通过仔细检查代码和使用调试工具,我们可以定位和修复问题,使程序在Linux下正常运行。 ### 回答3: 在Linux操作系统中,"segmentation fault"(段错误)是一种常见的运行时错误。它通常是由访问未分配给程序的内存地址或者未分配的内存段导致的。 当程序试图访问一个不合法的内存地址时,操作系统会发出一个"segmentation fault"信号,终止程序的运行并输出该错误信息。这个错误可能是由以下几种情况引起的: 1. 访问空指针:程序试图使用一个未初始化或者指向空地址的指针。 2. 数组越界访问:程序试图访问超出数组边界的索引,即访问数组中不存在的元素。 3. 栈溢出:当程序的递归调用深度过大或者函数调用层次嵌套过多时,可能导致栈空间溢出。 4. 内存泄漏:程序中未释放的动态分配的内存可能会导致内存耗尽,从而导致"segmentation fault"。 解决"segmentation fault"错误的方法通常是通过调试程序找到导致错误的代码,并修复相应的错误。可以使用工具如GDB进行调试,定位错误出现的位置。 可以采取的一些常见的调试策略包括: - 检查代码中是否存在未初始化或未分配正确地址的指针。 - 检查数组索引是否超出了数组的界限。 - 检查递归调用和函数调用层次是否过深。 - 检查内存分配和释放是否匹配,在动态内存分配后确保及时释放。 总之,"segmentation fault"是一个常见的运行时错误,它通常是由于程序访问不合法的内存地址或者超出内存限制导致的。通过调试程序并修复相应的错误,我们可以解决这个问题。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值