简体   繁体   中英

How can I find where the print called?

I'm working on an old java application project using IntelliJ, the source code is huge. One class has a method which prints the info of video per frame while playing. I want to disable this code for printing but I have no idea where does it come from or what the class name is. It didn't show up when I searched the string directly. Is there a cleverer way to find where the print called?

(From comments):

Output line is [isDeveloper true]------ get duration(=3.552653) is test impl ------

Replace System.out with your own PrintStream , using System.setOut() , have it match the (un-)desired output, put a break-point on the match clause, and look at the stack trace.


Since PrintStream has many, many methods, instead of overwriting all of the possible methods that may be called when generating the (un-)desired output, let's direct all the PrintStream output to a FilterOutputStream of our own devising; then we should only have to overwrite one method, but we will need to reconstruct our string.

Example:

class Prospector extends FilterOutputStream {

    int count = 0;

    private OutputStream original;

    public Prospector(OutputStream out) {
        super(out);
        original = out;
    }

    @Override
    public void write(byte[] b, int off, int len) throws IOException {
        String buffer = new String(b, off, len, StandardCharsets.ISO_8859_1);
        if (buffer.contains("]------ get duration(=")) {
            if (count == 0) {
                new Exception().printStackTrace(original);
            }
            count++;  // Set breakpoint here
        }
        super.write(b, off, len);
    }
}

When the program starts, install a new PrintStream wrapping the original in our Prospector :

System.setOut(new PrintStream(new Prospector(System.out)));

Set a breakpoint on the indicated line. When the program stops at the breakpoint, look up the stack trace to find the class/method which generates the output.

When the mystery class generates your target line, which may be like ...

System.out.format("[%s %s]------ get duration(=%f) is %s -------%n",
    "isDeveloper", "true", 3.552653, "test impl");

... this method may be called multiple times, with buffer contain the individual parts of the line, in succession. In the above case, this would be:

  • "["
  • "isDeveloper"
  • " "
  • "true"
  • "]------ get duration(="
  • "3.552653"
  • ") is "
  • "test impl"
  • " -------"
  • "\\n"

Ideally, ]------ get duration(= should be unique enough to find the class/method you are looking for, but you can adapt as needed.

It is also possible that the entire text is formatted into a single String , and printed out in one call. This is why .contains(...) is used to match the required output.

i think

Pressing Ctrl+ Mouse click on required variable or method

acts as a hyperlink to source

should do the trick(on IntelliJ)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM