简介
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(吐核)