1

我在 MinGW 环境中编译了一个 GTK 程序。它工作完美。最近更新了MinGW,重新编译了GTK程序,然后程序总是因为Segmentation fault而停止。我曾尝试使用 gdb 来查找错误,但我做不到。GTK 的配置在新旧 MinGW 中完全相同。因此,我对影响编译的MinGW环境持怀疑态度。我发现 gcc 的版本在两个环境中是不同的:

    old MinGW    new MinGW
gcc    3.4.5     4.7.2

任何的想法?有人遇到这种情况吗?

另一个线索是关于 GTK 本身。我发现程序停在这里:

g_signal_emit_by_name(G_OBJECT(g_object_get_data(G_OBJECT(window), "plat_GA_canvas")), "expose-event", G_TYPE_NONE);

它是根据不同情况绘制图像的画布。在这里它只是发送一个信号来暴露画布。奇怪的是它在旧的 MinGW 中工作。所以我不怀疑这是问题的关键。可能只是一个线索。顺便说一句,我在家里纯Linux环境下编译了GTK程序。它也很完美。

任何的想法?请帮忙。

@duskast,下面是代码的一部分。它有点长。

++++++++++++++++++++++++++++++++++++++++++++++++++++++ +
问题可能发生了—— g_signal_emit_by_name

void ACC_platform_unit_num_changed (GtkWidget *box, GtkWidget *window)
{
  int kind;

  kind = gtk_option_menu_get_history((GtkOptionMenu *)box) + 1;
  if(plat.unit_num != kind)
  {
    plat_GA_canvas_refresh (window);
    g_signal_emit_by_name(G_OBJECT(g_object_get_data(G_OBJECT(window), "plat_GA_canvas")), "expose-event", G_TYPE_NONE);

    plat.unit_num = kind;
    if(plat.unit_num == 1)
    {
      gtk_widget_set_sensitive(g_object_get_data(G_OBJECT(window), "ACC_platform_if_gap"), FALSE);
      gtk_widget_set_sensitive(g_object_get_data(G_OBJECT(window), "ACC_platform_if_big_gap"), FALSE);
      gtk_widget_set_sensitive(g_object_get_data(G_OBJECT(window), "ACC_platform_gap_w"), FALSE);
      gtk_widget_set_sensitive(g_object_get_data(G_OBJECT(window), "ACC_platform_live_load_gap"), FALSE);
    }
    else
    {
      gtk_widget_set_sensitive(g_object_get_data(G_OBJECT(window), "ACC_platform_if_gap"), TRUE);
      if(plat.has_gap)
      {
    gtk_widget_set_sensitive(g_object_get_data(G_OBJECT(window), "ACC_platform_if_big_gap"), TRUE);
    gtk_widget_set_sensitive(g_object_get_data(G_OBJECT(window), "ACC_platform_gap_w"), TRUE);
    gtk_widget_set_sensitive(g_object_get_data(G_OBJECT(window), "ACC_platform_live_load_gap"), TRUE);
      }
      else
      {
    gtk_widget_set_sensitive(g_object_get_data(G_OBJECT(window), "ACC_platform_if_big_gap"), FALSE);
    gtk_widget_set_sensitive(g_object_get_data(G_OBJECT(window), "ACC_platform_gap_w"), FALSE);
    gtk_widget_set_sensitive(g_object_get_data(G_OBJECT(window), "ACC_platform_live_load_gap"), FALSE);
      }
    }
    gap_span_show (g_object_get_data(G_OBJECT(window), "ACC_platform_gap_span_store"));
  }
}

核心绘图功能:

void ACC_GA_draw (cairo_t *cr, int width, int height)
{
/* #define X_MARGIN 30
#define Y_MARGIN 30 */
#define COLUMN_RADIUS_ASSUME 1.6
#define COLUMN_SQUARE_LEN_ASSUME 2.0
  double x, y, x1, y1, x2, y2, scale, x_base, y_base, X_MARGIN, Y_MARGIN;
  double x3, y3, downward_height = 0, downward_width = 0;
  double x_one_unit, y_one_unit, x_total, y_total, gap_value;
  double alpha = 60.0, arrow_side_length = 20.0, arrow_tail_length = 10.0;
  ACC_AXIS *x_axis, *y_axis;
  int i, j, unit_num, downward;
  char *AX, *AY, *Wx_left, *Wx_right, *Wy_top, *Wy_bottom, *gap, *axis;
  cairo_text_extents_t te;

  AX = g_strdup_printf("%.0f", plat.fan_section_AX * 1000);
  AY = g_strdup_printf("%.0f", plat.fan_section_AY * 1000);
  Wx_left = g_strdup_printf("%.0f", plat.walkway_Wx_left * 1000);
  Wx_right = g_strdup_printf("%.0f", plat.walkway_Wx_right * 1000);
  Wy_bottom = g_strdup_printf("%.0f", plat.walkway_Wy_bottom * 1000);
  Wy_top = g_strdup_printf("%.0f", plat.walkway_Wy_top * 1000);

  x_one_unit = plat.fan_section_AX * plat.SDD_num;
  x_total = x_one_unit * plat.unit_num + plat.gap_total + plat.walkway_Wx_left + plat.walkway_Wx_right;
  y_one_unit = plat.fan_section_AY * plat.row_num;
  y_total = y_one_unit + plat.walkway_Wy_bottom + plat.walkway_Wy_top;

  scale = calcu_scale (width, height, x_total, y_total, Wx_left, Wy_top, cr, &X_MARGIN, &Y_MARGIN);

  cairo_set_line_width (cr, NORMAL_LINE_WIDTH * 0.7);
  for(unit_num = 1; unit_num <= plat.unit_num; unit_num++)
  {
    if(unit_num == 1)
      x_base = X_MARGIN;
    else
    {
      double total_gap = 0;

      for(i = 0; i < unit_num - 1; i++)
    total_gap += strtod(g_list_nth(plat.gap_w, i)->data, NULL);

      x_base = X_MARGIN + (x_one_unit * (unit_num - 1) + total_gap) * scale;
    }
    y_base = Y_MARGIN;

    for(i = 0, x_axis = plat.X_axis; x_axis; x_axis = x_axis->next, i++)
    {
      if(i == 0)
    x = x_base;
      else
    x += plat.fan_section_AX * scale;
      y = y_base;
      cairo_move_to(cr, x, y);
      y += y_one_unit * scale;
      cairo_line_to(cr, x, y); /* vertical grid */
      cairo_stroke(cr);

      /* SDD */
      if(i != plat.SDD_num)
      {
    cairo_arrow (cr, x + plat.fan_section_AX / 2 * scale, y + plat.walkway_Wy_bottom * scale, alpha, arrow_side_length, 1, arrow_tail_length);
    cairo_save(cr);
    cairo_set_line_width (cr, BOLD_LINE_WIDTH);
    cairo_set_line_cap(cr, CAIRO_LINE_CAP_SQUARE);
    cairo_move_to(cr, x_base + plat.fan_section_AX / 2 * scale, y + plat.walkway_Wy_bottom * scale + arrow_side_length + arrow_tail_length);
    cairo_rel_line_to(cr, (x_one_unit - plat.fan_section_AX) * scale, 0);
    cairo_stroke(cr);
    cairo_restore(cr);
      }

      /* dim line for A1, A2 ... */
      cairo_move_to(cr, x, y + plat.walkway_Wy_bottom * scale + arrow_side_length + arrow_tail_length + 10);
      cairo_rel_line_to(cr, 0, 20);
      cairo_get_current_point(cr, &x3, &y3);
      if(i != plat.SDD_num)
      {
    cairo_text_align_horizontal_center (cr, AX, 0, 1, plat.fan_section_AX / 2 * scale, -10);
      }
      else
      {
    if(plat.unit_num > 1 && plat.has_gap && unit_num != plat.unit_num)
    {
      gap_value = strtod(g_list_nth(plat.gap_w, unit_num - 1)->data, NULL);
      gap = g_strdup_printf("%.0f", 1000 * gap_value);
      cairo_text_extents(cr, gap, &te);
      if(gap_value * scale < te.x_bearing + te.width)
      {
        downward = 1;
        downward_height = 11;
        downward_width = gap_value * scale;
        cairo_rel_move_to(cr, gap_value / 2 * scale - (te.x_bearing + te.width / 2), 10);
      }
      else
      {
        downward = 0;
        cairo_rel_move_to(cr, gap_value / 2 * scale - (te.x_bearing + te.width / 2), -10);
      }
      cairo_show_text(cr, gap);
      g_free(gap);
    }
    else
      downward = 0;
      }
      if(unit_num == 1 && i == 0)
      {
    cairo_move_to(cr, x - plat.walkway_Wx_left * scale, y + plat.walkway_Wy_bottom * scale + arrow_side_length + arrow_tail_length + 10);
    cairo_rel_line_to(cr, 0, 20);
    cairo_rel_move_to(cr, -25, -10);
    cairo_show_text(cr, Wx_left);
      }
      if(unit_num == plat.unit_num && i == plat.SDD_num)
      {
    cairo_move_to(cr, x + plat.walkway_Wx_right * scale, y + plat.walkway_Wy_bottom * scale + arrow_side_length + arrow_tail_length + 10);
    cairo_rel_line_to(cr, 0, 20);
    cairo_rel_move_to(cr, 3, -10);
    cairo_show_text(cr, Wx_right);
      }

      if(plat.axis_style_SDD == 0) /* 递增 */
    axis = g_strdup_printf("A%d", plat.start_axis_SDD + (unit_num - 1) * (plat.SDD_num + 1) + i);
      else
    axis = g_strdup_printf("A%d", plat.start_axis_SDD + (unit_num - 1) * (plat.SDD_num + 1) - i);
      cairo_text_extents(cr, axis, &te);
      if(!downward || ((i != plat.SDD_num) && (unit_num != 1 && i != 0)))
    cairo_move_to(cr, x3 - te.width / 2, y3 + te.height + 2);
      else
      {
    if(te.width < downward_width)
      cairo_move_to(cr, x3 - te.width / 2, y3 + te.height + downward_height);
    else
    {
      if(i == plat.SDD_num)
        cairo_move_to(cr, x3 - te.width, y3 + te.height + downward_height);
      else
        cairo_move_to(cr, x3, y3 + te.height + downward_height);
    }
      }
      cairo_show_text(cr, axis);
      g_free(axis);
      cairo_stroke(cr);

      for(j = 0, y_axis = plat.Y_axis; y_axis; y_axis = y_axis->next, j++)
      {
    x1 = x_base;
    if(j == 0)
      y1 = y_base + y_one_unit * scale;
    else
      y1 -= plat.fan_section_AY * scale;
    if(i == 0)
    {
      cairo_move_to(cr, x1, y1);
      x1 += x_one_unit * scale;
      cairo_line_to(cr, x1, y1); /* horizontal grid */
      cairo_stroke(cr);
    }

    if(i != plat.SDD_num && j != plat.row_num) /* fan ring */
    {
      cairo_arc(cr, x + plat.fan_section_AX / 2 * scale, y1 - plat.fan_section_AY / 2 * scale, plat.fan_ring_opening_D / 2 * scale, 0, 2 * PI);
      cairo_stroke(cr);
    }

    /* columns */
    if(plat.col_type == 0) /* 砼悬臂住 */
    {
      if(plat.SDD_num % 2 == 0)
      {
        if((i + 1) % 2 == plat.SDD_col_first && (j + 1) % 2 == plat.row_col_first)
        {
          cairo_arc(cr, x, y1, COLUMN_RADIUS_ASSUME * scale, 0, 2 * PI);
          cairo_fill(cr);
          cairo_stroke(cr);
        }
      }
      else
      {
        if(!plat.if_unit_symmetry || unit_num % 2 == 1)
        {
          if((i + 1) % 2 == plat.SDD_col_first && (j + 1) % 2 == plat.row_col_first)
          {
        cairo_arc(cr, x, y1, COLUMN_RADIUS_ASSUME * scale, 0, 2 * PI);
        cairo_fill(cr);
        cairo_stroke(cr);
          }
        }
        else
        {
          if((i) % 2 == plat.SDD_col_first && (j + 1) % 2 == plat.row_col_first)
          {
        cairo_arc(cr, x, y1, COLUMN_RADIUS_ASSUME * scale, 0, 2 * PI);
        cairo_fill(cr);
        cairo_stroke(cr);
          }
        }
      }
    }
    else if(plat.col_type == 1) /* 钢柱 */
    {
      cairo_save(cr);
      cairo_set_line_width (cr, 2 * NORMAL_LINE_WIDTH);
      cairo_move_to(cr, x, y1 - COLUMN_SQUARE_LEN_ASSUME / 2 * scale);
      cairo_rel_line_to(cr, 0, COLUMN_SQUARE_LEN_ASSUME * scale);
      cairo_move_to(cr, x - COLUMN_SQUARE_LEN_ASSUME / 2 * scale, y1 - COLUMN_SQUARE_LEN_ASSUME / 2 * scale);
      cairo_rel_line_to(cr, COLUMN_SQUARE_LEN_ASSUME * scale, 0);
      cairo_move_to(cr, x - COLUMN_SQUARE_LEN_ASSUME / 2 * scale, y1 + COLUMN_SQUARE_LEN_ASSUME / 2 * scale);
      cairo_rel_line_to(cr, COLUMN_SQUARE_LEN_ASSUME * scale, 0);
      cairo_stroke(cr);
      cairo_restore(cr);
    }
    else if(plat.col_type == 2) /* 砼框架柱 */
    {
      cairo_rectangle(cr, x - COLUMN_SQUARE_LEN_ASSUME / 2 * scale, y1 - COLUMN_SQUARE_LEN_ASSUME / 2 * scale, COLUMN_SQUARE_LEN_ASSUME * scale, COLUMN_SQUARE_LEN_ASSUME * scale);
      cairo_fill(cr);
      cairo_stroke(cr);
    }

    /* dim line of AA, AB ... */
    if(unit_num == plat.unit_num && i == 0)
    {
      cairo_move_to(cr, x1 + plat.walkway_Wx_right * scale + 10, y1);
      cairo_rel_line_to(cr, 20, 0);

      if(j != plat.row_num)
      {
        cairo_text_align_horizontal_center (cr, AY, 1, 1, -10, -plat.fan_section_AY / 2 * scale);
      }

      if(j == 0)
      {
        x2 = x1 + plat.walkway_Wx_right * scale + 10 + 20 - 5;
        y2 = y1 + plat.walkway_Wy_bottom * scale;

        cairo_move_to(cr, x1 + plat.walkway_Wx_right * scale + 10, y1);
        cairo_rel_move_to(cr, 0, plat.walkway_Wy_bottom * scale);
        cairo_rel_line_to(cr, 20, 0);

        cairo_rel_move_to(cr, -10, 25);
        cairo_save(cr);
        cairo_rotate(cr, - PI / 2.0);
        cairo_show_text(cr, Wy_bottom);
        cairo_restore(cr);
      }

      if(j == plat.row_num)
      {
        cairo_move_to(cr, x1 + plat.walkway_Wx_right * scale + 10, y1);
        cairo_rel_move_to(cr, 0, -plat.walkway_Wy_top * scale);
        cairo_rel_line_to(cr, 20, 0);

        cairo_rel_move_to(cr, -10, -1);
        cairo_save(cr);
        cairo_rotate(cr, - PI / 2.0);
        cairo_show_text(cr, Wy_top);
        cairo_restore(cr);
      }
      cairo_stroke(cr);
    }
    else if(unit_num == 1 && i == 0)
    {
      if(plat.axis_style_row == 0) /* 递增 */
        axis = g_strdup_printf("A%c", plat.start_axis_row + j);
      else
        axis = g_strdup_printf("A%c", plat.start_axis_row - j);
      cairo_text_extents(cr, axis, &te);
      cairo_move_to(cr, x_base - plat.walkway_Wx_left * scale - 20, y1 + te.height / 2);
      cairo_show_text(cr, axis);
      g_free(axis);
      cairo_stroke(cr);
    }
      }
    }
  }

  /* walkway line */
  x = X_MARGIN - plat.walkway_Wx_left * scale;
  y = Y_MARGIN - plat.walkway_Wy_top * scale;
  cairo_move_to(cr, x, y);
  cairo_rel_line_to(cr, x_total * scale, 0);
  cairo_rel_line_to(cr, 0, y_total * scale);
  cairo_rel_line_to(cr, -x_total * scale, 0);
  cairo_rel_line_to(cr, 0, -y_total * scale);
  cairo_stroke(cr);

  /* dim total line for A1, A2 ... */
  cairo_move_to(cr, X_MARGIN - plat.walkway_Wx_left * scale, Y_MARGIN + (y_one_unit + plat.walkway_Wy_bottom) * scale + arrow_side_length + arrow_tail_length + 10 + 20 - 5);
  cairo_rel_line_to(cr, x_total * scale, 0);
  cairo_stroke(cr);

  /* dim total line for AA, AB ... */
  cairo_move_to(cr, x2, y2);
  cairo_rel_line_to(cr, 0, -y_total * scale);
  cairo_stroke(cr);

  g_free(AX);
  g_free(AY);
  g_free(Wx_left);
  g_free(Wx_right);
  g_free(Wy_bottom);
  g_free(Wy_top);
}

expose-event信号:

static gboolean ACC_GA_expose (GtkWidget *canvas, GdkEventExpose *event, gpointer user_data)
{
  cairo_t *cr;

  cr = gdk_cairo_create (canvas->window);
  if(plat.if_GA_draw)
  {
    ACC_GA_draw (cr, canvas->allocation.width, canvas->allocation.height);
  }
  else
  {
    char *local = char_to_utf8 ("Press button \"生成GA\" to update!!");

    cairo_select_font_face(cr, "Sans", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD);
    cairo_set_font_size(cr, 0.35);
    cairo_move_to(cr, 200, 200);
    cairo_show_text(cr, local);
    g_free(local);

  }
  cairo_destroy (cr);

  return FALSE;
}

在 main() 函数中:

  .
  .
  .
  canvas = gtk_drawing_area_new();
  g_object_set_data(G_OBJECT(window), "plat_GA_canvas", canvas);
  plat.if_GA_draw = 0;
  gtk_widget_show(canvas);
  gtk_box_pack_start(GTK_BOX(sub_main_box), canvas, TRUE, TRUE, 0);
  g_signal_connect(G_OBJECT(canvas), "expose-event", G_CALLBACK(ACC_GA_expose), window);
  .
  .
  .

++++++++++++++++++++++++++++++++++++++++++++++++++++++ +

4

2 回答 2

2

GCC 3.4.5 和 GCC 4.7.2 不兼容 ABI。您需要重建所有代码。

于 2013-03-20T09:38:30.093 回答
0

我在我的程序中发现了一个错误。错误是expose-event画布不止一次暴露,并且第二次崩溃。但我不知道为什么在 gcc3.4.5 或纯 Linux 环境中没有出现该错误。在我修改我的程序后,它适用于 mingw-gcc4.7.2、mingw-gcc3.4.5 和纯 Linux 环境。

另一方面,gcc4.7.2 适用于预编译的 gtk2.10.11,但在我的情况下对于预编译的 gtk2.24.10 失败。这可能是由于 ABI 问题。

我已经发布了另外 2 个帖子:gtk window move then crash and compile GTK+ in MinGW, but failed。它们或多或少与这篇文章有关。

于 2013-04-16T07:18:32.840 回答