goccy / go-graphviz

Go bindings for Graphviz
MIT License
692 stars 69 forks source link

twopi and setRoot -> crash #29

Open offerm opened 4 years ago

offerm commented 4 years ago

I'm trying to graph using twopi and sent one of the nodes to be the graph root. This lead to a crash.

fatal error: unexpected signal during runtime execution
[signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0x52d5a4]

runtime stack:
runtime.throw(0x67e1e8, 0x2a)
        /usr/local/go/src/runtime/panic.go:1116 +0x72
runtime.sigpanic()
        /usr/local/go/src/runtime/signal_unix.go:679 +0x46a

goroutine 1 [syscall]:
runtime.cgocall(0x526ce0, 0xc000045dc8, 0x3)
        /usr/local/go/src/runtime/cgocall.go:133 +0x5b fp=0xc000045d98 sp=0xc000045d60 pc=0x41c90b
github.com/goccy/go-graphviz/internal/ccall._Cfunc_gvLayout(0x9fff70, 0xa01810, 0xa026d0, 0x0)
        _cgo_gotypes.go:2372 +0x4d fp=0xc000045dc8 sp=0xc000045d98 pc=0x4c2b3d
github.com/goccy/go-graphviz/internal/ccall.GvLayout.func1(0xc0000100a8, 0xc0000100b8, 0x676be7, 0x3, 0xc00006e1e0)
        /home/offerm/go/pkg/mod/github.com/goccy/go-graphviz@v0.0.6/internal/ccall/gvc.go:736 +0xd5 fp=0xc000045e10 sp=0xc000045dc8 pc=0x4c69a5
github.com/goccy/go-graphviz/internal/ccall.GvLayout(0xc0000100a8, 0xc0000100b8, 0x676be7, 0x3, 0x4c8827, 0xa01810)
        /home/offerm/go/pkg/mod/github.com/goccy/go-graphviz@v0.0.6/internal/ccall/gvc.go:736 +0x49 fp=0xc000045e48 sp=0xc000045e10 pc=0x4c5ec9
github.com/goccy/go-graphviz/gvc.(*Context).Layout(...)
        /home/offerm/go/pkg/mod/github.com/goccy/go-graphviz@v0.0.6/gvc/gvc.go:29
github.com/goccy/go-graphviz.(*Graphviz).Render(0xc00006e1b0, 0xc0000100c0, 0x676be7, 0x3, 0x6a0ee0, 0xc00006e1e0, 0x0, 0x0)
        /home/offerm/go/pkg/mod/github.com/goccy/go-graphviz@v0.0.6/graphviz.go:83 +0x74 fp=0xc000045ec0 sp=0xc000045e48 pc=0x522584
main.main()
        /home/offerm/github/ln-name-server/graph/test.go:45 +0x3d0 fp=0xc000045f88 sp=0xc000045ec0 pc=0x524300
runtime.main()
        /usr/local/go/src/runtime/proc.go:203 +0x1fa fp=0xc000045fe0 sp=0xc000045f88 pc=0x44befa
runtime.goexit()
        /usr/local/go/src/runtime/asm_amd64.s:1373 +0x1 fp=0xc000045fe8 sp=0xc000045fe0 pc=0x476731

not using twopi or setRoot prevent this error.

source code:

package main

import (
    "bytes"
    "fmt"
    "github.com/goccy/go-graphviz"
    "log"
)

func main() {

    g := graphviz.New()
    graph, err := g.Graph(graphviz.UnDirected)
    if err != nil {
        log.Fatal(err)
    }
    defer func() {
        if err := graph.Close(); err != nil {
            log.Fatal(err)
        }
        g.Close()
    }()
    n, err := graph.CreateNode("n")
    if err != nil {
        log.Fatal(err)
    }
    m, err := graph.CreateNode("m")
    if err != nil {
        log.Fatal(err)
    }
    _, err = graph.CreateNode("l")
    if err != nil {
        log.Fatal(err)
    }

    e, err := graph.CreateEdge("e", n, m)
    if err != nil {
        log.Fatal(err)
    }
    e.SetLabel("e")
    n.SetRoot(true)
    graph.SetLayout("twopi")

    var buf bytes.Buffer
    if err := g.Render(graph, "dot", &buf); err != nil {
        log.Fatal(err)
    }
    fmt.Println(buf.String())

    if err := g.Render(graph, graphviz.PNG, &buf); err != nil {
        log.Fatal(err)
    }

    if err := g.RenderFilename(graph, graphviz.PNG, "/tmp/graph.png"); err != nil {
        log.Fatal(err)
    }

}
oferbu commented 3 years ago

@offerm did you find a solution or workaround this issue?

goccy commented 1 week ago

@offerm Can the Graphviz's dot command output correctly ?

goccy commented 1 week ago
package main

import (
    "bytes"
    "context"
    "log"
    "os"

    "github.com/goccy/go-graphviz"
)

func main() {
    ctx := context.Background()
    g, _ := graphviz.New(ctx)
    graph, err := g.Graph(graphviz.WithDirectedType(graphviz.UnDirected))
    if err != nil {
        log.Fatal(err)
    }
    defer func() {
        if err := graph.Close(); err != nil {
            log.Fatal(err)
        }
        g.Close()
    }()
    n, err := graph.CreateNodeByName("n")
    if err != nil {
        log.Fatal(err)
    }
    m, err := graph.CreateNodeByName("m")
    if err != nil {
        log.Fatal(err)
    }
    _, err = graph.CreateNodeByName("l")
    if err != nil {
        log.Fatal(err)
    }

    e, err := graph.CreateEdgeByName("e", n, m)
    if err != nil {
        log.Fatal(err)
    }
    e.SetLabel("e")
    n.SetRoot(true)
    graph.SetLayout("twopi")
    var buf bytes.Buffer
    if err := g.Render(ctx, graph, graphviz.PNG, &buf); err != nil {
        log.Fatal(err)
    }
    os.WriteFile("twopi.png", buf.Bytes(), 644)
}

When I ran the above code with output to stderr enabled, I received the following error. I believe similar code would likely not work with the original dot command either.

Assertion failed: sym->id >= 0 && sym->id < topdictsize(obj) (/graphviz/lib/cgraph/attr.c: agxset: 491)