go-sonic / sonic

Sonic is a blogging platform developed by Go. Simple and powerful
MIT License
2.01k stars 256 forks source link

安装时服务器内部错误:`strconv.Atoi: out of range` #343

Closed simonkuang closed 9 months ago

simonkuang commented 11 months ago

检查清单

是什么版本出现了此问题?

1.6.0

使用的什么数据库?

SQLite3

使用的哪种方式部署?

Executable file

在线站点地址

No response

发生了什么?

安装过程中出现 500 Server Internal Error

2023-11-15T16:46:43.506Z DEBUG listener/template_config.go:136 load theme success {"theme": "Anatole"} 2023-11-15T16:46:43.532Z ERROR handler/server.go:229 handler error {"error": "option 类型错误 optionValue=1700066803520 kind=int: strconv.Atoi: parsing \"1700066803520\": value out of range", "errorVerbose": "strconv.Atoi: parsing \"1700066803520\": value out of range\noption 类型错误 optionValue=1700066803520 kind=int\ngithub.com/go-sonic/sonic/util/xerr.ErrorType.Wrapf\n\tgithub.com/go-sonic/sonic/util/xerr/error.go:46\ngithub.com/go-sonic/sonic/service/impl.(optionServiceImpl).convert\n\tgithub.com/go-sonic/sonic/service/impl/option.go:196\ngithub.com/go-sonic/sonic/service/impl.(optionServiceImpl).Save\n\tgithub.com/go-sonic/sonic/service/impl/option.go:224\ngithub.com/go-sonic/sonic/service/impl.installServiceImpl.createDefaultSetting\n\tgithub.com/go-sonic/sonic/service/impl/install.go:126\ngithub.com/go-sonic/sonic/service/impl.installServiceImpl.InstallBlog.func1\n\tgithub.com/go-sonic/sonic/service/impl/install.go:68\ngithub.com/go-sonic/sonic/dal.Transaction.func1\n\tgithub.com/go-sonic/sonic/dal/dal.go:129\ngithub.com/go-sonic/sonic/dal.Transaction.(Query).Transaction.func2\n\tgithub.com/go-sonic/sonic/dal/gen.go:210\ngorm.io/gorm.(DB).Transaction\n\tgorm.io/gorm@v1.25.5/finisher_api.go:647\ngithub.com/go-sonic/sonic/dal.(Query).Transaction\n\tgithub.com/go-sonic/sonic/dal/gen.go:210\ngithub.com/go-sonic/sonic/dal.Transaction\n\tgithub.com/go-sonic/sonic/dal/dal.go:127\ngithub.com/go-sonic/sonic/service/impl.installServiceImpl.InstallBlog\n\tgithub.com/go-sonic/sonic/service/impl/install.go:64\ngithub.com/go-sonic/sonic/handler/admin.(InstallHandler).InstallBlog\n\tgithub.com/go-sonic/sonic/handler/admin/install.go:35\ngithub.com/go-sonic/sonic/handler.(Server).RegisterRouters.(Server).wrapHandler.func8\n\tgithub.com/go-sonic/sonic/handler/server.go:227\ngithub.com/gin-gonic/gin.(Context).Next\n\tgithub.com/gin-gonic/gin@v1.9.1/context.go:174\ngithub.com/go-sonic/sonic/handler/middleware.(RecoveryMiddleware).RecoveryWithLogger.func1\n\tgithub.com/go-sonic/sonic/handler/middleware/recovery.go:62\ngithub.com/gin-gonic/gin.(Context).Next\n\tgithub.com/gin-gonic/gin@v1.9.1/context.go:174\ngithub.com/go-sonic/sonic/handler/middleware.(GinLoggerMiddleware).LoggerWithConfig.func1\n\tgithub.com/go-sonic/sonic/handler/middleware/log.go:50\ngithub.com/gin-gonic/gin.(Context).Next\n\tgithub.com/gin-gonic/gin@v1.9.1/context.go:174\ngithub.com/gin-gonic/gin.(Engine).handleHTTPRequest\n\tgithub.com/gin-gonic/gin@v1.9.1/gin.go:620\ngithub.com/gin-gonic/gin.(Engine).ServeHTTP\n\tgithub.com/gin-gonic/gin@v1.9.1/gin.go:576\nnet/http.serverHandler.ServeHTTP\n\tnet/http/server.go:2938\nnet/http.(conn).serve\n\tnet/http/server.go:2009\nruntime.goexit\n\truntime/asm_arm.s:859\n"}

硬件:Raspberrypi 4B+ & Raspberrypi 3B 系统:Raspbian OS(bullseye)arm & arm64 复现:以命令 ./sonic -config conf/config.yaml 直接运行;浏览器访问;安装界面提交信息时报错。错误信息从 log 文件中摘抄。

相关日志输出

"method": "POST", "path": "/api/admin/installations"}
2023-11-15T15:51:55.594Z        INFO    [GIN]   {"beginTime": "2023-11-15T15:51:55.593Z", "status": 200, "latency": 0.000143757, "clientIP": "192.168.6.106", "method": "GET", "path": "/api/admin/is_installed"}
2023-11-15T15:52:18.454Z        INFO    impl/option.go:204      [11.579ms] [rows:108] SELECT * FROM `option`
2023-11-15T15:52:18.456Z        INFO    impl/option.go:256      [1.071ms] [rows:1] UPDATE `option` SET `option_value`="c05769f58c054745aa2a7b92db1a97ff9de16dadcfec48e5978a313e59d3eff7780ba504d0cc4d37b2dc84b37a3cf1682dc4dc8312ab43eb9cc6f063422834336071baef8c1c47d2a1de5be558c2294dbc84fdc1b3424d8aaa202fc25fb594f699391fb66f234d73bdfeb6bbbcdf00af1f20c095aba8485dbfdc2e823517ce66" WHERE `option`.`id` = 108 AND `option`.`option_key` = "jwt_secret"
2023-11-15T15:52:18.466Z        INFO    impl/theme.go:260       [0.430ms] [rows:0] SELECT * FROM `theme_setting` WHERE `theme_setting`.`theme_id` = "caicai_anatole"
2023-11-15T15:52:18.466Z        DEBUG   listener/template_config.go:136 load theme success      {"theme": "Anatole"}
2023-11-15T15:52:18.477Z        INFO    impl/option.go:288      [10.258ms] [rows:108] SELECT * FROM `option`
2023-11-15T15:52:18.489Z        INFO    impl/option.go:204      [9.751ms] [rows:108] SELECT * FROM `option`
2023-11-15T15:52:18.490Z        ERROR   handler/server.go:229   handler error   {"error": "option 类型错误 optionValue=1700063538478 kind=int: strconv.Atoi: parsing \"1700063538478\": value out of range", "errorVerbose": "strconv.Atoi: parsing \"1700063538478\": value out of range\noption 类型错误 optionValue=1700063538478 kind=int\ngithub.com/go-sonic/sonic/util/xerr.ErrorType.Wrapf\n\tgithub.com/go-sonic/sonic/util/xerr/error.go:46\ngithub.com/go-sonic/sonic/service/impl.(*optionServiceImpl).convert\n\tgithub.com/go-sonic/sonic/service/impl/option.go:196\ngithub.com/go-sonic/sonic/service/impl.(*optionServiceImpl).Save\n\tgithub.com/go-sonic/sonic/service/impl/option.go:224\ngithub.com/go-sonic/sonic/service/impl.installServiceImpl.createDefaultSetting\n\tgithub.com/go-sonic/sonic/service/impl/install.go:126\ngithub.com/go-sonic/sonic/service/impl.installServiceImpl.InstallBlog.func1\n\tgithub.com/go-sonic/sonic/service/impl/install.go:68\ngithub.com/go-sonic/sonic/dal.Transaction.func1\n\tgithub.com/go-sonic/sonic/dal/dal.go:129\ngithub.com/go-sonic/sonic/dal.Transaction.(*Query).Transaction.func2\n\tgithub.com/go-sonic/sonic/dal/gen.go:210\ngorm.io/gorm.(*DB).Transaction\n\tgorm.io/gorm@v1.25.5/finisher_api.go:647\ngithub.com/go-sonic/sonic/dal.(*Query).Transaction\n\tgithub.com/go-sonic/sonic/dal/gen.go:210\ngithub.com/go-sonic/sonic/dal.Transaction\n\tgithub.com/go-sonic/sonic/dal/dal.go:127\ngithub.com/go-sonic/sonic/service/impl.installServiceImpl.InstallBlog\n\tgithub.com/go-sonic/sonic/service/impl/install.go:64\ngithub.com/go-sonic/sonic/handler/admin.(*InstallHandler).InstallBlog\n\tgithub.com/go-sonic/sonic/handler/admin/install.go:35\ngithub.com/go-sonic/sonic/handler.(*Server).RegisterRouters.(*Server).wrapHandler.func8\n\tgithub.com/go-sonic/sonic/handler/server.go:227\ngithub.com/gin-gonic/gin.(*Context).Next\n\tgithub.com/gin-gonic/gin@v1.9.1/context.go:174\ngithub.com/go-sonic/sonic/handler/middleware.(*RecoveryMiddleware).RecoveryWithLogger.func1\n\tgithub.com/go-sonic/sonic/handler/middleware/recovery.go:62\ngithub.com/gin-gonic/gin.(*Context).Next\n\tgithub.com/gin-gonic/gin@v1.9.1/context.go:174\ngithub.com/go-sonic/sonic/handler/middleware.(*GinLoggerMiddleware).LoggerWithConfig.func1\n\tgithub.com/go-sonic/sonic/handler/middleware/log.go:50\ngithub.com/gin-gonic/gin.(*Context).Next\n\tgithub.com/gin-gonic/gin@v1.9.1/context.go:174\ngithub.com/gin-gonic/gin.(*Engine).handleHTTPRequest\n\tgithub.com/gin-gonic/gin@v1.9.1/gin.go:620\ngithub.com/gin-gonic/gin.(*Engine).ServeHTTP\n\tgithub.com/gin-gonic/gin@v1.9.1/gin.go:576\nnet/http.serverHandler.ServeHTTP\n\tnet/http/server.go:2938\nnet/http.(*conn).serve\n\tnet/http/server.go:2009\nruntime.goexit\n\truntime/asm_arm.s:859\n"}
2023-11-15T15:52:18.491Z        INFO    [GIN]   {"beginTime": "2023-11-15T15:52:18.440Z", "status": 500, "latency": 0.050819438, "clientIP": "192.168.6.106", "method": "POST", "path": "/api/admin/installations"}
2023-11-15T15:52:18.519Z        INFO    [GIN]   {"beginTime": "2023-11-15T15:52:18.519Z", "status": 200, "latency": 0.000101276, "clientIP": "192.168.6.106", "method": "GET", "path": "/api/admin/is_installed"}

