dwarf: ensure Goroutine-safety in DWARFLines.Line function (#911)
Signed-off-by: Takeshi Yoneda <takeshi@tetrate.io>
This commit is contained in:
@@ -6,6 +6,7 @@ import (
|
||||
"fmt"
|
||||
"io"
|
||||
"sort"
|
||||
"sync"
|
||||
)
|
||||
|
||||
// DWARFLines is used to retrieve source code line information from the DWARF data.
|
||||
@@ -15,6 +16,7 @@ type DWARFLines struct {
|
||||
// linesPerEntry maps dwarf.Offset for dwarf.Entry to the list of lines contained by the entry.
|
||||
// The value is sorted in the increasing order by the address.
|
||||
linesPerEntry map[dwarf.Offset][]line
|
||||
mux sync.Mutex
|
||||
}
|
||||
|
||||
type line struct {
|
||||
@@ -37,6 +39,12 @@ func (d *DWARFLines) Line(instructionOffset uint64) string {
|
||||
return ""
|
||||
}
|
||||
|
||||
// DWARFLines is created per Wasm binary, so there's a possibility that multiple instances
|
||||
// created from a same binary face runtime error at the same time, and that results in
|
||||
// concurrent access to this function.
|
||||
d.mux.Lock()
|
||||
defer d.mux.Unlock()
|
||||
|
||||
r := d.d.Reader()
|
||||
|
||||
// Get the dwarf.Entry containing the instruction.
|
||||
|
||||
@@ -3,6 +3,7 @@ package wasmdebug_test
|
||||
import (
|
||||
"fmt"
|
||||
"math"
|
||||
"sync"
|
||||
"testing"
|
||||
|
||||
"github.com/tetratelabs/wazero/api"
|
||||
@@ -44,8 +45,19 @@ func TestDWARFLines_Line_TinyGO(t *testing.T) {
|
||||
|
||||
for _, tc := range tests {
|
||||
t.Run(tc.exp, func(t *testing.T) {
|
||||
actual := mod.DWARFLines.Line(tc.offset)
|
||||
require.Contains(t, actual, tc.exp)
|
||||
// Ensures that DWARFLines.Line is goroutine-safe.
|
||||
const concurrent = 100
|
||||
var wg sync.WaitGroup
|
||||
wg.Add(concurrent)
|
||||
|
||||
for i := 0; i < concurrent; i++ {
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
actual := mod.DWARFLines.Line(tc.offset)
|
||||
require.Contains(t, actual, tc.exp)
|
||||
}()
|
||||
}
|
||||
wg.Wait()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user