5_01_GLib库入门与实践_错误、告警和断言

简介

Linux系统编程中,有一个errno的变量,还有与之对应的perror及strerrno函数,在GLib中,也有相关的一组功能函数GError(源码在gerror.[ch]两个文件),与errno类似。注意,GLib的GError是独立的系统,其错误码与Linux的errno错误码并不相同。
GLib还专门提供了一组告警和断言的操作函数,源码在gmessages.[ch]两个文件。

数据结构

GError的数据结构体见下。
其中,code是错误码,message是错误码对应的字符串。

struct GError {
  GQuark       domain;
  gint         code;
  gchar       *message;
};

函数列表

错误系统

GError * 	g_error_new ()
GError * 	g_error_new_literal ()
GError * 	g_error_new_valist ()
void 	g_error_free ()
GError * 	g_error_copy ()
gboolean 	g_error_matches ()
void 	g_set_error ()
void 	g_set_error_literal ()
void 	g_propagate_error ()
void 	g_clear_error ()
void 	g_prefix_error ()
void 	g_propagate_prefixed_error ()

告警和断言

void 	g_print ()
GPrintFunc 	g_set_print_handler ()
void 	(*GPrintFunc) ()
void 	g_printerr ()
GPrintFunc 	g_set_printerr_handler ()
#define 	g_return_if_fail()
#define 	g_return_val_if_fail()
#define 	g_return_if_reached
#define 	g_return_val_if_reached()
#define 	g_warn_if_fail()
#define 	g_warn_if_reached
void 	g_on_error_query ()
void 	g_on_error_stack_trace ()
#define 	G_BREAKPOINT

函数功能分类

本章功能分为两大类:错误系统,告警和断言
错误系统

// 创建一个GError对象
GError * 	g_error_new ()
// 创建一个GError对象,可包含非printf打印字符
GError * 	g_error_new_literal ()
// 创建一个GError对象,参数来自va_list
GError * 	g_error_new_valist ()
// 释放一个创建的GError对象
void 	g_error_free ()
// 拷贝一个GError对象。注意这是一个深拷贝,由于GError的message成员是一个指针,因此在进行拷贝时,会申请新的内存。
GError * 	g_error_copy ()
// 是否匹配给定的错误域及错误码
gboolean 	g_error_matches ()
// 向GError系统设置一个错误对象
void 	g_set_error ()
// 设置错误对象,可包含非printf打印字符
void 	g_set_error_literal ()
// 传递一个错误对象,如果目的参数参数为空,则释放源错误,如果目的参数非空,则将源参数地址赋值给目的参数
void 	g_propagate_error ()
// 清空GError对象
void 	g_clear_error ()
// 将字符串加到一个已存在的GError对象上
void 	g_prefix_error ()
// g_propagate_error与g_prefix_error的组合
void 	g_propagate_prefixed_error ()

告警和断言

// 输出,默认输出到stdout,如果设置了输出句柄函数,则调用该句柄函数,由句柄函数决定输出到何处
void 	g_print ()
// 设置输出句柄,改变默认输出行为
GPrintFunc 	g_set_print_handler ()
void 	(*GPrintFunc) ()
// 错误输出,默认输出到stderr,如果设置了错误信息输出句柄,则调用该句柄函数,由句柄函数决定输出到何处
void 	g_printerr ()
// 设置错误输出句柄,改变默认错误输出行为
GPrintFunc 	g_set_printerr_handler ()
// 如果表达式为假则返回,无返回值,在void类型的函数中被调用。
#define 	g_return_if_fail()
// 如果表达式为假则返回,带返回值
#define 	g_return_val_if_fail()
// 当运行到本句时立即返回,无返回值,在void类型的函数中被调用。
#define 	g_return_if_reached
// 当运行到本句时立即返回,有返回值
#define 	g_return_val_if_reached()
// 不返回,只告警
#define 	g_warn_if_fail()
// 运行到本句时不返回,只告警
#define 	g_warn_if_reached
// 出现错误时提示,退出,挂起,打印堆栈,返回
void 	g_on_error_query ()
// 跟踪堆栈信息
void 	g_on_error_stack_trace ()
// 打印一个断点,当运行到本句时,产生一个SIGRAP的信号,并退出函数。
#define 	G_BREAKPOINT

函数功能说明及综合演示

设置输出句柄改变输出行为

以下四个函数与输出有关。g_print默认输出到标准输出stdout,g_printerr默认输出到标准错误输出stderr。如果设置了handler,则其输出行为由handler决定。

void 	g_print ()
GPrintFunc 	g_set_print_handler ()
void 	g_printerr ()
GPrintFunc 	g_set_printerr_handler ()

下面演示设置和取消handler的效果。
示例代码如下:
源码见glib_examples\glib_warning_and_assert\glib_warning_and_assert_print_handler

#include <stdio.h>
#include <glib.h>

void _print_func(const gchar *string)
{
    printf("[in _print_func]: %s", string);
}

void _printerr_func(const gchar *string)
{
    printf("[in _printerr_func]: %s", string);
}

gint main (gint argc, gchar **argv)
{
    g_print("call g_print \n");
    g_printerr("call g_printerr \n");

    g_set_print_handler(_print_func);
    g_set_printerr_handler(_printerr_func);

    g_print("print handler set! \n");
    g_printerr("printerr handler set! \n");

    g_set_print_handler(NULL);
    g_set_printerr_handler(NULL);

    g_print("after unset g_print handler \n");
    g_printerr("after unset g_printerr handler \n");
    
    return 0;
}

运行结果:

[root@centos7_6 build]# ./glib_warning_and_assert_print_handler
call g_print
call g_printerr
[in _print_func]: print handler set!
[in _printerr_func]: printerr handler set!
after unset g_print handler
after unset g_printerr handler
断言及告警综合演示

示例代码如下:
源码见glib_examples\glib_warning_and_assert\glib_warning_and_assert_if_fail_if_reach

#include <glib.h>

void _return_if_fail()
{
    g_return_if_fail(0);
}

gint _return_val_if_fail()
{
    g_return_val_if_fail(0, 999);
}

void _return_if_reached()
{
    g_return_if_reached();
}

gint _return_val_if_reached()
{
    g_return_val_if_reached(999);
}

gint _warn_if_fail()
{
    g_warn_if_fail(0);
}

void _warn_if_reached()
{
    g_warn_if_reached();
}


gint main (gint argc, gchar **argv)
{
    _return_if_fail();
    _return_val_if_fail();
    _return_if_reached();
    _return_val_if_reached();
    _warn_if_fail();
    _warn_if_reached();

    G_BREAKPOINT();
   
    return 0;
}

运行结果:

[root@centos7_6 build]# ./glib_warning_and_assert_if_fail_if_reach

** (process:56890): CRITICAL **: 20:56:59.991: _return_if_fail: assertion '0' failed

** (process:56890): CRITICAL **: 20:56:59.991: _return_val_if_fail: assertion '0' failed

** (process:56890): CRITICAL **: 20:56:59.991: file /root/glib_examples/glib_warning_and_assert/glib_warning_and_assert_if_fail_if_reach/glib_warning_and_assert_if_fail_if_reach.c: line 15 (_return_if_reached): should not be reached

** (process:56890): CRITICAL **: 20:56:59.991: file /root/glib_examples/glib_warning_and_assert/glib_warning_and_assert_if_fail_if_reach/glib_warning_and_assert_if_fail_if_reach.c: line 20 (_return_val_if_reached): should not be reached

** (process:56890): WARNING **: 20:56:59.991: (/root/glib_examples/glib_warning_and_assert/glib_warning_and_assert_if_fail_if_reach/glib_warning_and_assert_if_fail_if_reach.c:25):_warn_if_fail: runtime check failed: (0)

** (process:56890): WARNING **: 20:56:59.991: (/root/glib_examples/glib_warning_and_assert/glib_warning_and_assert_if_fail_if_reach/glib_warning_and_assert_if_fail_if_reach.c:30):_warn_if_reached: code should not be reached
Trace/breakpoint trap(吐核)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值