附加信息

No response

textworld commented 11 months ago

猜测应该是int类型在树莓派系统下实际上是int32,最大范围-2147483648 ~ 2147483647,而time.Now().UnixMilli()超过了这一范围

修复方式:BirthDay类型改成int64

optionMap[property.BirthDay.KeyValue] = strconv.FormatInt(time.Now().UnixMilli(), 10)
err := i.OptionService.Save(ctx, optionMap)
    BirthDay = Property{
        KeyValue:     "birthday",
        DefaultValue: int(0),
        Kind:         reflect.Int,
    }
jakezhu9 commented 11 months ago

@textworld 你的分析很有道理👍,能否再提交一个 PR 修复这个问题呢

simonkuang commented 11 months ago

猜测应该是int类型在树莓派系统下实际上是int32,最大范围-2147483648 ~ 2147483647,而time.Now().UnixMilli()超过了这一范围

修复方式:BirthDay类型改成int64

optionMap[property.BirthDay.KeyValue] = strconv.FormatInt(time.Now().UnixMilli(), 10)
err := i.OptionService.Save(ctx, optionMap)
  BirthDay = Property{
      KeyValue:     "birthday",
      DefaultValue: int(0),
      Kind:         reflect.Int,
  }

试了下直接从代码运行,就已经报错了。

