Skip to content

Segmentation fault in Image class due to missing deep copy semantics #731

@XINJIANGMO

Description

@XINJIANGMO

Environment

  • OS Version: Ubuntu 24.04
  • Source or binary build?
    source , jetty , gz-common7

Description

  • Expected behavior: work well
  • Actual behavior: crash
    I encountered a Double Free / Segmentation Fault when returning a gz::common::Image object by value.
    The gz::common::Image class manages a raw FIBITMAP* pointer via the FreeImage library. The destructor correctly calls FreeImage_Unload to release memory. However, the class does not implement a Copy Constructor or Assignment Operator.
    As a result, the default compiler-generated copy constructor performs a shallow copy of the raw pointer.

this issue may relate to gz-sim/#3217

Steps to reproduce

  1. Compile the following Minimal Reproduction Example (MRE) with -fno-elide-constructors (to disable RVO) or simply verify with Valgrind and gdb.
#include <gz/common/Image.hh>
#include <iostream>

gz::common::Image CreateImage()
{
    gz::common::Image img;
    // Simulate data loading to trigger FreeImage allocation
    unsigned char dummyData[3] = {255, 0, 0};
    img.SetFromData(dummyData, 1, 1, gz::common::Image::RGB_INT8);
    return img; // <--- Shallow copy occurs here
} // <--- Local 'img' destructor frees the memory

int main()
{
    gz::common::Image myImg = CreateImage();
    
    // Crash occurs here: accessing freed memory
    std::cout << "Height: " << myImg.Height() << std::endl; 
    return 0;
}

or compile using the follwing CMakeLists.txt

cmake_minimum_required(VERSION 3.10)
project(ReproCrash)

find_package(gz-common REQUIRED COMPONENTS graphics)

add_executable(repro_app repro_app.cc)
target_link_libraries(repro_app gz-common::graphics)

target_compile_options(repro_app PRIVATE -fno-elide-constructors)

Output

Valgrind output

==1996623== Invalid free() / delete / delete[] / realloc()
==1996623==    at 0x4851B2C: free (vg_replace_malloc.c:990)
==1996623==    by 0x630DB7D: FreeImage_Unload (libfreeimage-3.18.0.so)
==1996623==    by 0x4C8A260: gz::common::Image::~Image() (Image.cc:114)
==1996623==    by 0x40035CA: main (repro_app)
==1996623==  Address 0x72f8ec0 is 0 bytes inside a block of size 420 free'd
==1996623==    at 0x4851B2C: free (vg_replace_malloc.c:990)
==1996623==    by 0x630DB7D: FreeImage_Unload (libfreeimage-3.18.0.so)
==1996623==    by 0x4C8A260: gz::common::Image::~Image() (Image.cc:114)
==1996623==    by 0x40034AB: CreateImage() (repro_app)

gbd output

Program received signal SIGSEGV, Segmentation fault.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    Status

    Inbox

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions