@@ -4,8 +4,12 @@ import java.lang.foreign.Arena
44import java.lang.foreign.FunctionDescriptor
55import java.lang.foreign.Linker
66import java.lang.foreign.MemorySegment
7+ import java.lang.foreign.SymbolLookup
78import java.lang.foreign.ValueLayout
89import java.lang.invoke.MethodHandle
10+ import java.nio.file.Path
11+ import spock.lang.IgnoreIf
12+ import util.NativeLibraryResolver
913
1014class FFMInstrumentationTest extends InstrumentationSpecification {
1115 @Override
@@ -15,10 +19,10 @@ class FFMInstrumentationTest extends InstrumentationSpecification {
1519 injectSysConfig(" trace.native.methods" , " unknown[*]" )
1620 }
1721
18- def " should trace ffm calls" () {
22+ def " should trace ffm calls for #configured " () {
1923 setup :
2024 injectSysConfig(" trace.native.methods" , configured)
21- final MemorySegment strlenAddr = lookup . call (). findOrThrow(" strlen" )
25+ final MemorySegment strlenAddr = Linker . nativeLinker() . defaultLookup (). findOrThrow(" strlen" )
2226 final MethodHandle strlenHandle =
2327 Linker . nativeLinker(). downcallHandle(
2428 strlenAddr, FunctionDescriptor . of(ValueLayout . JAVA_LONG , ValueLayout . ADDRESS ))
@@ -47,16 +51,94 @@ class FFMInstrumentationTest extends InstrumentationSpecification {
4751 }
4852
4953 where :
50- configured | traceExpected | resource | lookup
51- " " | false | _ | {
52- Linker . nativeLinker(). defaultLookup()
54+ configured | traceExpected | resource
55+ " " | false | _
56+ " [strlen]" | true | " strlen"
57+ " [*]" | true | " strlen"
58+ }
59+
60+ @IgnoreIf ({ !os.isLinux() })
61+ def " should trace ffm calls using libraryLookup by name for #configured" () {
62+ setup :
63+ injectSysConfig(" trace.native.methods" , configured)
64+
65+ when :
66+ long len
67+ try (final Arena arena = Arena . ofConfined()) {
68+ final SymbolLookup libLookup = SymbolLookup . libraryLookup(" c" , arena)
69+ final MemorySegment strlenAddr = libLookup. findOrThrow(" strlen" )
70+ final MethodHandle strlenHandle =
71+ Linker . nativeLinker(). downcallHandle(
72+ strlenAddr, FunctionDescriptor . of(ValueLayout . JAVA_LONG , ValueLayout . ADDRESS ))
73+ len = (long ) strlenHandle. invokeWithArguments(arena. allocateFrom(" Hello world!" ))
5374 }
54- " [strlen]" | true | " strlen" | {
55- Linker . nativeLinker(). defaultLookup()
75+
76+ then :
77+ len == 12
78+ assertTraces(traceExpected ? 1 : 0 ) {
79+ if (traceExpected) {
80+ trace(1 ) {
81+ span {
82+ operationName " trace.native"
83+ resourceName " $resource "
84+ tags {
85+ " $Tags . COMPONENT " " trace-ffm"
86+ defaultTags()
87+ }
88+ }
89+ }
90+ }
91+ }
92+
93+ where :
94+ configured | traceExpected | resource
95+ " " | false | _
96+ " c[strlen]" | true | " c.strlen"
97+ " c[*]" | true | " c.strlen"
98+ " unknown_lib[*]" | false | _
99+ }
100+
101+ @IgnoreIf ({ !os.isLinux() })
102+ def " should trace ffm calls using libraryLookup by path for #configTemplate" () {
103+ setup :
104+ final MemorySegment strlenSym = Linker . nativeLinker(). defaultLookup(). findOrThrow(" strlen" )
105+ final String libPath = NativeLibraryResolver . findLibraryPath(strlenSym)
106+ final String libFileName = Path . of(libPath). getFileName(). toString(). toLowerCase(Locale . ROOT )
107+ injectSysConfig(" trace.native.methods" , configTemplate. replace(" {lib}" , libFileName))
108+
109+ when :
110+ long len
111+ try (final Arena arena = Arena . ofConfined()) {
112+ final SymbolLookup libLookup = SymbolLookup . libraryLookup(Path . of(libPath), arena)
113+ final MemorySegment strlenAddr = libLookup. findOrThrow(" strlen" )
114+ final MethodHandle strlenHandle =
115+ Linker . nativeLinker(). downcallHandle(
116+ strlenAddr, FunctionDescriptor . of(ValueLayout . JAVA_LONG , ValueLayout . ADDRESS ))
117+ len = (long ) strlenHandle. invokeWithArguments(arena. allocateFrom(" Hello world!" ))
56118 }
57- " [*]" | true | " strlen" | {
58- Linker . nativeLinker(). defaultLookup()
119+
120+ then :
121+ len == 12
122+ assertTraces(traceExpected ? 1 : 0 ) {
123+ if (traceExpected) {
124+ trace(1 ) {
125+ span {
126+ operationName " trace.native"
127+ resourceName " ${ libFileName} .strlen"
128+ tags {
129+ " $Tags . COMPONENT " " trace-ffm"
130+ defaultTags()
131+ }
132+ }
133+ }
134+ }
59135 }
136+
137+ where :
138+ configTemplate | traceExpected
139+ " " | false
140+ " {lib}[strlen]" | true
141+ " {lib}[*]" | true
142+ " unknown_lib[*]" | false
60143 }
61144}
62-
0 commit comments