簡體   English   中英

IntelliJ IDEA中的調試超時

[英]Debugging timeouts in IntelliJ IDEA

在我的應用程序中,如果不確定是否可以在合理的時間內滿足條件,我將使用超時退出某些無限循環。

為了計時,我使用系統的時間,因為它很簡單:

public class BenchmarkTimer
{
    private long startTime;

    public BenchmarkTimer()
    {
        startTime = System.currentTimeMillis();
    }

    public boolean isExpired(long milliseconds)
    {
        long executionTime = currentTimeMillis() - startTime;
        return executionTime > milliseconds;
    }
}

但是,在調試時,我不希望在凍結應用程序時繼續花費時間。 默認情況下,這顯然不起作用,因為即使在斷點期間,系統時間也將繼續。 我不想由於我在斷點上花費太長時間而無法繼續運行而導致超時,因為在正常的應用程序執行下,這種行為會有所不同(例如,在“放棄”之前將執行更多的嘗試)。

有什么解決辦法嗎? IntelliJ IDEA可以僅在斷點期間暫停Java應用程序可見的系統時間嗎? 我希望調試的行為像包含超時的常規執行,所以我不確定一般如何完成此操作。

評論的鏈接給了我一個正確的主意:運行一個線程,該線程會不斷檢查Thread.sleep()睡眠時間是否足夠短,否則事情會變得很糟糕,我們可能處於斷點,因此我們可以“確定”時間,再次請求系統時間時,返回較舊的時間。

import lombok.val;

import static com.mycompany.SystemTimeBreakpointFixer.getCurrentTimeMillis;
import static com.mycompany.SystemTimeBreakpointFixer.considerRunningTimerFixerThread;
import static java.lang.System.currentTimeMillis;
import static java.lang.management.ManagementFactory.getRuntimeMXBean;

public class BenchmarkTimer
{
    private long startTime;

    static
    {
        considerRunningTimerFixerThread();
    }

    public BenchmarkTimer()
    {
        startTime = getCurrentTimeMillis();
    }

    public boolean isExpired(long milliseconds)
    {
        val currentTimeMillis = getCurrentTimeMillis();
        val executionTime = currentTimeMillis - startTime;
        return executionTime > milliseconds;
    }

    static class SystemTimeBreakpointFixer
    {
        private static final String THREAD_NAME = "System Time Fixer";
        private static final int CHECKING_DELAY = 100;
        private static final int NON_BREAKPOINT_DELAY = 100;
        private static final String DEBUGGING_INPUT_ARGUMENT = "-agentlib:jdwp";
        private static final boolean ARE_WE_DEBUGGING;

        static
        {
            ARE_WE_DEBUGGING = areWeDebugging();
        }

        private static boolean areWeDebugging()
        {
            val runtimeMXBean = getRuntimeMXBean();
            val inputArguments = runtimeMXBean.getInputArguments();
            val jvmArguments = inputArguments.toString();
            return jvmArguments.contains(DEBUGGING_INPUT_ARGUMENT);
        }

        private static long totalPausedTime = 0;
        private static Thread thread;

        static long getCurrentTimeMillis()
        {
            sleepThread();
            val currentTimeMillis = currentTimeMillis();
            return currentTimeMillis - totalPausedTime;
        }

        static void considerRunningTimerFixerThread()
        {
            if (ARE_WE_DEBUGGING && thread == null)
            {
                startTimerFixerThread();
            }
        }

        private static void startTimerFixerThread()
        {
            thread = new Thread(() ->
            {
                //noinspection InfiniteLoopStatement
                while (true)
                {
                    val currentMilliseconds = currentTimeMillis();
                    sleepThread();
                    val updatedMilliseconds = currentTimeMillis();
                    val currentPausedTime = updatedMilliseconds - currentMilliseconds - CHECKING_DELAY;
                    if (currentPausedTime > NON_BREAKPOINT_DELAY)
                    {
                        totalPausedTime += currentPausedTime;
                    }
                }
            });

            thread.setName(THREAD_NAME);
            thread.start();
        }

        private static void sleepThread()
        {
            try
            {
                Thread.sleep(CHECKING_DELAY);
            } catch (InterruptedException exception)
            {
                exception.printStackTrace();
            }
        }
    }
}

還稱贊到文章的調試檢測。

在isExpired內部使用一個斷點,並在返回值中進行設置:

  • 設置“評估並記錄”表達式,例如executionTime = 0
  • 未設定“暫停”

現在處於調試模式,它將修改執行時間,以便isExpired始終返回false

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM