Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why my object has been changed by IntelliJ IDEA's debugger soundlessly?

I'm debug(Shift + F9) the method offer(E e) of JDK8 API's java.util.concurrent.ConcurrentLinkedQueue,

i found IntelliJ IDEA will change the field head of this queue soundlessly in the process of debugging,

but the run schema(Shift + F10) will not change the field, why?

and there's no code change this field in offer(E e), it makes me confused.

Then, I tried another IDE(Eclipse Mars.1 Release (4.5.1)), it hasn't such problem.

There are some result of my test:

  • run schema (Shift + F10)
head: 1159190947 
head: 1159190947 
head: 1159190947 
head: 1159190947 
  • debug schema (Step over: F8)
head: 1989972246 
head: 1791930789 
head: 1791930789 
head: 1791930789 
  • debug schema (Resume program: F9)
head: 1989972246 
head: 1989972246 
head: 1791930789 
head: 1791930789 

version info :
IntelliJ IDEA 2018.1 (Ultimate Edition)
Build #IU-181.4203.550, built on March 27, 2018
JRE: 1.8.0_162-b12 amd64
JVM: Java HotSpot(TM) 64-Bit Server VM by Oracle Corporation
Windows 10 10.0

And IntelliJ IDEA 2018.2.3 (Community Edition) & IntelliJ IDEA 2019.1 (Ultimate Edition) has the same problem.

import java.lang.reflect.Field;
import java.util.concurrent.ConcurrentLinkedQueue;

public class ConcurrentLinkedQueueTest {

    public static void main(String[] args) {
        ConcurrentLinkedQueue<String> queue = new ConcurrentLinkedQueue<>();
        print(queue);
        queue.offer("aaa");
        print(queue);
        queue.offer("bbb");
        print(queue);
        queue.offer("ccc");
        print(queue);
    }

    /**
     * 打印并发队列head属性的identityHashCode
     * @param queue
     */
    private static void print(ConcurrentLinkedQueue queue) {
        Field field = null;
        boolean isAccessible = false;
        try {
            field = ConcurrentLinkedQueue.class.getDeclaredField("head");
            isAccessible = field.isAccessible();
            if (!isAccessible) {
                field.setAccessible(true);
            }
            System.out.println("head: " + System.identityHashCode(field.get(queue)));
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            field.setAccessible(isAccessible);
        }
    }
}
like image 338
hiccup Avatar asked Apr 28 '19 10:04

hiccup


People also ask

How do I get out of debug mode in IntelliJ?

Click the Stop button in the Debug tool window. Alternatively, press Ctrl+F2 and select the process to terminate (if there are two or more of them).

Why debugger is not working in IntelliJ?

To solve this, simply remove the jar of the debugged module from all modules' dependencies in the Project Structure. If you do not know which modules have the debugged module jar as dependencies, you can use some tools (Eg. Sublime Text, bash, ...) to search for the module name which is stored in Intellij *.

How does debugger in IntelliJ work?

During a debugging session, you launch your program with the debugger attached to it. The purpose of the debugger is to interfere with the program execution and provide you with the information on what's happening under the hood. This facilitates the process of detecting and fixing bugs in your program.

How do I change the debug value in IntelliJ?

Select a variable or a property of a complex object in the Debug window, press F2 or right-click and choose Set Value... from the context menu, and then specify a new value and press Enter .

Can IntelliJ IDEA debug Java code?

IntelliJ IDEA provides a debugger for Java code. Depending on the installed/enabled plugins, you can also debug code written in other languages. During a debugging session, you launch your program with the debugger attached to it.

How do I view changes made to a file in IntelliJ?

IntelliJ IDEA allows you to review changes made to files or even fragments of source code. The Show History and the Show History for Selection commands are available from the main VCS menu and from the context menu of files. The change history for a file is displayed in the dedicated History tab of the Version Control tool window Alt+9.

How to view the value of variable during debugging in IntelliJ?

During debugging, IntelliJ shows value of variable in the Editor window itself. We can also view the same information in the Debug window. Evaluate expression allows to evaluate expression on the fly. Follow these steps to perform this action −

What is the difference between breakpoint and debug in IntelliJ?

Debugger makes application debugging much easier. Using debugger, we can stop the execution of program at a certain point, inspect variables, step into function and do many things. IntelliJ provides inbuilt Java debugger. Breakpoint allows stopping program execution at certain point.


1 Answers

By default, IntelliJ IDEA invokes the toString() method on objects to obtain their presentation in the Watches view. In ConcurrentLinkedQueue, the toString() method iterates over the collection, which can update the head field via the updateHead() call in the first() method (and possibly in other places, I haven't investigated the entire implementation.

If you go to Preferences | Build, Execution, Deployment | Debugger | Data Views | Java and turn off "Enable toString() object view", you should no longer observe this behavior.

like image 70
yole Avatar answered Oct 05 '22 23:10

yole