gookit / goutil

💪 Helper Utils(700+): int, byte, string, array/slice, map, struct, dump, convert/format, error, web/http, cli/flag, OS/ENV, filesystem, system, test/assert, time and more. Go 常用的一些工具函数:数字,字符串,数组,Map,结构体,反射,文本,文件,错误,时间日期,特殊处理,格式化,常用信息获取等等
https://pkg.go.dev/github.com/gookit/goutil
MIT License
2k stars 191 forks source link

runtime error: makeslice: cap out of range #76

Closed Mehrdad-Dadkhah closed 1 year ago

Mehrdad-Dadkhah commented 1 year ago

I use dump.Format(ob) where ob is an interface of struct then I have error: runtime error: makeslice: cap out of range

trace is:

Screenshot from 2022-12-25 15-12-24

inhere commented 1 year ago

hi @Mehrdad-Dadkhah

Thanks, can provide an example for ob?

tommynanny commented 1 year ago

I got this error when the code is run in a goroutine (not sure exactly what the cause is, but it happens from time to time, and only happens to that line, all the other places where I use kw.Logger.Println never gives an error)

kw.Logger.Println("KafkaWorker Starts Listening.")  // << the error happens here
!!!!!!!!!!!!!!!![All 2 KafkaWorkers Start Listening...
]PRINT AT anra/go-sim-driver/log.(*ANRALogger).Printf(anra_logger.go:67)
[]interface {} [ #len=1,cap=1
  string("[]interface {} [ #len=1,cap=1
  string("All 2 KafkaWorkers Start Listening...
"), #len=38
],
"), #len=126
],
!!!!!!!!!!!!!!!![KafkaWorker Starts Listening.]PRINT AT anra/go-sim-driver/kafka.(*KafkaWorker).Listen(kafka_worker.go:54)
string("KafkaWorker Starts Listening."), #len=29
!!!!!!!!!!!!!!!![KafkaWorker Starts Listening.]panic: runtime error: makeslice: cap out of range

goroutine 60 [running]:
github.com/gookit/goutil/strutil.RepeatChars[...](0x20?, 0xfffffffffffffffe)
        /home/nanlin/go/pkg/mod/github.com/gookit/goutil@v0.6.2/strutil/padding.go:167 +0x34
github.com/gookit/goutil/strutil.RepeatBytes(...)
        /home/nanlin/go/pkg/mod/github.com/gookit/goutil@v0.6.2/strutil/padding.go:158
github.com/gookit/goutil/dump.(*Dumper).advance(...)
        /home/nanlin/go/pkg/mod/github.com/gookit/goutil@v0.6.2/dump/dumper.go:172
github.com/gookit/goutil/dump.(*Dumper).printRValue(0xc0000b25a0, {0x10b73c0, 0xed54a0}, {0xed54a0?, 0xc0003eea50?, 0xc0001bf020?})
        /home/nanlin/go/pkg/mod/github.com/gookit/goutil@v0.6.2/dump/dumper.go:263 +0x1ca5
github.com/gookit/goutil/dump.(*Dumper).printOne(0xc0000b25a0, {0xed54a0?, 0xc0003eea50?})
        /home/nanlin/go/pkg/mod/github.com/gookit/goutil@v0.6.2/dump/dumper.go:190 +0x2f9
github.com/gookit/goutil/dump.(*Dumper).dump(0xc0000b25a0, {0xc0000d5ea8, 0x1, 0xc00008dde8?})
        /home/nanlin/go/pkg/mod/github.com/gookit/goutil@v0.6.2/dump/dumper.go:124 +0x114
github.com/gookit/goutil/dump.(*Dumper).Fprint(...)
        /home/nanlin/go/pkg/mod/github.com/gookit/goutil@v0.6.2/dump/dumper.go:97
github.com/gookit/goutil/dump.Format({0xc00008dea8, 0x1, 0x1})
        /home/nanlin/go/pkg/mod/github.com/gookit/goutil@v0.6.2/dump/dump.go:116 +0x93
go-sim-driver/log.(*SpecialLogger).wrap(0xc00053aa20, {0xc000318a50, 0x1, 0x1})
func (l *SpecialLogger) Println(v ...any) {
    r1, r2 := l.wrap(v...) // << the error happens here
    l.dumpToStdout(r2)
    l.Logger.Println(r1)
}

func (l *SpecialLogger) wrap(raw ...any) (logString string, stdString string) {
    if !l.UseWrapper {
        return fmt.Sprint(raw...), fmt.Sprint(raw...)
    }

    dump.Config(dump.WithoutColor(), dump.WithCallerSkip(l.WithCallerSkip))
    w := &bytes.Buffer{}
    dump.Std().Fprint(w, raw...)
    noCOlorWrappedString := w.String()

    if l.ColorfulStdout {
        fmt.Printf("!!!!!!!!!!!!!!!!%v", raw) 
        return noCOlorWrappedString, dump.Format(raw)  // << the error happens here
    }
    return noCOlorWrappedString, noCOlorWrappedString
}
func (kw *KafkaWorker) Listen() {
    kw.Logger.Println("KafkaWorker Starts Listening.")  // << the error happens here
    kw.isWorking = true
    //main blocking loop
workloop:
    for {
        //check if there is stop signal
        select {
        case <-*kw.NeedsToStop:
            break workloop
        default:
        }

        ev := kw.consumer.Poll(100)
        switch e := ev.(type) {
        case *kafka.Message:
            // application-specific processing
            kw.processMessage(e)
        case kafka.Error:
            kw.Logger.HandleError(e)
        default:
            // listening...
        }
    }
    kw.Logger.Println("KafkaWorker Stops Listening.")
} 
func (m *KafkaManager) InitManager() {
    for _, p := range profiles.Manager.All() {
        stopChanel := make(chan bool)
        kw := &KafkaWorker{
            Profile:     p,
            Logger:      log.CreateProductLogger(p.Name),
            NeedsToStop: &(stopChanel),
        }

        if err := kw.Init(); err == nil {
            m.Workers = append(m.Workers, kw)
            //increase the worker for an extra goroutine
            m.WG.Add(1)
            m.Routines = append(m.Routines, func() {
                kw.Listen() // << the error happens here
                //mark as done when one is finished
                m.WG.Done()
            })
        } else {
            kw.Logger.HandleError(err)
            m.Logger.Printf("[Abort] '%s' can't be initilized.\n", p.Name)
        }
    }
    m.Logger.Printf("All %d KafkaWorkers have been initialized.\n", len(m.Workers))
}

func (m *KafkaManager) ListenAll() {
    m.Logger.Printf("All %d KafkaWorkers Start Listening...\n", len(m.Workers))
    for _, r := range m.Routines {
        go r()
    }
    m.WG.Wait()
    m.Logger.Printf("All %d KafkaWorkers Stop Listening.\n", len(m.Workers))
}
tommynanny commented 1 year ago

@inhere after checking my call stack, it seems it is triggered by possible negative value of the times being negative from func RepeatChars[T byte | rune](char T, times int) []T at goutil@v0.6.2/strutil/padding.go

from my particular case, the times becomes -2, probably needs to change

if times == 0 {
     return make([]T, 0)
}

into

if times <= 0 {
     return make([]T, 0)
}

goutil/strutil.RepeatBytes(char 32 = 0x20, times = -2) goutil/strutil.RepeatBytes(char 32 = 0x20, times = -2) goutil/dump.(*Dumper).advance(step = -1)

goutil/dump.(*Dumper).printRValue(d, t, v ,eleNum = 1, lenTip = "<gray>#len=1,cap=1</>", i = 0, sv)
//d
*github.com/gookit/goutil/dump.Dumper {Options: *github.com/gookit/goutil/dump.Options {Output: io.Writer(*bytes.Buffer) ..., NoType: false, NoColor: false, IndentLen: 2, IndentChar: 32, MaxDepth: 5, ShowFlag: 1, CallerSkip: 3, ColorTheme: github.com/gookit/goutil/dump.Theme [...], SkipNilField: false, SkipPrivate: false, BytesAsString: false}, mu: sync.RWMutex {w: (*sync.Mutex)(0x1400009a5a8), writerSem: 0, readerSem: 0, readerCount: -1073741824, readerWait: 0}, visited: map[github.com/gookit/goutil/dump.visit]int [], msValue: false, curDepth: 0, indentBytes: []uint8 len: 0, cap: 0, []}

//t
reflect.Type(*reflect.rtype) *{size: 24, ptrdata: 8, hash: 228187766, tflag: tflagExtraStar (2), align: 8, fieldAlign: 8, kind: 23, equal: nil, gcdata: *1, str: 62293, ptrToThis: 195648}

//v
reflect.Value {typ: *reflect.rtype {size: 24, ptrdata: 8, hash: 228187766, tflag: tflagExtraStar (2), align: 8, fieldAlign: 8, kind: 23, equal: nil, gcdata: *1, str: 62293, ptrToThis: 195648}, ptr: unsafe.Pointer(0x140003c2150), flag: 151}

//sv
reflect.Value {typ: *reflect.rtype {size: 16, ptrdata: 16, hash: 252279353, tflag: tflagExtraStar (2), align: 8, fieldAlign: 8, kind: 20, equal: runtime.nilinterequal, gcdata: *2, str: 49081, ptrToThis: 244160}, ptr: unsafe.Pointer(0x140001ca8b0), flag: 404}
inhere commented 1 year ago

@tommynanny Thank you very much! I will fix it in the next version.

inhere commented 1 year ago

Hi @tommynanny @Mehrdad-Dadkhah Released v0.6.4