【发布时间】:2026-01-24 07:35:01
【问题描述】:
我正在制作一个显示任务栏的程序,其中包含来自打开窗口的图标。我做了一个函数,它需要两个指针和一些额外的辅助数据。 icon_Data 和icon_Data_Ptr 这两个指针分别指向原子_NET_WM_ICON 返回的数据和我要使用的具体图标。下面是函数:
static Pixmap create_Pixmap_From_Icon_Data(Taskbar * taskbar, Taskbar_Item * taskbar_Item, uint32_t * icon_Data_Ptr, uint32_t * icon_Data) {
Pixmap icon_Pixmap = XCreatePixmap(taskbar->display, taskbar->parent, (unsigned int) icon_Data_Ptr[0], (unsigned int) icon_Data_Ptr[1], 32);
XImage * x_Image = XCreateImage(taskbar->display, taskbar->visual, 32, ZPixmap, 2, (char *) &icon_Data_Ptr, (unsigned int) icon_Data_Ptr[0], (unsigned int) icon_Data_Ptr[1], 32, 0);
GC temp_GC = XCreateGC(taskbar->display, icon_Pixmap, 0, 0);
XPutImage(taskbar->display, icon_Pixmap, temp_GC, x_Image, 0, 0, 0, 0, icon_Data_Ptr[0], icon_Data_Ptr[1]);
x_Image->data = (char *) icon_Data;
XDestroyImage(x_Image);
XFreeGC(taskbar->display, temp_GC);
return icon_Pixmap;
}
每当我尝试运行程序时,它大约有一半的时间会出现段错误。 Gdb 的堆栈跟踪如下:
#0 __memmove_sse2_unaligned_erms ()
在 ../sysdeps/x86_64/multiarch/memmove-vec-unaligned-erms.S:262
#1 0x00007ffff7c9f6b0 in memcpy (__len=,
__src=0x7fffffffdd48, __dest=)
在 /usr/include/x86_64-linux-gnu/bits/string_fortified.h:34
#2 SendZImage (dest_scanline_pad=,
dest_bits_per_pixel=32,req_yoffset=0,
req_xoffset=, image=0x459dd0,
req=, dpy=0x4062a0)
在 ../../src/PutImage.c:795
#3 PutImageRequest (gc=,
dest_scanline_pad=, dest_bits_per_pixel=32,
req_height=, req_width=,
y=, x=, req_yoffset=0,
req_xoffset=, image=0x459dd0,
d=, dpy=0x4062a0) 在 ../../src/PutImage.c:861
#4 PutSubImage (dpy=0x4062a0, d=,
gc=, image=0x459dd0,
req_xoffset=, req_yoffset=,
x=0, y=0, req_width=48, req_height=48,
dest_bits_per_pixel=32, dest_scanline_pad=32)
在 ../../src/PutImage.c:899
#5 0x00007ffff7c9faae 在 XPutImage (dpy=0x4062a0, d=23068677,
gc=0x459e60,图像=0x459dd0,req_xoffset=0,req_yoffset=0,
x=0, y=0, req_width=48, req_height=48)
在../../src/PutImage.c:1018
#6 0x00000000004022bc 在 create_Pixmap_From_Icon_Data (
任务栏=0x4088e0,任务栏_项目=0x413760,
icon_Data_Ptr=0x4579b8, icon_Data=0x413890) 在 taskbar.c:206
#7 0x0000000000402032 在 find_And_Set_Pixmap_From_Property_Data
(任务栏=0x4088e0,任务栏_项目=0x413760,
icon_Data=0x413890, item_Count=72012) 在 taskbar.c:231
#8 0x0000000000401c48 在 set_Taskbar_Item_Icon_Pixmap (
任务栏=0x4088e0,任务栏_项目=0x413760,实例=0x408860)
在 taskbar.c:256
#9 0x000000000040196c 在 add_Instance_To_New_Taskbar_Item (
任务栏=0x4088e0,实例=0x408860)在taskbar.c:315
#10 0x000000000040170e 在 add_Window_If_Necessary (
--键入 获取更多信息,q 退出,c 继续不分页--
任务栏=0x4088e0,窗口=18876630)在taskbar.c:386
#11 0x0000000000402ae5 in iterate_Through_All_Windows (
任务栏=0x4088e0,显示=0x4062a0,屏幕=0,
iterator_Callback=0x401690 )
在 taskbar_Test.c:31
#12 0x0000000000402997 在 setup_Taskbar (taskbar=0x7fffffffdfb8,
显示=0x4062a0,屏幕=0,父=23068674,
视觉= 0x408430,颜色图= 23068673)在taskbar_Test.c:42
#13 0x00000000004027bf in main () at taskbar_Test.c:72
在我调试它的其他时间,我已经检查以确保 icon_Data_Ptr 有足够的数据让 XCreatePixmap 运行,确实如此。然而,奇怪的是,我发现当 Gdb 进入 XCreatePixmap 时,指向函数内部数据的指针与函数外部的地址不同。此外,在使用 GDB 时,我发现当我在 XCreateImage 内部时,图像的数据指针不包含足够的数据以使函数工作。我还在 XCreateImage 的函数调用和 XCreateImage 的函数调用内部转储了指向图像数据的内存。我使用 Gimp 导入了这些数据。该图像在函数外部看起来像 chrome 浏览器图标,但在函数内部它看起来像是有序和随机颜色的混合,与 chrome 图标不同。
除了使用 Gdb 之外,我还尝试使用 Clang 代替 GCC 来查看这是否是编译器错误;它产生了同样的错误。
我不知道我做错了什么导致了这个分段错误,任何帮助都将不胜感激。
【问题讨论】:
-
调用Xlib的函数后,应该检查返回值。如果这些返回值是指针,请检查它们是否不为空,然后继续。您似乎没有检查
XCreateImage、XCreatePixmap和XCreateGC的结果。 -
此外,许多函数参数在 GDB 堆栈跟踪中显示为
optimized。你是在 Release 模式下编译吗?请在调试模式下使用-g3编译器选项编译您的程序。这样,optimized的实际值就会显示出来(我希望如此)。 -
刚才,我使用 Gdb 运行我的程序,并打印了 XCreateImage、XCreatePixmap 和 XCreateGC 的输出;他们都给出了有效的值,但仍然崩溃。另外,我的程序没有优化并且设置了最大调试设置,只是优化了 libX11 和 libc。但是,我已经为这两个库安装了 dbgsym 包。
-
由于问题在
memcpy中显示,请检查您是否传递了任何与尺寸相关的参数以及该参数是否正确。尝试访问非法内存时似乎程序崩溃了,这通常发生在尝试越界访问内存时。
标签: c segmentation-fault gdb x11 xlib