You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Glib::DateTime触发Segmentation Fault问题排查及用法确认

GLib::DateTime 段错误问题排查

问题重现

测试代码

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

int main()
{
    Glib::DateTime start_time;
    long int tv_sec = start_time.to_unix();
    long int tv_usec = start_time.get_microsecond();

    printf("%ld %ld\n", tv_sec, tv_usec);
}

编译命令

$ g++ `pkg-config --cflags glibmm-2.4` main.cpp `pkg-config --libs glibmm-2.4`

运行错误

Segmentation fault (core dumped)

GDB调试信息

编译带调试信息后运行GDB:

$ g++ -g `pkg-config --cflags glibmm-2.4` main.cpp `pkg-config --libs glibmm-2.4`
$ gdb ./a.out
(gdb) break main
(gdb) run
Breakpoint 1, main () at main.cpp:6
6    {
(gdb) next 2
9        tv.tv_sec = start_time.to_unix();
(gdb) next

Program received signal SIGSEGV,Segmentation fault.
0x00007ffff6881854 in g_date_time_to_unix () from /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0
(gdb) disas
    0x#### push %rbx
    0x#### mov %rdi,%rbx
==> 0x#### mov 0x10(%rdi),%esi
    ....
(gdb) info reg rbx rdi
rbx 0x0  0
rdi 0x0  0
(gdb) where
#0 0x#### in g_date_time_to_unix () at /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0
#1 0x#### in main() () at main.cpp:9

(部分地址已省略)

用户问题

  1. 如何排查问题根源?
  2. 是否错误使用了DateTime类?

解答

问题2:确实错误使用了DateTime类

Glib::DateTime的默认构造函数创建的是无效空对象,其底层封装的GDateTime指针为nullptr。直接调用to_unix()或get_microsecond()这类成员函数时,会间接调用GLib的C API(如g_date_time_to_unix()),而这些API要求传入有效的GDateTime指针,空指针访问就会触发段错误。

正确用法是通过GLibmm提供的静态工厂方法创建有效实例,比如:

  • 获取当前本地时间:Glib::DateTime start_time = Glib::DateTime::create_now_local();
  • 获取当前UTC时间:Glib::DateTime start_time = Glib::DateTime::create_now_utc();
  • 从Unix时间戳创建:Glib::DateTime start_time = Glib::DateTime::create_from_unix_local(tv_sec);

修改后的测试代码示例:

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

int main()
{
    // 创建当前本地时间的有效实例
    Glib::DateTime start_time = Glib::DateTime::create_now_local();
    long int tv_sec = start_time.to_unix();
    long int tv_usec = start_time.get_microsecond();

    printf("%ld %ld\n", tv_sec, tv_usec);
}

问题1:排查这类问题的常用方法

  • 利用GDB定位参数合法性:从调试信息看,rdi寄存器值为0,说明传入g_date_time_to_unix()的是nullptr,直接指向底层C API的参数非法,进而回溯到C++对象未正确初始化。
  • 查阅库文档确认对象生命周期:GLibmm的DateTime文档明确说明,默认构造的对象是无效的,必须通过工厂方法创建有效实例;调用成员函数前可通过is_valid()方法检查对象状态。
  • 编译时开启高警告等级:添加-Wall -Wextra编译选项,虽然不一定直接提示空对象问题,但能帮助发现其他潜在的不规范用法。
  • 分步调试验证对象状态:在创建对象后,通过GDB打印对象的底层指针(比如print start_time.gobj()),确认是否为nullptr,快速定位空对象问题。

内容的提问来源于stack exchange,提问作者harper

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 18:15:06