X11 DefaultRootWindow Segfault 仅当程序由 Systemctl 运行时

问题描述

我是 Linux 和 C 开发的新手,尝试使用 X11 库在 C 中截取屏幕截图。 如果我正常编译和运行我的程序,屏幕截图是正确的,没有问题。如果我将程序作为服务运行,例如

sudo systemctl start screenshot

程序失败。日志和用 GDB 分析 coredump 都只说

Program terminated with signal SIGSEGV,Segmentation fault.

我在我的代码中设置了手动登录

int main(int argc,char** argv ){
    FILE *fp = fopen("log.txt","w");
    setvbuf(fp,NULL,_IONBF,1024);
    fputs("2",fp);
    display* display = XOpendisplay(NULL);
    fputs("5",fp);
    Window root = DefaultRootwindow(display);
    fputs("6",fp);

当作为服务运行时,log.txt 包含序列 25。如果从终端运行,如 ./screenshot,程序正常终止。

任何有关查找问题原因的提示将不胜感激。

解决方法

David 指出要检查 display 是否为 NULL,一些搜索发现问题是程序作为服务运行时无法打开显示。

基于这个问题:https://unix.stackexchange.com/questions/537628/error-cannot-open-display-on-systemd-service-which-needs-graphical-interface

在systemd服务文件中设置环境为

Environment=DISPLAY=:0.0
Environment=XAUTHORITY=/home/<username>/.Xauthority

解决了问题,服务正常运行。