|
1 | 1 | package com.semmle.js.parser; |
2 | 2 |
|
3 | | -import ch.qos.logback.classic.Level; |
| 3 | +import java.io.BufferedReader; |
| 4 | +import java.io.BufferedWriter; |
| 5 | +import java.io.ByteArrayOutputStream; |
| 6 | +import java.io.Closeable; |
| 7 | +import java.io.File; |
| 8 | +import java.io.IOException; |
| 9 | +import java.io.InputStream; |
| 10 | +import java.io.InputStreamReader; |
| 11 | +import java.io.OutputStream; |
| 12 | +import java.io.OutputStreamWriter; |
| 13 | +import java.lang.ProcessBuilder.Redirect; |
| 14 | +import java.util.ArrayList; |
| 15 | +import java.util.Arrays; |
| 16 | +import java.util.Collections; |
| 17 | +import java.util.List; |
| 18 | + |
4 | 19 | import com.google.gson.JsonArray; |
5 | 20 | import com.google.gson.JsonElement; |
6 | 21 | import com.google.gson.JsonObject; |
|
21 | 36 | import com.semmle.util.process.AbstractProcessBuilder; |
22 | 37 | import com.semmle.util.process.Builder; |
23 | 38 | import com.semmle.util.process.Env; |
24 | | -import java.io.BufferedReader; |
25 | | -import java.io.BufferedWriter; |
26 | | -import java.io.ByteArrayOutputStream; |
27 | | -import java.io.Closeable; |
28 | | -import java.io.File; |
29 | | -import java.io.IOException; |
30 | | -import java.io.InputStream; |
31 | | -import java.io.InputStreamReader; |
32 | | -import java.io.OutputStream; |
33 | | -import java.io.OutputStreamWriter; |
34 | | -import java.lang.ProcessBuilder.Redirect; |
35 | | -import java.util.ArrayList; |
36 | | -import java.util.Arrays; |
37 | | -import java.util.Collections; |
38 | | -import java.util.List; |
| 39 | + |
| 40 | +import ch.qos.logback.classic.Level; |
39 | 41 |
|
40 | 42 | /** |
41 | 43 | * The Java half of our wrapper for invoking the TypeScript parser. |
@@ -98,6 +100,13 @@ public class TypeScriptParser { |
98 | 100 | */ |
99 | 101 | public static final String TYPESCRIPT_RAM_RESERVE_SUFFIX = "TYPESCRIPT_RAM_RESERVE"; |
100 | 102 |
|
| 103 | + /** |
| 104 | + * An environment variable with additional VM arguments to pass to the Node process. |
| 105 | + * <p> |
| 106 | + * Only <code>--inspect</code> or <code>--inspect-brk</code> may be used at the moment. |
| 107 | + */ |
| 108 | + public static final String TYPESCRIPT_NODE_FLAGS = "SEMMLE_TYPESCRIPT_NODE_FLAGS"; |
| 109 | + |
101 | 110 | /** The Node.js parser wrapper process, if it has been started already. */ |
102 | 111 | private Process parserWrapperProcess; |
103 | 112 |
|
@@ -236,11 +245,24 @@ private void setupParserWrapper() { |
236 | 245 | int reserveMemoryMb = getMegabyteCountFromPrefixedEnv(TYPESCRIPT_RAM_RESERVE_SUFFIX, 400); |
237 | 246 |
|
238 | 247 | File parserWrapper = getParserWrapper(); |
239 | | - |
240 | | - List<String> cmd = getNodeJsRuntimeInvocation( |
241 | | - "--max_old_space_size=" + (mainMemoryMb + reserveMemoryMb), |
242 | | - parserWrapper.getAbsolutePath() |
243 | | - ); |
| 248 | + |
| 249 | + String debugFlagString = Env.systemEnv().getNonEmpty(TYPESCRIPT_NODE_FLAGS); |
| 250 | + List<String> debugFlags = new ArrayList<>(); |
| 251 | + if (debugFlagString != null) { |
| 252 | + for (String flag : debugFlagString.split(" ")) { |
| 253 | + if (!flag.startsWith("--inspect") || flag.contains(":")) { |
| 254 | + System.err.println("Ignoring unrecognized Node flag: '" + flag + "'"); |
| 255 | + } else { |
| 256 | + debugFlags.add(flag); |
| 257 | + } |
| 258 | + } |
| 259 | + } |
| 260 | + |
| 261 | + List<String> cmd = getNodeJsRuntimeInvocation(); |
| 262 | + cmd.add("--max_old_space_size=" + (mainMemoryMb + reserveMemoryMb)); |
| 263 | + cmd.addAll(debugFlags); |
| 264 | + cmd.add(parserWrapper.getAbsolutePath()); |
| 265 | + |
244 | 266 | ProcessBuilder pb = new ProcessBuilder(cmd); |
245 | 267 | parserWrapperCommand = StringUtil.glue(" ", cmd); |
246 | 268 | pb.environment().put("SEMMLE_TYPESCRIPT_MEMORY_THRESHOLD", "" + mainMemoryMb); |
|
0 commit comments