github.com/wasilibs/wazerox@v0.0.0-20240124024944-4923be63ab5f/internal/wasmdebug/dwarf_test.go (about)

     1  package wasmdebug_test
     2  
     3  import (
     4  	"fmt"
     5  	"strings"
     6  	"testing"
     7  
     8  	"github.com/wasilibs/wazerox/api"
     9  	"github.com/wasilibs/wazerox/internal/testing/dwarftestdata"
    10  	"github.com/wasilibs/wazerox/internal/testing/hammer"
    11  	"github.com/wasilibs/wazerox/internal/testing/require"
    12  	"github.com/wasilibs/wazerox/internal/wasm"
    13  	"github.com/wasilibs/wazerox/internal/wasm/binary"
    14  )
    15  
    16  func TestDWARFLines_Line_Zig(t *testing.T) {
    17  	mod, err := binary.DecodeModule(dwarftestdata.ZigWasm, api.CoreFeaturesV2, wasm.MemoryLimitPages, false, true, false)
    18  	require.NoError(t, err)
    19  	require.NotNil(t, mod.DWARFLines)
    20  
    21  	// codeSecStart is the beginning of the code section in the Wasm binary.
    22  	// If dwarftestdata.ZigWasm has been changed, we need to inspect by `wasm-tools objdump`.
    23  	const codeSecStart = 0x46
    24  
    25  	// These cases are crafted by matching the stack trace result from wasmtime. To verify, run:
    26  	//
    27  	// 	WASMTIME_BACKTRACE_DETAILS=1 wasmtime run internal/testing/dwarftestdata/testdata/zig/main.wasm
    28  	//
    29  	// And this should produce the output as:
    30  	//
    31  	// Caused by:
    32  	//    0: failed to invoke command default
    33  	//    1: error while executing at wasm backtrace:
    34  	//           0:   0xa9 - builtin.default_panic
    35  	//                           at /Users/adrian/Downloads/zig-macos-aarch64-0.11.0-dev.3334+cd1417dbd/lib/std/builtin.zig:889:17
    36  	//           1:   0x6b - main.inlined_b
    37  	//                           at /Users/adrian/oss/wazero/internal/testing/dwarftestdata/testdata/zig/main.zig:10:5              - main.inlined_a
    38  	//                           at /Users/adrian/oss/wazero/internal/testing/dwarftestdata/testdata/zig/main.zig:6:5              - main.main
    39  	//                           at /Users/adrian/oss/wazero/internal/testing/dwarftestdata/testdata/zig/main.zig:2:5
    40  	//           2:   0xb0 - start.callMain
    41  	//                           at /Users/adrian/Downloads/zig-macos-aarch64-0.11.0-dev.3334+cd1417dbd/lib/std/start.zig:609:37              - _start
    42  	//                           at /Users/adrian/Downloads/zig-macos-aarch64-0.11.0-dev.3334+cd1417dbd/lib/std/start.zig:224:5
    43  	//    2: wasm trap: wasm `unreachable` instruction executed
    44  	for _, tc := range []struct {
    45  		offset uint64
    46  		exp    []string
    47  	}{
    48  		{offset: 0xa9 - codeSecStart, exp: []string{
    49  			"lib/std/builtin.zig:889:17",
    50  		}},
    51  		{offset: 0x6b - codeSecStart, exp: []string{
    52  			"zig/main.zig:10:5 (inlined)",
    53  			"zig/main.zig:6:5 (inlined)",
    54  			"zig/main.zig:2:5",
    55  		}},
    56  		{offset: 0xb0 - codeSecStart, exp: []string{
    57  			"lib/std/start.zig:609:37 (inlined)",
    58  			"lib/std/start.zig:224:5",
    59  		}},
    60  	} {
    61  		tc := tc
    62  		t.Run(fmt.Sprintf("%#x/%s", tc.offset, tc.exp), func(t *testing.T) {
    63  			// Ensures that DWARFLines.Line is goroutine-safe.
    64  			hammer.NewHammer(t, 100, 5).Run(func(name string) {
    65  				actual := mod.DWARFLines.Line(tc.offset)
    66  				require.Equal(t, len(tc.exp), len(actual))
    67  				for i := range tc.exp {
    68  					require.Contains(t, actual[i], tc.exp[i])
    69  				}
    70  			}, nil)
    71  		})
    72  	}
    73  }
    74  
    75  func TestDWARFLines_Line_Rust(t *testing.T) {
    76  	if len(dwarftestdata.RustWasm) == 0 {
    77  		t.Skip()
    78  	}
    79  	mod, err := binary.DecodeModule(dwarftestdata.RustWasm, api.CoreFeaturesV2, wasm.MemoryLimitPages, false, true, false)
    80  	require.NoError(t, err)
    81  	require.NotNil(t, mod.DWARFLines)
    82  
    83  	// codeSecStart is the beginning of the code section in the Wasm binary.
    84  	// If dwarftestdata.RustWasm has been changed, we need to inspect by `wasm-tools objdump`.
    85  	const codeSecStart = 0x309
    86  
    87  	// These cases are crafted by matching the stack trace result from wasmtime. To verify, run:
    88  	//
    89  	// 	WASMTIME_BACKTRACE_DETAILS=1 wasmtime run internal/testing/dwarftestdata/testdata/rust/main.wasm
    90  	//
    91  	// And this should produce the output as:
    92  	// Caused by:
    93  	//    0: failed to invoke command default
    94  	//    1: error while executing at wasm backtrace:
    95  	//           0: 0xc77d - core::ptr::const_ptr::<impl *const T>::offset::ha55096d7e14d75d8
    96  	//                           at /rustc/c396bb3b8a16b1f2762b7c6078dc3e023f6a2493/library/core/src/slice/index.rs:286:39              - core::ptr::const_ptr::<impl *const T>::add::h089d5a72f68a4291
    97  	//                           at /rustc/c396bb3b8a16b1f2762b7c6078dc3e023f6a2493/library/core/src/ptr/const_ptr.rs:870:18              - <core::ops::range::Range<usize> as core::slice::index::SliceIndex<[T]>>::get_unchecked::h29ddcf1882fa0f66
    98  	//                           at /rustc/c396bb3b8a16b1f2762b7c6078dc3e023f6a2493/library/core/src/slice/index.rs:286:39              - <core::ops::range::RangeFrom<usize> as core::slice::index::SliceIndex<[T]>>::get_unchecked::h75ebc890f16858ff
    99  	//                           at /rustc/c396bb3b8a16b1f2762b7c6078dc3e023f6a2493/library/core/src/slice/mod.rs:1630:46              - core::slice::<impl [T]>::get_unchecked::h6278e5a065ea078a
   100  	//                           at /rustc/c396bb3b8a16b1f2762b7c6078dc3e023f6a2493/library/core/src/slice/mod.rs:405:20              - core::slice::<impl [T]>::split_at_unchecked::h88a6f1e7c576a79c
   101  	//                           at /rustc/c396bb3b8a16b1f2762b7c6078dc3e023f6a2493/library/core/src/slice/mod.rs:1630:46              - core::slice::<impl [T]>::split_at::h68e6904057100aef
   102  	//                           at /rustc/c396bb3b8a16b1f2762b7c6078dc3e023f6a2493/library/core/src/slice/mod.rs:1548:18              - <core::slice::iter::Chunks<T> as core::iter::traits::iterator::Iterator>::next::h9e3ea1e50ad1cfcf
   103  	//                           at /rustc/c396bb3b8a16b1f2762b7c6078dc3e023f6a2493/library/core/src/slice/iter.rs:1478:30              - core::str::count::do_count_chars::h124622240ac1fb8b
   104  	//                           at /rustc/c396bb3b8a16b1f2762b7c6078dc3e023f6a2493/library/core/src/str/count.rs:74:18
   105  	//           1: 0xa701 - core::str::validations::utf8_acc_cont_byte::hb47c34b8c4cbf06b
   106  	//                           at /rustc/c396bb3b8a16b1f2762b7c6078dc3e023f6a2493/library/core/src/str/validations.rs:57:19              - core::str::validations::next_code_point::hbb42fe8b8fcbddc3
   107  	//                           at /rustc/c396bb3b8a16b1f2762b7c6078dc3e023f6a2493/library/core/src/str/validations.rs:57:19              - <core::str::iter::Chars as core::iter::traits::iterator::Iterator>::next::h2dc4678e3c0bda18
   108  	//                           at /rustc/c396bb3b8a16b1f2762b7c6078dc3e023f6a2493/library/core/src/str/iter.rs:140:15              - <core::str::iter::CharIndices as core::iter::traits::iterator::Iterator>::next::h430b9a1b0d2fcfcd
   109  	//                           at /rustc/c396bb3b8a16b1f2762b7c6078dc3e023f6a2493/library/core/src/str/iter.rs:140:15              - core::iter::traits::iterator::Iterator::advance_by::hadbf2e62b9ea873e
   110  	//                           at /rustc/c396bb3b8a16b1f2762b7c6078dc3e023f6a2493/library/core/src/iter/traits/iterator.rs:330:13              - core::iter::traits::iterator::Iterator::nth::h68978ac344a2c26f
   111  	//                           at /rustc/c396bb3b8a16b1f2762b7c6078dc3e023f6a2493/library/core/src/iter/traits/iterator.rs:377:9              - core::fmt::Formatter::pad::hc91f9fb3fb51f81f
   112  	//                           at /rustc/c396bb3b8a16b1f2762b7c6078dc3e023f6a2493/library/core/src/fmt/mod.rs:1455:35
   113  	//           2: 0x45e8 - alloc::alloc::dealloc::hde3d57428722ee9b
   114  	//                           at /rustc/c396bb3b8a16b1f2762b7c6078dc3e023f6a2493/library/alloc/src/alloc.rs:244:22              - <alloc::alloc::Global as core::alloc::Allocator>::deallocate::h9c672f23742d6fbc
   115  	//                           at /rustc/c396bb3b8a16b1f2762b7c6078dc3e023f6a2493/library/alloc/src/alloc.rs:244:22              - alloc::alloc::box_free::hd090040c59659308
   116  	//                           at /rustc/c396bb3b8a16b1f2762b7c6078dc3e023f6a2493/library/alloc/src/alloc.rs:342:9              - core::ptr::drop_in_place<alloc::boxed::Box<std::io::error::Custom>>::h3d2c76e2b4a26668
   117  	//                           at /rustc/c396bb3b8a16b1f2762b7c6078dc3e023f6a2493/library/core/src/ptr/mod.rs:487:1              - core::ptr::drop_in_place<std::io::error::ErrorData<alloc::boxed::Box<std::io::error::Custom>>>::hcaa143fc963fdc85
   118  	//                           at /rustc/c396bb3b8a16b1f2762b7c6078dc3e023f6a2493/library/core/src/ptr/mod.rs:487:1              - core::ptr::drop_in_place<std::io::error::repr_unpacked::Repr>::hf8eda15dbd953cd1
   119  	//                           at /rustc/c396bb3b8a16b1f2762b7c6078dc3e023f6a2493/library/core/src/ptr/mod.rs:487:1              - core::ptr::drop_in_place<std::io::error::Error>::ha50d906acd95a768
   120  	//                           at /rustc/c396bb3b8a16b1f2762b7c6078dc3e023f6a2493/library/core/src/ptr/mod.rs:487:1              - core::ptr::drop_in_place<core::result::Result<(),std::io::error::Error>>::h1a246d5cbc0481cf
   121  	//                           at /rustc/c396bb3b8a16b1f2762b7c6078dc3e023f6a2493/library/core/src/ptr/mod.rs:487:1              - core::mem::drop::h37b541d3c993930c
   122  	//                           at /rustc/c396bb3b8a16b1f2762b7c6078dc3e023f6a2493/library/std/src/panicking.rs:292:17              - std::panicking::default_hook::{{closure}}::h78d75d30689791e7
   123  	//                           at /rustc/c396bb3b8a16b1f2762b7c6078dc3e023f6a2493/library/std/src/panicking.rs:292:17
   124  	//           3: 0xad95 - core::fmt::ArgumentV1::as_usize::h1da6b057d1a7dc54
   125  	//                           at /rustc/c396bb3b8a16b1f2762b7c6078dc3e023f6a2493/library/core/src/fmt/mod.rs:362:12              - core::fmt::getcount::h8c5d6b3aea75a2d3
   126  	//                           at /rustc/c396bb3b8a16b1f2762b7c6078dc3e023f6a2493/library/core/src/fmt/mod.rs:1257:22              - core::fmt::run::h78a98448d78ecec3
   127  	//                           at /rustc/c396bb3b8a16b1f2762b7c6078dc3e023f6a2493/library/core/src/fmt/mod.rs:1235:21              - core::fmt::write::h5471a2341ce22f17
   128  	//                           at /rustc/c396bb3b8a16b1f2762b7c6078dc3e023f6a2493/library/core/src/fmt/mod.rs:1214:26
   129  	//           4: 0xc44d - core::fmt::Write::write_fmt::h4a7e084f8beacf08
   130  	//                           at /rustc/c396bb3b8a16b1f2762b7c6078dc3e023f6a2493/library/core/src/fmt/mod.rs:188:26
   131  	//           5: 0xbae8 - core::fmt::Formatter::write_str::hc634aaecc183d175
   132  	//                           at /rustc/c396bb3b8a16b1f2762b7c6078dc3e023f6a2493/library/core/src/fmt/mod.rs:1629:9              - core::fmt::builders::DebugStruct::finish_non_exhaustive::{{closure}}::h51dc89dce87b7120
   133  	//                           at /rustc/c396bb3b8a16b1f2762b7c6078dc3e023f6a2493/library/core/src/fmt/builders.rs:199:17              - core::result::Result<T,E>::and_then::hea34a5d4dd616ad6
   134  	//                           at /rustc/c396bb3b8a16b1f2762b7c6078dc3e023f6a2493/library/core/src/result.rs:1352:22              - core::fmt::builders::DebugStruct::finish_non_exhaustive::h87daf5524c71dda9
   135  	//                           at /rustc/c396bb3b8a16b1f2762b7c6078dc3e023f6a2493/library/core/src/fmt/builders.rs:187:23
   136  	//           6: 0xc046 - core::fmt::Formatter::pad_integral::ha8bb3db77298fecc
   137  	//                           at /rustc/c396bb3b8a16b1f2762b7c6078dc3e023f6a2493/library/core/src/fmt/mod.rs:1384:17
   138  	//           7: 0xb035 - core::slice::memchr::memchr_general_case::hb481b2edf3b1871e
   139  	//                           at /rustc/c396bb3b8a16b1f2762b7c6078dc3e023f6a2493/library/core/src/slice/memchr.rs
   140  	//           8: 0xc06a - core::fmt::Formatter::pad_integral::ha8bb3db77298fecc
   141  	//                           at /rustc/c396bb3b8a16b1f2762b7c6078dc3e023f6a2493/library/core/src/fmt/mod.rs
   142  	//           9: 0xc09e - core::fmt::Formatter::padding::h4b882ffb39d00a12
   143  	//                           at /rustc/c396bb3b8a16b1f2762b7c6078dc3e023f6a2493/library/core/src/fmt/mod.rs:1504:35              - core::fmt::Formatter::pad_integral::ha8bb3db77298fecc
   144  	//                           at /rustc/c396bb3b8a16b1f2762b7c6078dc3e023f6a2493/library/core/src/fmt/mod.rs:1407:36
   145  	//          10: 0xb1a3 - <core::panic::location::Location as core::fmt::Display>::fmt::hf3870c0af6a67fac
   146  	//                           at /rustc/c396bb3b8a16b1f2762b7c6078dc3e023f6a2493/library/core/src/panic/location.rs:196:6
   147  	//          11: 0x8ee0 - <unknown>!std::rt::lang_start_internal::h3c39e5d3c278a90f
   148  	//          12: 0xae9d - core::fmt::write::h5471a2341ce22f17
   149  	//                           at /rustc/c396bb3b8a16b1f2762b7c6078dc3e023f6a2493/library/core/src/fmt/mod.rs:1226:2
   150  	//          13: 0xc3b7 - core::char::methods::encode_utf8_raw::h700e7a293d6eb2b7
   151  	//                           at /rustc/c396bb3b8a16b1f2762b7c6078dc3e023f6a2493/library/core/src/char/methods.rs:1677:13              - core::char::methods::<impl char>::encode_utf8::h641f2d1d001008d5
   152  	//                           at /rustc/c396bb3b8a16b1f2762b7c6078dc3e023f6a2493/library/core/src/fmt/mod.rs:165:24              - core::fmt::Write::write_char::ha951e2975b9730c3
   153  	//                           at /rustc/c396bb3b8a16b1f2762b7c6078dc3e023f6a2493/library/core/src/fmt/mod.rs:165:24
   154  	//          14: 0xc418 - core::fmt::Write::write_fmt::h4a7e084f8beacf08
   155  	//                           at /rustc/c396bb3b8a16b1f2762b7c6078dc3e023f6a2493/library/core/src/fmt/mod.rs:187
   156  	//          15: 0xc6e7 - core::iter::traits::iterator::Iterator::fold::h99ed29c108afc948
   157  	//                           at /rustc/c396bb3b8a16b1f2762b7c6078dc3e023f6a2493/library/core/src/iter/traits/iterator.rs:2414:21              - <core::iter::adapters::map::Map<I,F> as core::iter::traits::iterator::Iterator>::fold::ha5be3bb1eeeaf8fe
   158  	//                           at /rustc/c396bb3b8a16b1f2762b7c6078dc3e023f6a2493/library/core/src/iter/adapters/map.rs:124:9              - <usize as core::iter::traits::accum::Sum>::sum::h00b4d0c0300e94a9
   159  	//                           at /rustc/c396bb3b8a16b1f2762b7c6078dc3e023f6a2493/library/core/src/iter/traits/accum.rs:42:17              - core::iter::traits::iterator::Iterator::sum::h04374b17d4abbea5
   160  	//                           at /rustc/c396bb3b8a16b1f2762b7c6078dc3e023f6a2493/library/core/src/iter/traits/iterator.rs:3347:9              - <core::iter::adapters::filter::Filter<I,P> as core::iter::traits::iterator::Iterator>::count::h5c8b4c5e67e6831c
   161  	//                           at /rustc/c396bb3b8a16b1f2762b7c6078dc3e023f6a2493/library/core/src/str/count.rs:135:5              - core::str::count::char_count_general_case::hfffa06842344b9fe
   162  	//                           at /rustc/c396bb3b8a16b1f2762b7c6078dc3e023f6a2493/library/core/src/str/count.rs:135:5              - core::str::count::do_count_chars::h124622240ac1fb8b
   163  	//                           at /rustc/c396bb3b8a16b1f2762b7c6078dc3e023f6a2493/library/core/src/str/count.rs:71:21
   164  	for _, tc := range []struct {
   165  		offset uint64
   166  		exp    []string
   167  	}{
   168  		{offset: 0xc77d - codeSecStart, exp: []string{
   169  			"/library/core/src/slice/index.rs:286:39",
   170  			"/library/core/src/ptr/const_ptr.rs:870:18",
   171  			"/library/core/src/slice/index.rs:286:39",
   172  			"/library/core/src/slice/mod.rs:1630:46",
   173  			"/library/core/src/slice/mod.rs:405:20",
   174  			"/library/core/src/slice/mod.rs:1630:46",
   175  			"/library/core/src/slice/mod.rs:1548:18",
   176  			"/library/core/src/slice/iter.rs:1478:30",
   177  			"/library/core/src/str/count.rs:74:18",
   178  		}},
   179  		{offset: 0xc06a - codeSecStart, exp: []string{"/library/core/src/fmt/mod.rs"}},
   180  		{offset: 0xc6e7 - codeSecStart, exp: []string{
   181  			"/library/core/src/iter/traits/iterator.rs:2414:21",
   182  			"/library/core/src/iter/adapters/map.rs:124:9",
   183  			"/library/core/src/iter/traits/accum.rs:42:17",
   184  			"/library/core/src/iter/traits/iterator.rs:3347:9",
   185  			"/library/core/src/str/count.rs:135:5",
   186  			"/library/core/src/str/count.rs:135:5",
   187  			"/library/core/src/str/count.rs:71:21",
   188  		}},
   189  	} {
   190  		tc := tc
   191  		t.Run(fmt.Sprintf("%#x/%s", tc.offset, tc.exp), func(t *testing.T) {
   192  			actual := mod.DWARFLines.Line(tc.offset)
   193  
   194  			require.Equal(t, len(tc.exp), len(actual))
   195  			for i := range tc.exp {
   196  				require.Contains(t, actual[i], tc.exp[i])
   197  			}
   198  		})
   199  	}
   200  }
   201  
   202  func TestDWARFLines_Line_TinyGo(t *testing.T) {
   203  	mod, err := binary.DecodeModule(dwarftestdata.TinyGoWasm, api.CoreFeaturesV2, wasm.MemoryLimitPages, false, true, false)
   204  	require.NoError(t, err)
   205  	require.NotNil(t, mod.DWARFLines)
   206  
   207  	// codeSecStart is the beginning of the code section in the Wasm binary.
   208  	// If dwarftestdata.TinyGoWasm has been changed, we need to inspect by `wasm-tools objdump`.
   209  	const codeSecStart = 0x16f
   210  
   211  	// These cases are crafted by matching the stack trace result from wasmtime. To verify, run:
   212  	//
   213  	// 	WASMTIME_BACKTRACE_DETAILS=1 wasmtime run internal/testing/dwarftestdata/testdata/tinygo/main.wasm
   214  	//
   215  	// And this should produce the output as:
   216  	//
   217  	// Caused by:
   218  	//    0: failed to invoke command default
   219  	//    1: error while executing at wasm backtrace:
   220  	//           0: 0x1a62 - runtime.abort
   221  	//                           at /Users/mathetake/Downloads/tinygo/src/runtime/runtime_tinygowasm.go:70:6              - runtime._panic
   222  	//                           at /Users/mathetake/Downloads/tinygo/src/runtime/panic.go:52:7
   223  	//           1: 0x3168 - main.c
   224  	//                           at /Users/mathetake/Downloads/tinygo/tmo/main.go:16:7
   225  	//           2: 0x3106 - main.b
   226  	//                           at /Users/mathetake/Downloads/tinygo/tmo/main.go:12:3
   227  	//           3: 0x30a8 - main.a
   228  	//                           at /Users/mathetake/Downloads/tinygo/tmo/main.go:8:3
   229  	//           4: 0x22b8 - main.main
   230  	//                           at /Users/mathetake/Downloads/tinygo/tmo/main.go:4:3
   231  	//           5: 0x213a - runtime.run$1
   232  	//                           at /Users/mathetake/Downloads/tinygo/src/runtime/scheduler_any.go:25:11
   233  	//           6:  0x85f - <goroutine wrapper>
   234  	//                           at /Users/mathetake/Downloads/tinygo/src/runtime/scheduler_any.go:23:2
   235  	//           7:  0x192 - tinygo_launch
   236  	//                           at /Users/mathetake/Downloads/tinygo/src/internal/task/task_asyncify_wasm.S:59
   237  	//           8: 0x2033 - (*internal/task.Task).Resume
   238  	//                           at /Users/mathetake/Downloads/tinygo/src/internal/task/task_asyncify.go:109:17              - runtime.scheduler
   239  	//                           at /Users/mathetake/Downloads/tinygo/src/runtime/scheduler.go:236:11
   240  	//           9: 0x1f01 - runtime.run
   241  	//                           at /Users/mathetake/Downloads/tinygo/src/runtime/scheduler_any.go:28:11
   242  	//          10: 0x1e81 - _start
   243  	//                           at /Users/mathetake/Downloads/tinygo/src/runtime/runtime_wasm_wasi.go:21:5
   244  	for _, tc := range []struct {
   245  		offset uint64
   246  		exp    []string
   247  	}{
   248  		{offset: 0x1e81 - codeSecStart, exp: []string{"runtime/runtime_wasm_wasi.go:21:5"}},
   249  		{offset: 0x1f01 - codeSecStart, exp: []string{"runtime/scheduler_any.go:28:11"}},
   250  		{offset: 0x2033 - codeSecStart, exp: []string{
   251  			"internal/task/task_asyncify.go:109:17",
   252  			"runtime/scheduler.go:236:11",
   253  		}},
   254  		{offset: 0x192 - codeSecStart, exp: []string{"internal/task/task_asyncify_wasm.S:59"}},
   255  		{offset: 0x85f - codeSecStart, exp: []string{"runtime/scheduler_any.go:23:2"}},
   256  		{offset: 0x213a - codeSecStart, exp: []string{"runtime/scheduler_any.go:25:11"}},
   257  		{offset: 0x22b8 - codeSecStart, exp: []string{"main.go:4:3"}},
   258  		{offset: 0x30a8 - codeSecStart, exp: []string{"main.go:8:3"}},
   259  		{offset: 0x3106 - codeSecStart, exp: []string{"main.go:12:3"}},
   260  		{offset: 0x3168 - codeSecStart, exp: []string{"main.go:16:7"}},
   261  		// Note(important): this case is different from the output of Wasmtime, which produces the incorrect inline info (panic.go:52:7).
   262  		// Actually, "runtime_tinygowasm.go:70:6" invokes trap() which is translated as "unreachable" instruction by LLVM, so there won't be
   263  		// any inlined function invocation here.
   264  		{offset: 0x1a62 - codeSecStart, exp: []string{"runtime/runtime_tinygowasm.go:70:6"}},
   265  	} {
   266  		tc := tc
   267  		t.Run(fmt.Sprintf("%#x/%s", tc.offset, tc.exp), func(t *testing.T) {
   268  			actual := mod.DWARFLines.Line(tc.offset)
   269  			require.Equal(t, len(tc.exp), len(actual), "\nexp: %s\ngot: %s", strings.Join(tc.exp, "\n"), strings.Join(actual, "\n"))
   270  			for i := range tc.exp {
   271  				require.Contains(t, actual[i], tc.exp[i])
   272  			}
   273  		})
   274  	}
   275  }