Segmentation fault at dlclose

The MagickWand interface is a new high-level C API interface to ImageMagick core methods. We discourage the use of the core methods and encourage the use of this API instead. Post MagickWand questions, bug reports, and suggestions to this forum.
Post Reply
Alxv
Posts: 1
Joined: 2013-03-06T12:15:56-07:00
Authentication code: 6789

Segmentation fault at dlclose

Post by Alxv »

I'm loading libmagickwand dynamicly with dlopen.
But my program segfault at dlclose.
Here it is program source code:

Code: Select all

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <inttypes.h>
#include <dlfcn.h>

typedef enum
{
  MagickFalse = 0,
  MagickTrue = 1
} MagickBooleanType;

typedef enum
{
  CharPixel = 1
} StorageType;

typedef enum
{
  SincFilter = 15
} FilterTypes;

typedef enum
{
  RedChannel   = 0x0001,
  GreenChannel = 0x0002,
  BlueChannel  = 0x0004,
  AlphaChannel = 0x0008,
} ChannelType;

typedef void MagickWand;

void (*MagickWandGenesis)(void);
void (*MagickWandTerminus)(void);
MagickWand *(*NewMagickWand)(void);
MagickWand *(*DestroyMagickWand)(MagickWand *wand);

MagickBooleanType (*MagickReadImage)(MagickWand *wand, const char *filename);
MagickBooleanType (*MagickSetImageFormat)(MagickWand *wand, const char *format);
MagickBooleanType (*MagickSetImageChannelDepth)
    (MagickWand *wand, const ChannelType channel, const unsigned long depth);
unsigned char *(*MagickGetImageBlob)(MagickWand *wand, size_t *length);
unsigned long (*MagickGetImageWidth)(MagickWand *wand);
unsigned long (*MagickGetImageHeight)(MagickWand *wand);
void *(*MagickRelinquishMemory)(void *resource);

void *libmagickwand;

#define get_func(func) (func = dlsym(libmagickwand, #func))

void libmagickwand_init(void)
{
    if (libmagickwand == NULL)
    {
        libmagickwand = dlopen("libMagickWand.so.3", RTLD_LAZY);
        if (libmagickwand == NULL)
        {
            fputs(dlerror(), stderr);
            return;
        }
        if
        (
            get_func(MagickWandGenesis)          == NULL ||
            get_func(MagickWandTerminus)         == NULL ||
            get_func(NewMagickWand)              == NULL ||
            get_func(DestroyMagickWand)          == NULL ||
            get_func(MagickReadImage)            == NULL ||
            get_func(MagickSetImageFormat)       == NULL ||
            get_func(MagickSetImageChannelDepth) == NULL ||
            get_func(MagickGetImageBlob)         == NULL ||
            get_func(MagickGetImageWidth)        == NULL ||
            get_func(MagickGetImageHeight)       == NULL ||
            get_func(MagickRelinquishMemory)     == NULL
        )
        {
            fputs("Some function missing in \"libMagickWand.so.3\"", stderr);
            dlclose(libmagickwand);
            libmagickwand = NULL;
            return;
        }
        MagickWandGenesis();
    }
}

void libmagickwand_free()
{
    if (libmagickwand != NULL)
    {
        MagickWandTerminus();
        dlclose(libmagickwand);
        libmagickwand = NULL;
    }
}

typedef struct
{
    uint32_t width, height, *rgba;
} image;

int load_image(char *file, image *img)
{
    if (libmagickwand == NULL)
        return 0;

    MagickWand *mw = NewMagickWand();
    if (mw == NULL)
        return 1;

    int result = 0;
    unsigned char *blob;
    size_t blob_len;
    if
    (
        MagickReadImage(mw, file)        &&
        MagickSetImageFormat(mw, "RGBA") &&
        MagickSetImageChannelDepth
            (mw, RedChannel | GreenChannel | BlueChannel | AlphaChannel, 8) &&
        (blob = MagickGetImageBlob(mw, &blob_len))
    )
    {
        img->width = MagickGetImageWidth(mw);
        img->height = MagickGetImageHeight(mw);
        img->rgba = malloc(blob_len);
        memcpy(img->rgba, blob, blob_len);
        MagickRelinquishMemory(blob);
        result = 1;
    }

    DestroyMagickWand(mw);

    return result;
    
}

int main(int argc, char *argv[])
{
    if (argc != 2)
    {
        puts("Usage: image2rgba FILE");
        return EXIT_SUCCESS;
    }

    libmagickwand_init();

    image img;
    if (load_image(argv[1], &img))
    {
        puts("Image loaded. We can use it, for example, as OpenGL's texture.");
        free(img.rgba);
    }
    else
    {
        puts("Failed to load image.");
    }

    libmagickwand_free();

    return EXIT_SUCCESS;
} 
To compile run gcc image2rgba.c -g3 -O0 -ldl -o image2rgba
And this is gdb backtrace:

Code: Select all

#0  0xb76f84e0 in ?? () from /usr/lib/libgomp.so.1
#1  0xb76f869b in ?? () from /usr/lib/libgomp.so.1
#2  0xb76f6d40 in ?? () from /usr/lib/libgomp.so.1
#3  0xb7fcc7b0 in start_thread (arg=0xb6134b70) at pthread_create.c:300
#4  0xb7f2d1de in clone () at ../sysdeps/unix/sysv/linux/i386/clone.S:130
Segfault disapper if I compile with -fopenmp option.
Is this problem has any other solution?
User avatar
magick
Site Admin
Posts: 11064
Joined: 2003-05-31T11:32:55-07:00

Re: Segmentation fault at dlclose

Post by magick »

OpenMP threads the ImageMagick algorithms and provides a performance boost on multi-core processors. You can remove the OpenMP dependence on libgomp by adding --disable-openmp on the configure script command line when building ImageMagick:
  • cd ImageMagick-6.8.3-7
    ./configure --disable-openm
    make
    make install
Post Reply