33import datadog .trace .api .Platform ;
44import datadog .trace .bootstrap .instrumentation .jfr .JfrHelper ;
55import de .thetaphi .forbiddenapis .SuppressForbidden ;
6+
7+ import java .io .BufferedReader ;
68import java .io .File ;
9+ import java .io .FileInputStream ;
710import java .io .FileNotFoundException ;
11+ import java .io .IOException ;
12+ import java .io .InputStreamReader ;
813import java .lang .management .ManagementFactory ;
14+ import java .nio .file .Files ;
15+ import java .nio .file .Paths ;
916import java .util .ArrayList ;
1017import java .util .Arrays ;
1118import java .util .Collections ;
@@ -34,7 +41,8 @@ public class SmapEntryFactory {
3441 private static final Pattern SYSTEM_MAP_ENTRY_PATTERN =
3542 Pattern .compile (
3643 "([0-9a-fA-Fx]+)\\ s+-\\ s+([0-9a-fA-Fx]+)\\ s+(\\ d+)\\ s+(\\ S+)\\ s+(\\ S+)(?:\\ s+(.*))?" );
37- private static final String VSYSCALL_START_ADDRESS = "ffffffffff600000" ;
44+ private static final String VSYSCALL_START_ADDRESS_STR = "ffffffffff600000" ;
45+ private static final long VSYSCALL_START_ADDRESS = 0xffffffffff600000L ;
3846 private static final SmapEntryEvent SMAP_ENTRY_EVENT = new SmapEntryEvent ();
3947
4048 private enum ErrorReason {
@@ -81,6 +89,57 @@ public static void registerEvents() {
8189 }
8290 }
8391
92+ static class AnnotatedRegion {
93+ final long startAddress ;
94+ final String description ;
95+
96+ AnnotatedRegion (long startAddress , String description ) {
97+ this .startAddress = startAddress ;
98+ this .description = description ;
99+ }
100+ }
101+
102+ static AnnotatedRegion fromAnnotatedEntry (String line ) {
103+ boolean isRegion = line .startsWith ("0x" );
104+ if (isRegion ) {
105+ // 0x0000000420000000 - 0x000000043b000000 452984832 rw-p 00000000 JAVAHEAP
106+ boolean isVsyscall = line .startsWith ("0x" + VSYSCALL_START_ADDRESS_STR ); // can't be parsed to Long safely(?)
107+ long startAddress = -1 ;
108+ int dashIndex = line .indexOf ('-' );
109+ if (dashIndex > 0 ) {
110+ startAddress = isVsyscall ? -0x1000 - 1 : Long .decode (line .substring (0 , dashIndex - 1 ));
111+ String description = extractElement (line , 4 , dashIndex + 1 );
112+ if (description == null || description .isEmpty ()) {
113+ return new AnnotatedRegion (startAddress , "UNDEFINED" );
114+ } else if (description .startsWith ("STACK" )) {
115+ return new AnnotatedRegion (startAddress , "STACK" );
116+ } else if (description .startsWith ("[" ) || description .startsWith ("/" )) {
117+ return new AnnotatedRegion (startAddress , "SYSTEM" );
118+ } else {
119+ return new AnnotatedRegion (startAddress , description );
120+ }
121+ }
122+ }
123+ return null ;
124+ }
125+
126+ static String extractElement (String line , int index , int from ) {
127+ int wsCount = 0 ;
128+ int wsIndex = line .indexOf (' ' , from + 1 );
129+ if (wsIndex > 0 ) {
130+ wsCount ++;
131+ while (wsCount < index ) {
132+ while (line .charAt (++wsIndex ) == ' ' ) {}
133+ wsIndex = line .indexOf (' ' , wsIndex + 1 );
134+ if (wsIndex <= 0 ) {
135+ break ;
136+ }
137+ wsCount ++;
138+ }
139+ }
140+ return wsCount == index ? line .substring (wsIndex + 1 ).trim () : null ;
141+ }
142+
84143 @ SuppressForbidden
85144 private static HashMap <Long , String > getAnnotatedRegions () {
86145 if (annotatedMapsAvailable ) {
@@ -97,28 +156,33 @@ private static HashMap<Long, String> getAnnotatedRegions() {
97156 HashMap <Long , String > annotatedRegions = new HashMap <>();
98157
99158 for (String line : lines ) {
100- Matcher matcher = SYSTEM_MAP_ENTRY_PATTERN .matcher (line );
101- if (matcher .matches ()) {
102- long startAddress ;
103- if (matcher .group (1 ).equals ("0x" + VSYSCALL_START_ADDRESS )) {
104- // See how smap entry parsing is done for vsyscall
105- startAddress = -0x1000 - 1 ;
106- } else {
107- startAddress = Long .decode (matcher .group (1 ));
108- }
109- String description = matcher .group (6 );
110- annotatedRegions .put (startAddress , description );
111- if (description .isEmpty ()) {
112- annotatedRegions .put (startAddress , "UNDEFINED" );
113- } else if (description .startsWith ("STACK" )) {
114- annotatedRegions .put (startAddress , "STACK" );
115- } else if (description .startsWith ("[" ) || description .startsWith ("/" )) {
116- annotatedRegions .put (startAddress , "SYSTEM" );
117- } else {
118- annotatedRegions .put (startAddress , description .split ("\\ s+" )[0 ]);
119- }
159+ AnnotatedRegion region = fromAnnotatedEntry (line );
160+ if (region != null ) {
161+ annotatedRegions .put (region .startAddress , region .description );
120162 }
121163 }
164+ // Matcher matcher = SYSTEM_MAP_ENTRY_PATTERN.matcher(line);
165+ // if (matcher.matches()) {
166+ // long startAddress;
167+ // if (matcher.group(1).equals("0x" + VSYSCALL_START_ADDRESS)) {
168+ // // See how smap entry parsing is done for vsyscall
169+ // startAddress = -0x1000 - 1;
170+ // } else {
171+ // startAddress = Long.decode(matcher.group(1));
172+ // }
173+ // String description = matcher.group(6);
174+ // annotatedRegions.put(startAddress, description);
175+ // if (description.isEmpty()) {
176+ // annotatedRegions.put(startAddress, "UNDEFINED");
177+ // } else if (description.startsWith("STACK")) {
178+ // annotatedRegions.put(startAddress, "STACK");
179+ // } else if (description.startsWith("[") || description.startsWith("/")) {
180+ // annotatedRegions.put(startAddress, "SYSTEM");
181+ // } else {
182+ // annotatedRegions.put(startAddress, description.split("\\s+")[0]);
183+ // }
184+ // }
185+ // }
122186 return annotatedRegions ;
123187 } catch (Exception e ) {
124188 new SmapParseErrorEvent (ErrorReason .VM_MAP_PARSING_ERROR ).commit ();
@@ -130,6 +194,67 @@ private static HashMap<Long, String> getAnnotatedRegions() {
130194 }
131195 }
132196
197+ private static int nextDelimitedStart (String line , int from ) {
198+ if (from < 0 ) {
199+ return from ;
200+ }
201+ int idx = line .indexOf (' ' , from + 1 );
202+ while (line .charAt (++idx ) == ' ' ) {}
203+ return idx ;
204+ }
205+
206+ private static int nextDelimitedEnd (String line , int from ) {
207+ if (from < 0 ) {
208+ return from ;
209+ }
210+ int idx = line .indexOf (' ' , from + 1 );
211+ if (idx <= 0 ) {
212+ return line .length ();
213+ }
214+ return idx ;
215+ }
216+
217+ static final class SmapHeader {
218+ long startAddress ;
219+ long endAddress ;
220+ String perms ;
221+ long offset ;
222+ String dev ;
223+ int inode ;
224+ String pathname = "" ;
225+ }
226+
227+ static int nextValueIdx (String line , int from ) {
228+ int limit = line .length () - 1 ;
229+ while (from < limit && line .charAt (++from ) == ' ' ) {}
230+ if (from == limit ) {
231+ return -1 ;
232+ }
233+ int next = line .indexOf (' ' , from + 1 );
234+ return next == -1 ? limit + 1 : next ;
235+ }
236+
237+ static long nextLongValue (String line , int [] position ) {
238+ int from = position [0 ];
239+ int limit = line .length () - 1 ;
240+ while (from < limit && line .charAt (++from ) == ' ' ) {}
241+ if (from == limit ) {
242+ position [0 ] = -1 ;
243+ return -1 ;
244+ }
245+ long val = 0 ;
246+ while (from < limit && line .charAt (++from ) != ' ' ) {
247+ char c = line .charAt (from );
248+ if (c < '0' || c > '9' ) {
249+ position [0 ] = -1 ;
250+ return -1 ;
251+ }
252+ val = val * 10 + (c - '0' );
253+ }
254+ position [0 ] = from + 1 ;
255+ return val ;
256+ }
257+
133258 @ SuppressForbidden // split with one-char String use a fast-path without regex usage
134259 static List <? extends Event > collectEvents () {
135260 if (!SMAP_ENTRY_EVENT .isEnabled ()) {
@@ -178,7 +303,7 @@ static List<? extends Event> collectEvents() {
178303 while (scanner .hasNextLine ()) {
179304 boolean encounteredForeignKeys = false ;
180305 String [] addresses = scanner .next ().split ("-" );
181- if (!addresses [0 ].equals (VSYSCALL_START_ADDRESS )) {
306+ if (!addresses [0 ].equals (VSYSCALL_START_ADDRESS_STR )) {
182307 startAddress = Long .parseLong (addresses [0 ], 16 );
183308 endAddress = Long .parseLong (addresses [1 ], 16 );
184309 } else {
@@ -347,7 +472,7 @@ static List<? extends Event> collectEvents() {
347472 nmtCategory ));
348473 }
349474 return events ;
350- } catch (FileNotFoundException e ) {
475+ } catch (IOException e ) {
351476 return List .of (new SmapParseErrorEvent (ErrorReason .SMAP_FILE_NOT_FOUND ));
352477 } catch (Exception e ) {
353478 return List .of (new SmapParseErrorEvent (ErrorReason .SMAP_PARSING_ERROR ));
0 commit comments