Why "index out of range" stack traces don't list the indices

polaris · · 565 次点击    
这是一个分享于 的资源,其中的信息可能已经有所发展或是发生改变。
<p>I was annoyed that such stack traces don&#39;t provide some simple numbers to say the length of the slice and the index, something like:</p> <pre><code>panic: runtime error: index out of range ($idx &gt; $len) panic: runtime error: index out of range ($idx &lt; 0) </code></pre> <p>So I looked into how the compiler implements bounds-checking code. That error message comes from <code>runtime/panic.go</code>.</p> <pre><code>var indexError = error(errorString(&#34;index out of range&#34;)) func panicindex() { panicCheckMalloc(indexError) panic(indexError) } </code></pre> <p>Searching for panicindex in the code base reveals that it is never explicitly called, only via dynamic dispatch. The bounds-checking happens in <code>cmd/compile/internal/gc/ssa.go</code>, which is 5,000 lines long.</p> <pre><code>func (s *state) boundsCheck(idx, len *ssa.Value) { if Debug[&#39;B&#39;] != 0 { return } // bounds check cmp := s.newValue2(ssa.OpIsInBounds, Types[TBOOL], idx, len) s.check(cmp, panicindex) } </code></pre> <p><code>s.check(cmp, panicindex)</code> generates the code to panic, but it requires <code>cmp</code> to be a boolean variable. newValue2 generates the code to compare, terminating in this function:</p> <pre><code>func (f *Func) newValue(op Op, t Type, b *Block, pos src.XPos) *Value { var v *Value if f.freeValues != nil { v = f.freeValues f.freeValues = v.argstorage[0] v.argstorage[0] = nil } else { ID := f.vid.get() if int(ID) &lt; len(f.Config.values) { v = &amp;f.Config.values[ID] } else { v = &amp;Value{ID: ID} } } v.Op = op v.Type = t v.Block = b v.Pos = pos b.Values = append(b.Values, v) return v } </code></pre> <p>Because the panic error messages appear designed to have the same signature for dynamic dispatch, and are so far removed from the actual numbers, including the indices like that would require substantial refactoring.</p> <hr/>**评论:**<br/><br/>jerf: <pre><p>I salute you for investigating the nature of your problem, then posting about your investigation, rather than simply complaining and suggesting with one degree of subtleness or another that Go or its programmers suck.</p></pre>mdempsky: <pre><p>FYI <a href="https://github.com/golang/go/issues/14443">https://github.com/golang/go/issues/14443</a></p></pre>ItsNotMineISwear: <pre><p>The obsession with binary size seems silly to me. And it&#39;s the binary size of the compiler, not produced executables? Why does that dominate this discussion?</p></pre>jerf: <pre><p>If they were &#34;obsessed&#34; with it, we&#39;d have fewer features since binary size has been going up in the past few releases.</p> <p>They are <em>considering it as one of many factors</em>. The inability to generate small executables squeezes Go out of some spaces it could otherwise play in. Neither I nor from what I can see the Go team find this to be anything catastrophic, but it is something to be considered moving forward. For the same functionality, smaller is better than larger. Not all Go code is running on desktop machines that have more than twice the RAM they know how to use.</p> <p>You probably won&#39;t be surprised that there are still some embedded platforms out there where having to pay ~2-3MB off the top just for a runtime is a bit of a problem, not to mention how easy it is to tack on more MB by using net/http or encoding/json. You might be surprised at just how picky cloud server writers can be about their bytes too, though. Executable sizes on their own are rarely an intrinsic problem the way that an executable can be simply too large to run on a given embedded platform, but the implied issues with how their stuff fits into cache can be a big deal for them.</p></pre>mdempsky: <pre><p>Thanks to paying consideration to binary size, it&#39;s actually been on a downward trend the last couple of releases: <a href="https://blog.golang.org/go1.7-binary-size" rel="nofollow">https://blog.golang.org/go1.7-binary-size</a></p></pre>jerf: <pre><p>My apologies, and thanks for the correction.</p></pre>mdempsky: <pre><p>Nothing to apologize about. :)</p></pre>mdempsky: <pre><blockquote> <p>And it&#39;s the binary size of the compiler, not produced executables? </p> </blockquote> <p>No, it&#39;s the binary size of compiled executables. We use cmd/go as a representative example of how toolchain changes will affect compiled user programs.</p></pre>

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

565 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传