I grabbed the stack frames of all threads using jcmd pid Thread.print
on the production server to troubleshoot the problem, but found that one of the methods had a clearly incorrect line number, so I grabbed a heap dump using the internal diagnostic tool, And the line number in the thread stack frame in the heap dump is correct, because it is a commercial application, so I can't provide all the source code, I want to know the reason why jcmd
returns the wrong line number. I checked the relevant underlying implementations, and it seems that they all use bci to query the corresponding line number in LineNumberTable.
Stack frame returned by jcmd
, sensitive information is replaced by *
:
"myScheduler-7" #131 prio=5 os_prio=0 tid=0x00007ffb039df000 nid=0x91 waiting on condition [0x00007ffae9364000]
java.lang.Thread.State: WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x00000006d3406010> (a java.util.concurrent.CountDownLatch$Sync)
at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(AbstractQueuedSynchronizer.java:836)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.doAcquireSharedInterruptibly(AbstractQueuedSynchronizer.java:997)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireSharedInterruptibly(AbstractQueuedSynchronizer.java:1304)
at java.util.concurrent.CountDownLatch.await(CountDownLatch.java:231)
at ***.*****.***.service.impl.ScheduledServiceImpl.analyze*****(ScheduledServiceImpl.java:546)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:84)
at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54)
at org.springframework.scheduling.concurrent.ReschedulingRunnable.run(ReschedulingRunnable.java:95)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:180)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
In this stack frame, ScheduledServiceImpl
has line number 546, which is clearly incorrect.
Stack frame returned by internal diagnostic tool, heap dump is generated by the following command: ManagementFactory.getPlatformMXBean(HotSpotDiagnosticMXBean.class).dumpHeap(dumpFilePath, true)
, sensitive information is mosaicked:
In this stack frame, ScheduledServiceImpl
has line number 559, which is correct.
JDK version: Oracle JDK 1.8.0_291
OS: Linux 4.15.0-139-generic #143-Ubuntu SMP Tue Mar 16 01:30:17 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux
Reference: