程序退出时的 Segfault (-11)

Posted

技术标签:

【中文标题】程序退出时的 Segfault (-11)【英文标题】:Segfault (-11) on program exit 【发布时间】:2021-05-10 14:41:12 【问题描述】:

我正在尝试让goocanvasmm 从 C++ 程序中工作。来自一对 我结合了代码 sn-ps 并让程序绘制的地方。

但是,在程序终止时,会出现段错误。我不是普通的C++ 用户, 因此,gdb 消息对我来说有点神秘。

这是代码。它创建一个窗口,并在其中绘制一个 200x200 像素的黄色方块:

#include <gtkmm.h>
#include <goocanvasmm.h>
#include <iostream>
#define UI_FILE "gtk_foobar.ui"

int
main (int argc, char *argv[]) 
  Gtk::Main kit(argc, argv);

  //Load the Glade file and instiate its widgets:
  Glib::RefPtr<Gtk::Builder> builder;
  try 
    builder = Gtk::Builder::create_from_file(UI_FILE);
  
  catch (const Glib::FileError & ex) 
    std::cerr << ex.what() << std::endl;
    return 1;
  
  
  Gtk::Window *main_win = 0;
  builder->get_widget("main_window", main_win);
  
  Goocanvas::Canvas canvas;
  
  main_win->add(canvas);
  auto root = (canvas).get_root_item();
  auto rect = Goocanvas::Rect::create(100, 100, 200, 200);
  
  rect->property_stroke_color() = "yellow";
  rect->property_line_width() = 3;
  root->add_child(rect);
  
  main_win->show_all();

  if (main_win) 
    kit.run(*main_win);
  
  return 0;

运行时错误消息(在程序终止时显示):

Program has been terminated receiving signal 11 (Segmentation fault)

还有gdb 回溯:

#0  0x00007ffff5ae7d6c in free () at /lib64/libc.so.6
#1  0x00007ffff5a97736 in __cxa_finalize () at /lib64/libc.so.6
#2  0x00007ffff7d22946 in __do_global_dtors_aux () at /usr/lib64/libgoocanvasmm-2.0.so.6
#3  0x00007ffff7ffd060 in _rtld_local () at /lib64/ld-linux-x86-64.so.2
#4  0x0000000000000000 in  ()

如果我没记错的话,这似乎表明在 libgoocanvasmm.

编辑:我意识到(有点晚了),要运行应用程序,还需要UIFILE。这是(“gtk_foobar.ui”):

<?xml version="1.0"?>
<interface>
  <!-- interface-naming-policy project-wide -->
  <!-- interface-requires gtk+ 3.0 -->
  <object class="GtkWindow" id="main_window">
    <property name="visible">True</property>
    <property name="title" translatable="yes">Hello World!</property>
    <property name="default_width">500</property>
    <property name="default_height">400</property>
    <child>
      <placeholder/>
    </child>
  </object>
</interface>

为方便起见,this link 将下载完整的 autotools 项目。

【问题讨论】:

您是否尝试在您的main 中的return 0; 之前编码main_win = nullptr; @BasileStarynkevitch:没有变化 - 仍然是段错误。谢谢! 感谢您的可重现示例,我可以构建并运行您的程序。我正在使用带有 GCC 的 Ubuntu。为了构建它,我在官方 Ubuntu 存储库中安装了 libgoocanvasmm 项目。运行您的程序时,我注意到没有段错误,即使在退出时也是如此。它似乎与您正在使用的特定版本有关,或者可能与您正在运行它的平台有关。你正在那个操作系统上构建什么版本的 goocanvas? @BobMorane 我想问的问题完全一样。 pkg-config 报告 1.90.9,但在某处我读到 2.0.6。我现在在 Ubuntu 存储库中看到,版本是 1.90.11,但包实际上也是 2.0.6?无论如何,我在download-fallback.gnome.org/sources/goocanvasmm/1.90 找到了.11 源代码,编译后错误消失了!感谢您的测试! 无需在标题中加上“已解决”——只要系统允许就接受您的回答 【参考方案1】:

感谢@BobMorane,他测试了程序并发现了库之间的微小版本差异。似乎我的源包和他的源包都标记为 2.0.6,但在内部有一个小的区别,1.90.9 和 1.90.11,这很重要。

用1.90.11版本重新编译解决了问题!

查看变更日志并没有发现令人震惊的差异,而是进行了一系列小的兼容性更新。重新运行 valgrind 确实显示此消息消失了:

==30082== Invalid free() / delete / delete[] / realloc()
==30082==    at 0x483B71B: operator delete(void*) (vg_replace_malloc.c:802)
==30082==    by 0x6C25735: __cxa_finalize (in /lib64/libc-2.30.so)
==30082==    by 0x48FB945: ??? (in /usr/lib64/libgoocanvasmm-2.0.so.6.0.0)
==30082==    by 0x4914FC0: ??? (in /usr/lib64/libgoocanvasmm-2.0.so.6.0.0)
==30082==    by 0x6C25016: __run_exit_handlers (in /lib64/libc-2.30.so)
==30082==    by 0x6C251C9: exit (in /lib64/libc-2.30.so)
==30082==    by 0x6C03E61: (below main) (in /lib64/libc-2.30.so)
==30082==  Address 0x8 is not stack'd, malloc'd or (recently) free'd

【讨论】:

以上是关于程序退出时的 Segfault (-11)的主要内容,如果未能解决你的问题,请参考以下文章

删除原始缓冲区时的opencv cvarrtoMat segfault

调用 glDrawArrays() 时的 OpenGL VBO Segfault

从Assembly调用C函数(printf)时的Segfault

创建 avx 向量时的 Segfault

返回包含向量的空向量时的C++ Segfault

取消引用自定义mem地址时的Segfault(C)