btrace icon indicating copy to clipboard operation
btrace copied to clipboard

Is adding method printStrings with a ... array possible?

Open joachimhs opened this issue 2 years ago • 3 comments

Hello,

I was trying to add a method in BTraceUtils called printStrings that would take a ... array as input and format it with a prefix, suffix and delimiter.

However, this does not work because the agent is throwing an exception that creating arrays in the BTrace script is not allowed.

Does Java know the difference between creating an array with the new keyword, and with method overloading? Would it be possible to allow it if it is through a method in BTraceUtils?

Below is the method I was thinking about adding the BTraceUtils:

` /** Prints the elements of the given array as comma separated line bounded by prefix and suffix, and separated with delimiter'. */ public static void printStrings(String prefix, String suffix, String delimeter, String ... strings) { StringBuilder buf = new StringBuilder(); if (prefix != null && prefix.length() > 0) { buf.append(prefix); }

  for (String str : strings) {
    buf.append(str);
    buf.append(delimeter);
  }
  if (suffix != null && suffix.length() > 0) {
    buf.append(suffix);
  }
  println(buf.toString());
}`

joachimhs avatar Sep 09 '22 19:09 joachimhs

You could indeed use a static method to create a new array and then pass it to a method. However, the array creation is 'forbidden' for a reason - it may increase the allocation rate of the app significantly and one could allocate huge arrays, bringing down the traced app. While it is not really possible to avoid the first problem, you could have a hard limit for the array size in lower hundreds to prevent intentional or unintentionally OOME-ing the traced app.

jbachorik avatar Sep 09 '22 21:09 jbachorik

I do not think there is a possibility to limit the number of items in a parameter that is a vararg. The goals was to simplify printing out a more complex structure, without having to rely on Appendable in the BTrace script file.

joachimhs avatar Sep 10 '22 06:09 joachimhs

Does Java know the difference between creating an array with the new keyword, and with method overloading? Would it be possible to allow it if it is through a method in BTraceUtils?

Actually, this is the sole reason - it is not possible to distinguish between varargs array and a 'normal', user instantiated array. The annotation processor BTrace is using to validate the scripts also can not be used to somehow 'mark' the varargs array instantiation - the processor can not really change the shape of the bytecode generated by javac. At best it can create some extra files - and this would require a 'post-processing' step which would take the bytecode and the extra files as input and merge them. This seems to be doable as BTrace compiler is already generating the pack file which is containing 'enhanced' bytecode so we could, somehow, distinguish between the varargs creation and array instantiation.

But, TBH, this is a rather large undertaking for which I currently don't have neither time nor incentive to do. However, as always, any contributions are very welcomed and I will gladly help with providing advice on BTrace internal to whoever would decide to pick this up. Actually, creating a generic mechanims where we could actually modify the bytecode shape using the extra info from the annotation processor pass could turn out to be pretty useful for the potential future BTrace verifier improvements (making it smarter, denying things at much finer granularity as it is doing now etc.)

jbachorik avatar Oct 02 '22 19:10 jbachorik

Stale issue message

github-actions[bot] avatar Dec 02 '22 00:12 github-actions[bot]