04:02:57 root@raspberrypi sonic ±|master|→ go run main.go
# runtime/cgo
In file included from _cgo_export.c:4:
cgo-gcc-export-header-prolog:31:14: error: size of array ‘_check_for_64_bit_pointer_matching_GoInt’ is negative
^C
04:03:52 root@raspberrypi sonic ±|master|→ uname -a
Linux raspberrypi 6.1.61-v8+ #1696 SMP PREEMPT Thu Nov  2 16:44:46 GMT 2023 aarch64 GNU/Linux
04:04:12 root@raspberrypi sonic ±|master|→ go env | grep GOARCH
GOARCH='arm64'
04:04:49 root@raspberrypi sonic ±|master|→ GOARCH=arm64 go run main.go
# runtime/cgo
In file included from _cgo_export.c:4:
cgo-gcc-export-header-prolog:31:14: error: size of array ‘_check_for_64_bit_pointer_matching_GoInt’ is negative
^C
04:05:07 root@raspberrypi sonic ±|master|→ GOARCH=arm go run main.go
exit status 1

解释一下上述操作的意图和结论。

  1. 直接从代码运行,报错 _check_for_64_bit_pointer_matching_GoInt 数组的长度为负。
  2. uname 命令检查了 kernel 参数,确认当前是在 aarch64 模式。应该就是 64bit 了。
  3. go env 命令进一步确认了当前系统的架构是 arm64
  4. 特别指定 GOARCH=arm64 然后从代码运行项目,得到与第 1 步相同的结果。
  5. 指定 GOARCH=arm 然后从代码云心项目,只得到一个 exit status 1 的结果。
jakezhu9 commented 11 months ago

@simonkuang 感谢你提供更多信息,但从你的输出(‘_check_for_64_bit_pointer_matching_GoInt’ is negative)来看应该是和编译器/编译环境相关的错误,抱歉我手上仅有的arm环境暂时没法复现,可能要你自己看看 而最后的exit status 1,我猜测可能是程序初始化阶段出现了一些错误,看看 sonic.log 文件里有没有相关的内容? 另外想问一下你最开始运行的是哪个版本?sonic-linux-arm64?

当然 @textworld 的分析也是正确的,32 位下确实会有问题,欢迎 PR

textworld commented 11 months ago

@jakezhu9 我手头有一台raspberry 3B,我测试一下没问题后会提个PR的

simonkuang commented 11 months ago

@simonkuang 感谢你提供更多信息,但从你的输出(‘_check_for_64_bit_pointer_matching_GoInt’ is negative)来看应该是和编译器/编译环境相关的错误,抱歉我手上仅有的arm环境暂时没法复现,可能要你自己看看 而最后的exit status 1,我猜测可能是程序初始化阶段出现了一些错误,看看 sonic.log 文件里有没有相关的内容? 另外想问一下你最开始运行的是哪个版本?sonic-linux-arm64?

当然 @textworld 的分析也是正确的,32 位下确实会有问题,欢迎 PR

需要补充一个信息。这可能是我的错……

我今天给另外一台树莓派重做系统的时候发现,我之前好像选择了 RaspbianOS Lite (Legancy),是一个过时的系统。据官方的播客描述,那段时间是 RaspbianOS 从 32-bit 向 64-bit 过度的中间时期,系统不稳定。我估计可能跟这个有关。

比如在安装 rust 时我也遇到类似的问题,只能安装 armhf 架构(32-bit)的版本,无法安装 arm64 架构的版本。

也就是说说,只要能支持 arm 架构,应该就完美了。似乎不用考虑我这种特殊情况。

PS:我正在重装一个最新的 Raspberrypi OS 测试。有进一步消息随时更新