# Works in debugger, segfaults when compiled

**URL:** <https://discourse.julialang.org/t/works-in-debugger-segfaults-when-compiled/111385>\
**Category:** General Usage\
**Created:** [March 9, 2024, 3:25am UTC](https://discourse.julialang.org/t/works-in-debugger-segfaults-when-compiled/111385 "2024-03-09T03:25:20Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![mpeters2](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mpeters2/32/202247_2.png) [@mpeters2](https://discourse.julialang.org/u/mpeters2)\
**Post date:** [March 9, 2024, 3:25am UTC](https://discourse.julialang.org/t/works-in-debugger-segfaults-when-compiled/111385/1 "2024-03-09T03:25:20Z")

</div>

I’m trying to translate some C/C++ code to take a screenshot of an SDL window. My code works in the debugger, but not in normal compiled mode. It’s based on the following C/C++ code:

```julia
void SosariaInputController::SaveScreenshot()
{
    const Uint32 format = SDL_PIXELFORMAT_ARGB8888;
    const int width = 640;
    const int height = 400;
    auto renderer = sdl2Core->GetRenderer();
 
    SDL_Surface *surface = SDL_CreateRGBSurfaceWithFormat(0, width, height, 32, format);
    SDL_RenderReadPixels(renderer, NULL, format, surface->pixels, surface->pitch);
    SDL_SaveBMP(surface, "screenshot.bmp");
    SDL_FreeSurface(surface);
}

```

My Julia code does a bit more, as it takes a screen shot and renders the image to the window :

```julia
function flip2(win::Window, screenshot::Bool)
 
    if screenshot == true
        w = Ref{Cint}()
        h = Ref{Cint}()
        SDL_GL_GetDrawableSize(win.win, w, h)
        
        mySurfacePtr = SDL_CreateRGBSurfaceWithFormat(0, w[], h[], 32, SDL_PIXELFORMAT_ARGB8888); # create empy mySurfacePtr

        dereference(T::DataType, ptr::Ptr) = unsafe_load(Ptr{T}(ptr)) # generic function
        surfaceStruct = dereference(SDL_Surface, mySurfacePtr) # try to put the C-based SDL_Surface struct into a Julia struct

        result = SDL_RenderReadPixels(win.renderer, C_NULL, SDL_PIXELFORMAT_ARGB8888, surfaceStruct.pixels, surfaceStruct.pitch);

        if result != 0
            error("SDL_RenderReadPixels failed: ", unsafe_string(SDL_GetError()) )
        end
            
        surfaceStructPtr = Ptr{SDL_Surface}(pointer_from_objref(Ref(surfaceStruct)))

        if surfaceStructPtr == C_NULL
            println("surfaceStructPtr is C_NULL" )
        else
            println(logFile, "surfaceStructPtr is NOT C_NULL" )
        end

        result = IMG_SavePNG(surfaceStructPtr, "screenshot.png")
        if result != 0
            error("IMG_SavePNG failed: ", unsafe_string(SDL_GetError()) )
        end 
    end
    SDL_RenderPresent(win.renderer) # Present the backbuffer (memory) to the screen
    SDL_PumpEvents()
    SDL_SetRenderDrawColor(win.renderer, win.color[1], win.color[2], win.color[3], 255) # sets window background color
    SDL_RenderClear(win.renderer) # Clears the window in memory, getting it read for the next drawing session.
end

```

When I run it outside the debugger, I get a segmentation fault, with this as the error log. The segfault seems to occur when I call `IMG_SavePNG()`. Any ideas why this is happening, and why it would work just fine when running it in the debugger, but crash-and-burn when running the compiled version?

```julia
[56036] signal (11.2): Segmentation fault: 11
in expression starting at /Users/SomeGuysAccount/.julia/dev/PsychoJL/Examples/complex occlusions/ComplexOcclusionSearchMain.jl:613
IMG_SavePNG_RW at /Users/SomeGuysAccount/.julia/artifacts/5ebb4b9114677f6288d27366c03555cca9d7ab98/lib/libSDL2_image-2.0.601.2.0.dylib (unknown line)
IMG_SavePNG at /Users/SomeGuysAccount/.julia/packages/SimpleDirectMediaLayer/wjMsP/src/LibSDL2.jl:5846 [inlined]
flip2 at /Users/SomeGuysAccount/.julia/dev/PsychoJL/src/window.jl:420
doATrial at /Users/SomeGuysAccount/.julia/dev/PsychoJL/Examples/complex occlusions/ComplexOcclusionSearchMain.jl:352
main at /Users/SomeGuysAccount/.julia/dev/PsychoJL/Examples/complex occlusions/ComplexOcclusionSearchMain.jl:83
unknown function (ip: 0x2a8788467)
_jl_invoke at /Users/julia/.julia/scratchspaces/a66863c6-20e8-4ff4-8a62-49f30b1f605e/agent-cache/default-honeycrisp-HL2F7YQ3XH.0/build/default-honeycrisp-HL2F7YQ3XH-0/julialang/julia-release-1-dot-10/src/gf.c:0 [inlined]
ijl_apply_generic at /Users/julia/.julia/scratchspaces/a66863c6-20e8-4ff4-8a62-49f30b1f605e/agent-cache/default-honeycrisp-HL2F7YQ3XH.0/build/default-honeycrisp-HL2F7YQ3XH-0/julialang/julia-release-1-dot-10/src/gf.c:3076
jl_apply at /Users/julia/.julia/scratchspaces/a66863c6-20e8-4ff4-8a62-49f30b1f605e/agent-cache/default-honeycrisp-HL2F7YQ3XH.0/build/default-honeycrisp-HL2F7YQ3XH-0/julialang/julia-release-1-dot-10/src/./julia.h:1982 [inlined]
do_call at /Users/julia/.julia/scratchspaces/a66863c6-20e8-4ff4-8a62-49f30b1f605e/agent-cache/default-honeycrisp-HL2F7YQ3XH.0/build/default-honeycrisp-HL2F7YQ3XH-0/julialang/julia-release-1-dot-10/src/interpreter.c:126
eval_body at /Users/julia/.julia/scratchspaces/a66863c6-20e8-4ff4-8a62-49f30b1f605e/agent-cache/default-honeycrisp-HL2F7YQ3XH.0/build/default-honeycrisp-HL2F7YQ3XH-0/julialang/julia-release-1-dot-10/src/interpreter.c:0
jl_interpret_toplevel_thunk at /Users/julia/.julia/scratchspaces/a66863c6-20e8-4ff4-8a62-49f30b1f605e/agent-cache/default-honeycrisp-HL2F7YQ3XH.0/build/default-honeycrisp-HL2F7YQ3XH-0/julialang/julia-release-1-dot-10/src/interpreter.c:775
jl_toplevel_eval_flex at /Users/julia/.julia/scratchspaces/a66863c6-20e8-4ff4-8a62-49f30b1f605e/agent-cache/default-honeycrisp-HL2F7YQ3XH.0/build/default-honeycrisp-HL2F7YQ3XH-0/julialang/julia-release-1-dot-10/src/toplevel.c:934
jl_toplevel_eval_flex at /Users/julia/.julia/scratchspaces/a66863c6-20e8-4ff4-8a62-49f30b1f605e/agent-cache/default-honeycrisp-HL2F7YQ3XH.0/build/default-honeycrisp-HL2F7YQ3XH-0/julialang/julia-release-1-dot-10/src/toplevel.c:877
ijl_toplevel_eval at /Users/julia/.julia/scratchspaces/a66863c6-20e8-4ff4-8a62-49f30b1f605e/agent-cache/default-honeycrisp-HL2F7YQ3XH.0/build/default-honeycrisp-HL2F7YQ3XH-0/julialang/julia-release-1-dot-10/src/toplevel.c:943 [inlined]
ijl_toplevel_eval_in at /Users/julia/.julia/scratchspaces/a66863c6-20e8-4ff4-8a62-49f30b1f605e/agent-cache/default-honeycrisp-HL2F7YQ3XH.0/build/default-honeycrisp-HL2F7YQ3XH-0/julialang/julia-release-1-dot-10/src/toplevel.c:985
eval at ./boot.jl:385 [inlined]
include_string at ./loading.jl:2070
_jl_invoke at /Users/julia/.julia/scratchspaces/a66863c6-20e8-4ff4-8a62-49f30b1f605e/agent-cache/default-honeycrisp-HL2F7YQ3XH.0/build/default-honeycrisp-HL2F7YQ3XH-0/julialang/julia-release-1-dot-10/src/gf.c:0 [inlined]
ijl_apply_generic at /Users/julia/.julia/scratchspaces/a66863c6-20e8-4ff4-8a62-49f30b1f605e/agent-cache/default-honeycrisp-HL2F7YQ3XH.0/build/default-honeycrisp-HL2F7YQ3XH-0/julialang/julia-release-1-dot-10/src/gf.c:3076
_include at ./loading.jl:2130
include at ./Base.jl:495
jfptr_include_46486 at /Users/SomeGuysAccount/.julia/juliaup/julia-1.10.0+0.aarch64.apple.darwin14/lib/julia/sys.dylib (unknown line)
_jl_invoke at /Users/julia/.julia/scratchspaces/a66863c6-20e8-4ff4-8a62-49f30b1f605e/agent-cache/default-honeycrisp-HL2F7YQ3XH.0/build/default-honeycrisp-HL2F7YQ3XH-0/julialang/julia-release-1-dot-10/src/gf.c:0 [inlined]
ijl_apply_generic at /Users/julia/.julia/scratchspaces/a66863c6-20e8-4ff4-8a62-49f30b1f605e/agent-cache/default-honeycrisp-HL2F7YQ3XH.0/build/default-honeycrisp-HL2F7YQ3XH-0/julialang/julia-release-1-dot-10/src/gf.c:3076
exec_options at ./client.jl:318
_start at ./client.jl:552
jfptr__start_82831 at /Users/SomeGuysAccount/.julia/juliaup/julia-1.10.0+0.aarch64.apple.darwin14/lib/julia/sys.dylib (unknown line)
_jl_invoke at /Users/julia/.julia/scratchspaces/a66863c6-20e8-4ff4-8a62-49f30b1f605e/agent-cache/default-honeycrisp-HL2F7YQ3XH.0/build/default-honeycrisp-HL2F7YQ3XH-0/julialang/julia-release-1-dot-10/src/gf.c:0 [inlined]
ijl_apply_generic at /Users/julia/.julia/scratchspaces/a66863c6-20e8-4ff4-8a62-49f30b1f605e/agent-cache/default-honeycrisp-HL2F7YQ3XH.0/build/default-honeycrisp-HL2F7YQ3XH-0/julialang/julia-release-1-dot-10/src/gf.c:3076
jl_apply at /Users/julia/.julia/scratchspaces/a66863c6-20e8-4ff4-8a62-49f30b1f605e/agent-cache/default-honeycrisp-HL2F7YQ3XH.0/build/default-honeycrisp-HL2F7YQ3XH-0/julialang/julia-release-1-dot-10/src/./julia.h:1982 [inlined]
true_main at /Users/julia/.julia/scratchspaces/a66863c6-20e8-4ff4-8a62-49f30b1f605e/agent-cache/default-honeycrisp-HL2F7YQ3XH.0/build/default-honeycrisp-HL2F7YQ3XH-0/julialang/julia-release-1-dot-10/src/jlapi.c:582
jl_repl_entrypoint at /Users/julia/.julia/scratchspaces/a66863c6-20e8-4ff4-8a62-49f30b1f605e/agent-cache/default-honeycrisp-HL2F7YQ3XH.0/build/default-honeycrisp-HL2F7YQ3XH-0/julialang/julia-release-1-dot-10/src/jlapi.c:731
Allocations: 7895382 (Pool: 7886666; Big: 8716); GC: 11

```

---

<div class="post-metadata">

**Author:** ![vchuravy](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/vchuravy/32/8_2.png) [@vchuravy](https://discourse.julialang.org/u/vchuravy)\
**Post date:** [March 9, 2024, 3:39am UTC](https://discourse.julialang.org/t/works-in-debugger-segfaults-when-compiled/111385/2 "2024-03-09T03:39:01Z")

</div>

> [@mpeters2](#):
>
> ```julia
> surfaceStructPtr = Ptr{SDL_Surface}(pointer_from_objref(Ref(surfaceStruct)))
> 
> ```

This is illegal. You create an object `Ref(surfaceStruct)`, then observe the pointer, and use the the pointer after the object is no longer reachable.

It depends on the definition of `IMG_SavePNG`, but it may suffice passing the `Ref` directly,

Otherwise a safe pattern is:

```julia
r_surfacestruct = Ref(surfaceStruct)
GC.@preserve r_surfacestruct begin
    ptr_surfacestruct = Base.unsafe_convert(Ptr{SDL_Surface}, r_surfacestruct)
    result = IMG_SavePNG(ptr_surfacestruct, "screenshot.png")
end

```

`@preserve` extends the lifetime of the object across the `begin`/`end`.

---

<div class="post-metadata">

**Author:** ![mpeters2](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mpeters2/32/202247_2.png) [@mpeters2](https://discourse.julialang.org/u/mpeters2)\
**Post date:** [March 11, 2024, 1:56am UTC](https://discourse.julialang.org/t/works-in-debugger-segfaults-when-compiled/111385/3 "2024-03-11T01:56:38Z")

</div>

Thanks, that worked!

Pointers and handles were my least favorite part of C/C++. I wish there was the equivalent of `->` for dereferencing a field of a pointer to a C struct in Julia.

---

<div class="post-metadata">

**Author:** ![mkitti](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mkitti/32/12459_2.png) [@mkitti](https://discourse.julialang.org/u/mkitti)\
**Post date:** [March 11, 2024, 2:28am UTC](https://discourse.julialang.org/t/works-in-debugger-segfaults-when-compiled/111385/4 "2024-03-11T02:28:54Z")

</div>

We really do not want users to be messing with raw pointers in Julia due to the potential for exactly the kind of error you stumbled upon. `Ref` or specifically `Base.RefValue` is the closest you will get. The syntax is then `[].`.

```julia
julia> struct Foo
           x::Int64
       end

julia> r = Ref{Foo}()
Base.RefValue{Foo}(Foo(480270463568))

julia> r[].x
480270463568

```
