【问题标题】:Segmentation Fault when loading font with FreeTypeC 中的分段错误故障排除
【发布时间】:2012-09-02 11:31:24
【问题描述】:

我正在尝试将 FreeType 库与 libpng 一起使用来输出字形的 PNG 图像。我的代码编译得很好,但是我遇到了分段错误。这是 gdb 的一些调试输出(我不知道该怎么做):

(gdb) run
Starting program: /home/david/Desktop/a.out 

Program received signal SIGSEGV, Segmentation fault.
0x00007ffff76a58a5 in ?? () from /lib/x86_64-linux-gnu/libc.so.6
(gdb) where
#0  0x00007ffff76a58a5 in ?? () from /lib/x86_64-linux-gnu/libc.so.6
#1  0x00007ffff7bcb298 in png_write_row (png_ptr=0x611320, row=<optimized out>)
    at /usr/include/x86_64-linux-gnu/bits/string3.h:52
#2  0x00007ffff7bcb56c in png_write_image (png_ptr=0x611320, image=0x60d218)
    at pngwrite.c:608
#3  0x0000000000400c35 in main ()

这是代码:

#include <stdlib.h>
#include <stdio.h>
#include <png.h>

#include <ft2build.h>
#include FT_FREETYPE_H

main() {

    // Declare FreeType variables
    FT_Library library;
    FT_Face face;
    FT_GlyphSlot slot;
    FT_UInt glyph_index = 30;
    char* font_file = "/usr/share/fonts/truetype/freefont/FreeMono.ttf";

    // Declare PNG variables
    png_uint_32 width = 100;
    png_uint_32 height = 100;
    int bit_depth = 16;
    int color_type = PNG_COLOR_TYPE_GRAY;
    char* file_name = "/home/david/Desktop/out.png";
    png_structp png_ptr;
    png_infop info_ptr;

    // Render font
    int error;
    error = FT_Init_FreeType(&library);
    error = FT_New_Face(library, font_file, 0, &face);
    error = FT_Set_Pixel_Sizes(face, 100, 100);
    error = FT_Load_Glyph(face, glyph_index, FT_LOAD_DEFAULT);
    error = FT_Render_Glyph(face->glyph, FT_RENDER_MODE_NORMAL);

    if (error) {
        printf("ERROR CODE: %d", error);
    }

    // Create a PNG file
    FILE *fp = fopen(file_name, "wb");

    // Create the PNG in memory
    png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
    info_ptr = png_create_info_struct(png_ptr);
    png_init_io(png_ptr, fp);

    // Write the header
    png_set_IHDR(png_ptr, info_ptr, width, height, bit_depth, color_type, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
    png_write_info(png_ptr, info_ptr);

    // Write image data
    slot = face->glyph;
    png_write_image(png_ptr, &slot->bitmap.buffer);

    // End write
    png_write_end(png_ptr, NULL);

    fclose(fp);
}

更新

我正在尝试一种稍微新的方法(使用 png_write_row 而不是 png_write_image)。

... SAME AS BEFORE ABOVE ....

// Write image data
slot = face->glyph;

int x, y, offset;
for (y = 0; y < slot->bitmap.rows; y++) {
    for (x = 0; x < slot->bitmap.width; x++) {
        offset = y*(slot->bitmap.width) + x;
        png_write_row(png_ptr, &slot->bitmap.buffer[offset]);
    }
}

// End write
png_write_end(png_ptr, NULL);

fclose(fp);

}

现在我得到了一些更有用的 libpng 错误,但我仍然不确定如何处理它们:

libpng warning: zstream not in use (internal error)
libpng error: stream error
Aborted (core dumped)

【问题讨论】:

  • 你试过用-g编译你的程序吗(如果你使用的是gcc)?那么 gdb 输出会更有帮助。
  • 您可以使用受影响库的调试变体,例如使用 libc6-dbglibpng-dbg 包。您还应该使用valgrind 并使用gcc -Wall -Wextra -g 进行编译
  • 一个非常基本的规则:检查所有API调用的返回值。
  • 谢谢@KarolyHorvath。我现在正在检查所有 API 调用的返回值。仍然没有错误/警告。
  • @AndreasHenning:我尝试将 -g、-Wall 和 -Wextra 添加到 gcc,但我似乎没有使用 gdb 获得更多信息(我对调试有点陌生方式)。

标签: c segmentation-fault libpng freetype


【解决方案1】:

两个建议:

  1. 查看所有编译器警告以查看指针类型是否正确匹配。

  2. 更好地跟踪可能的错误。比如这样写:

    int error;
    error = FT_Init_FreeType(&library);
    if (error) {
        printf("ERROR CODE: %d", error);
    }
    error = FT_New_Face(library, font_file, 0, &face);
    if (error) {
        printf("ERROR CODE: %d", error);
    }
    error = FT_Set_Pixel_Sizes(face, 100, 100);
    if (error) {
        printf("ERROR CODE: %d", error);
    }
    error = FT_Load_Glyph(face, glyph_index, FT_LOAD_DEFAULT);
    if (error) {
        printf("ERROR CODE: %d", error);
    }
    error = FT_Render_Glyph(face->glyph, FT_RENDER_MODE_NORMAL);
    
    if (error) {
        printf("ERROR CODE: %d", error);
    }
    

其中一个调用的任何错误都可能导致指针错位,从而触发分段错误。

这很明显:

FILE *fp = fopen(file_name, "wb");
if ( fp == null ) {
    printf ("Unable to open file for writing"):
}

但是,例如,如果您尝试将文件写入没有权限的目录中,您将有 fp 指向 NULL 和进一步的分段错误。

【讨论】:

  • 嗨,埃尔南。感谢您的建议。我添加了所有错误输出,但没有错误。它也可以在没有警告的情况下编译。还在努力……
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-10-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多