Segment fault when calling shared library from node plotting png using CairoMakie library

have simple .jl (below are source files) program flow is: test.js calls c program which calls julia program

  1. when using svg extension

const result = generate_c(‘td’, 250, 250, ‘test_draw.svg’);

image is generated

  1. when using png extension get exception related to png library

const result = generate_c(‘td’, 250, 250, 'test_draw.png);

Segmentation fault

in expression starting at none:0

deflateReset at node (unknown line)

png_deflate_claim at /home/server/go/src/blockbook/ml/ca/server/recursiveDynamic/dist/share/julia/artifacts/79994d5aa1ffc0e9e42f2348a7f9c584dbe20204/lib/libpng16.so (unknown line)

this error is related to calling build so library from node

followed project structure PackageCompiler.jl for libs (al works just fine if one is calling it from a c program but not as shared (so) library

see also make file (below)

test_draw.jl

using CairoMakie
CairoMakie.activate!()

export generate_test_draw

function generate_test_draw(width::Integer, height::Integer, output_path::String)
fig = Figure(size = (width, height))
ax = Axis(fig[1, 1]; title = “Simple Square”)

# Define square corners manually
points = [Point2f(0.25, 0.25), Point2f(0.75, 0.25),
          Point2f(0.75, 0.75), Point2f(0.25, 0.75)]

poly!(ax, points, color = :blue)

save(output_path, fig)

end

rdlib.js

export generate

using Base: Cint, Cstring, unsafe_string

include(“cantor_set.jl”)
include(“hilbert_curve.jl”)
include(“test_draw.jl”)

C-callable function via @ccallable

Base.@ccallable function generate(ctype::Cstring, width::Cint, height::Cint, o::Cstring)::Cint
ctype_str = unsafe_string(ctype)
output_str = unsafe_string(o)

if ctype_str == "td"
    generate_test_draw(width, height, output_str)
else
    @warn "Unknown ctype: $ctype_str"
    return 1  # Non-zero to indicate error
end

return 0

end

c program

generate.c

#include <stdio.h>
#include “julia_init.h”
#include “rdlib.h”

int generate_c(const char *ctype, int width, int height, const char *output_path)
{
init_julia(0, NULL); // Initialize Julia runtime; adjust if you need argc/argv

int status = 0;
status = generate(ctype, width, height, output_path);
if (status != 0) {
    fprintf(stderr, "generate_%s failed with status %d\n", ctype, status);
}

shutdown_julia(0);  // Shutdown Julia runtime

return status;

}


test.js

const koffi = require(‘koffi’);

// Load the shared library
const lib = koffi.load(‘./dist/lib/librdlib_c.so’);

// Define the C-callable function signature
const generate_c = lib.func(‘int generate_c(const char*, int, int, const char*)’);

// Call the function
const result = generate_c(‘td’, 250, 250, ‘test_draw.svg’);

console.log(‘generate() returned:’, result);

– Make file

.DEFAULT_GOAL := all

JULIA ?= julia
DLEXT := (shell (JULIA) --startup-file=no -e ‘using Libdl; print(Libdl.dlext)’)

TARGET=“dist”

RDLIB_INCLUDES = (TARGET)/include/julia_init.h (TARGET)/include/rdlib.h
RDLIB_PATH := (TARGET)/lib/librdlib.(DLEXT)

build-library: build/build.jl src/rdlib.jl
(JULIA) --startup-file=no --project=. -e 'using Pkg; Pkg.instantiate()' (JULIA) --startup-file=no --project=build -e ‘using Pkg; Pkg.instantiate(); include(“build/build.jl”)’

INCLUDE_DIR = $(TARGET)/include

build-c-library:
gcc -shared -fPIC generate.c -o (TARGET)/lib/librdlib_c.so \ -I(INCLUDE_DIR) -L$(TARGET)/lib -ljulia -lrdlib

build-executable:
gcc generate.c -o generate -I$(INCLUDE_DIR) -L$(TARGET)/lib -ljulia -lrdlib

all: build-library build-c-library build-executable

clean:
(RM) *~ *.o *.(DLEXT)
(RM) -Rf (TARGET)

.PHONY: build-library build-executable clean all

Don’t think I can help but a slight advice, you may envolope your code snippets in ``` notations to improve readibility and possibility that people come in to help :slight_smile: