当前位置:   article > 正文

linux PerfCollect收集日志及perfview分析_linux perfview

linux perfview

Perfview:https://github.com/Microsoft/perfview/releases
PerfCollect:https://github.com/dotnet/coreclr/blob/master/Documentation/project-docs/linux-performance-tracing.md

Linux 环境中运行的 ASP.NET Core应用中收集跟踪
PerfCollect(https://github.com/dotnet/coreclr/blob/master/Documentation/project-docs/linux-performance-tracing.md) 是一个 bash 脚本,它使用本机 Linux 分析工具(Perf 和 LTTng)收集 Linux 上的跟踪信息,以便 PerfView 进行分析

  1. #Download Perfcollect.
  2. curl -OL http://aka.ms/perfcollect (网络原因,因此下载存为文件名:/root/perfcollect)
  3. #Make the script executable.
  4. chmod +x ./perfcollect
  5. #Install tracing prerequisites - these are the actual tracing libraries. For details on prerequisites, see below.
  6. sudo ./perfcollect install
  7. ##Collecting a Trace
  8. #[App] Setup the application shell - this enables tracing configuration inside of CoreCLR.
  9. export COMPlus_PerfMapEnabled=1
  10. export COMPlus_EnableEventLog=1
  11. #[Trace] Start collection.
  12. sudo ./perfcollect collect trace_202306082203

运行效果:


perfcollect文件内容如下:

  1. #!/bin/bash
  2. #############################################################################################################
  3. # .NET Performance Data Collection Script
  4. #############################################################################################################
  5. #############################################################################################################
  6. #
  7. # ***** HOW TO USE THIS SCRIPT *****
  8. #
  9. # This script can be used to collect and view performance data collected with perf_event on Linux.
  10. # It's job is to make it simple to collect performance traces.
  11. #
  12. # How to collect a performance trace:
  13. # 1. Prior to starting the .NET process, set the environment variable COMPlus_PerfMapEnabled=1.
  14. # This tells the runtime to emit information that enables perf_event to resolve JIT-compiled code symbols.
  15. #
  16. # 2. Setup your system to reproduce the performance issue you'd like to capture. Data collection can be
  17. # started on already running processes.
  18. #
  19. # 3. [Usage #1] use "collect" command
  20. # - Run this script: sudo ./perfcollect collect samplePerfTrace. This will start data collection.
  21. # - Let the repro run as long as you need to capture the performance problem.
  22. # - Hit CTRL+C to stop collection.
  23. #
  24. # [Usage #2] use "start" and "stop" command
  25. # - Run this script: sudo ./perfcollect start samplePerfTrace. This will start data colletion.
  26. # - Let the repro run as long as you need to capture the performance problem.
  27. # - Run: sudo ./perfcollect stop samplePerfTrace. This will stop collection.
  28. #
  29. # 4. When collection is stopped, the script will create a trace.zip file matching the name specified on the
  30. # command line. This file will contain the trace, JIT-compiled symbol information, and all debugging
  31. # symbols for binaries referenced by this trace that were available on the machine at collection time.
  32. #
  33. # How to view a performance trace:
  34. # 1. Run this script: ./perfcollect view samplePerfTrace.trace.zip
  35. # This will extract the trace, place and register all symbol files and JIT-compiled symbol information
  36. # and start the perf_event viewer. By default, you will be looking at a callee view - stacks are ordered
  37. # top down. For a caller or bottom up view, specify '-graphtype caller'.
  38. #############################################################################################################
  39. ######################################
  40. ## FOR DEBUGGING ONLY
  41. ######################################
  42. # set -x
  43. ######################################
  44. ## Collection Options
  45. ## NOTE: These values represent the collection defaults.
  46. ######################################
  47. # Set when we parse command line arguments to determine if we should enable specific collection options.
  48. collect_cpu=1
  49. collect_threadTime=0
  50. collect_offcpu=0
  51. collect_system=0
  52. ######################################
  53. ## .NET Event Categories
  54. ######################################
  55. # Separate GCCollectOnly list because our LTTng implementation doesn't set tracepoint verbosity.
  56. # Once tracepoint verbosity is set, we can set verbosity and collapse this with DotNETRuntime_GCKeyword.
  57. declare -a DotNETRuntime_GCKeyword_GCCollectOnly=(
  58. DotNETRuntime:GCStart
  59. DotNETRuntime:GCStart_V1
  60. DotNETRuntime:GCStart_V2
  61. DotNETRuntime:GCEnd
  62. DotNETRuntime:GCEnd_V1
  63. DotNETRuntime:GCRestartEEEnd
  64. DotNETRuntime:GCRestartEEEnd_V1
  65. DotNETRuntime:GCHeapStats
  66. DotNETRuntime:GCHeapStats_V1
  67. DotNETRuntime:GCCreateSegment
  68. DotNETRuntime:GCCreateSegment_V1
  69. DotNETRuntime:GCFreeSegment
  70. DotNETRuntime:GCFreeSegment_V1
  71. DotNETRuntime:GCRestartEEBegin
  72. DotNETRuntime:GCRestartEEBegin_V1
  73. DotNETRuntime:GCSuspendEEEnd
  74. DotNETRuntime:GCSuspendEEEnd_V1
  75. DotNETRuntime:GCSuspendEEBegin
  76. DotNETRuntime:GCSuspendEEBegin_V1
  77. DotNETRuntime:GCCreateConcurrentThread
  78. DotNETRuntime:GCTerminateConcurrentThread
  79. DotNETRuntime:GCFinalizersEnd
  80. DotNETRuntime:GCFinalizersEnd_V1
  81. DotNETRuntime:GCFinalizersBegin
  82. DotNETRuntime:GCFinalizersBegin_V1
  83. DotNETRuntime:GCMarkStackRoots
  84. DotNETRuntime:GCMarkFinalizeQueueRoots
  85. DotNETRuntime:GCMarkHandles
  86. DotNETRuntime:GCMarkOlderGenerationRoots
  87. DotNETRuntime:FinalizeObject
  88. DotNETRuntime:GCTriggered
  89. DotNETRuntime:IncreaseMemoryPressure
  90. DotNETRuntime:DecreaseMemoryPressure
  91. DotNETRuntime:GCMarkWithType
  92. DotNETRuntime:GCPerHeapHistory_V3
  93. DotNETRuntime:GCGlobalHeapHistory_V2
  94. DotNETRuntime:GCCreateConcurrentThread_V1
  95. DotNETRuntime:GCTerminateConcurrentThread_V1
  96. )
  97. declare -a DotNETRuntime_GCKeyword=(
  98. DotNETRuntime:GCStart
  99. DotNETRuntime:GCStart_V1
  100. DotNETRuntime:GCStart_V2
  101. DotNETRuntime:GCEnd
  102. DotNETRuntime:GCEnd_V1
  103. DotNETRuntime:GCRestartEEEnd
  104. DotNETRuntime:GCRestartEEEnd_V1
  105. DotNETRuntime:GCHeapStats
  106. DotNETRuntime:GCHeapStats_V1
  107. DotNETRuntime:GCCreateSegment
  108. DotNETRuntime:GCCreateSegment_V1
  109. DotNETRuntime:GCFreeSegment
  110. DotNETRuntime:GCFreeSegment_V1
  111. DotNETRuntime:GCRestartEEBegin
  112. DotNETRuntime:GCRestartEEBegin_V1
  113. DotNETRuntime:GCSuspendEEEnd
  114. DotNETRuntime:GCSuspendEEEnd_V1
  115. DotNETRuntime:GCSuspendEEBegin
  116. DotNETRuntime:GCSuspendEEBegin_V1
  117. DotNETRuntime:GCAllocationTick
  118. DotNETRuntime:GCAllocationTick_V1
  119. DotNETRuntime:GCAllocationTick_V2
  120. DotNETRuntime:GCAllocationTick_V3
  121. DotNETRuntime:GCCreateConcurrentThread
  122. DotNETRuntime:GCTerminateConcurrentThread
  123. DotNETRuntime:GCFinalizersEnd
  124. DotNETRuntime:GCFinalizersEnd_V1
  125. DotNETRuntime:GCFinalizersBegin
  126. DotNETRuntime:GCFinalizersBegin_V1
  127. DotNETRuntime:GCMarkStackRoots
  128. DotNETRuntime:GCMarkFinalizeQueueRoots
  129. DotNETRuntime:GCMarkHandles
  130. DotNETRuntime:GCMarkOlderGenerationRoots
  131. DotNETRuntime:FinalizeObject
  132. DotNETRuntime:PinObjectAtGCTime
  133. DotNETRuntime:GCTriggered
  134. DotNETRuntime:IncreaseMemoryPressure
  135. DotNETRuntime:DecreaseMemoryPressure
  136. DotNETRuntime:GCMarkWithType
  137. DotNETRuntime:GCJoin_V2
  138. DotNETRuntime:GCPerHeapHistory_V3
  139. DotNETRuntime:GCGlobalHeapHistory_V2
  140. DotNETRuntime:GCCreateConcurrentThread_V1
  141. DotNETRuntime:GCTerminateConcurrentThread_V1
  142. )
  143. declare -a DotNETRuntime_TypeKeyword=(
  144. DotNETRuntime:BulkType
  145. )
  146. declare -a DotNETRuntime_GCHeapDumpKeyword=(
  147. DotNETRuntime:GCBulkRootEdge
  148. DotNETRuntime:GCBulkRootConditionalWeakTableElementEdge
  149. DotNETRuntime:GCBulkNode
  150. DotNETRuntime:GCBulkEdge
  151. DotNETRuntime:GCBulkRootCCW
  152. DotNETRuntime:GCBulkRCW
  153. DotNETRuntime:GCBulkRootStaticVar
  154. )
  155. declare -a DotNETRuntime_GCSampledObjectAllocationHighKeyword=(
  156. DotNETRuntime:GCSampledObjectAllocationHigh
  157. )
  158. declare -a DotNETRuntime_GCHeapSurvivalAndMovementKeyword=(
  159. DotNETRuntime:GCBulkSurvivingObjectRanges
  160. DotNETRuntime:GCBulkMovedObjectRanges
  161. DotNETRuntime:GCGenerationRange
  162. )
  163. declare -a DotNETRuntime_GCHandleKeyword=(
  164. DotNETRuntime:SetGCHandle
  165. DotNETRuntime:DestroyGCHandle
  166. )
  167. declare -a DotNETRuntime_GCSampledObjectAllocationLowKeyword=(
  168. DotNETRuntime:GCSampledObjectAllocationLow
  169. )
  170. declare -a DotNETRuntime_ThreadingKeyword=(
  171. DotNETRuntime:WorkerThreadCreate
  172. DotNETRuntime:WorkerThreadTerminate
  173. DotNETRuntime:WorkerThreadRetire
  174. DotNETRuntime:WorkerThreadUnretire
  175. DotNETRuntime:IOThreadCreate
  176. DotNETRuntime:IOThreadCreate_V1
  177. DotNETRuntime:IOThreadTerminate
  178. DotNETRuntime:IOThreadTerminate_V1
  179. DotNETRuntime:IOThreadRetire
  180. DotNETRuntime:IOThreadRetire_V1
  181. DotNETRuntime:IOThreadUnretire
  182. DotNETRuntime:IOThreadUnretire_V1
  183. DotNETRuntime:ThreadpoolSuspensionSuspendThread
  184. DotNETRuntime:ThreadpoolSuspensionResumeThread
  185. DotNETRuntime:ThreadPoolWorkerThreadStart
  186. DotNETRuntime:ThreadPoolWorkerThreadStop
  187. DotNETRuntime:ThreadPoolWorkerThreadRetirementStart
  188. DotNETRuntime:ThreadPoolWorkerThreadRetirementStop
  189. DotNETRuntime:ThreadPoolWorkerThreadAdjustmentSample
  190. DotNETRuntime:ThreadPoolWorkerThreadAdjustmentAdjustment
  191. DotNETRuntime:ThreadPoolWorkerThreadAdjustmentStats
  192. DotNETRuntime:ThreadPoolWorkerThreadWait
  193. DotNETRuntime:ThreadPoolWorkingThreadCount
  194. DotNETRuntime:ThreadPoolIOPack
  195. DotNETRuntime:GCCreateConcurrentThread_V1
  196. DotNETRuntime:GCTerminateConcurrentThread_V1
  197. )
  198. declare -a DotNETRuntime_ThreadingKeyword_ThreadTransferKeyword=(
  199. DotNETRuntime:ThreadPoolEnqueue
  200. DotNETRuntime:ThreadPoolDequeue
  201. DotNETRuntime:ThreadPoolIOEnqueue
  202. DotNETRuntime:ThreadPoolIODequeue
  203. DotNETRuntime:ThreadCreating
  204. DotNETRuntime:ThreadRunning
  205. )
  206. declare -a DotNETRuntime_NoKeyword=(
  207. DotNETRuntime:ExceptionThrown
  208. DotNETRuntime:Contention
  209. DotNETRuntime:RuntimeInformationStart
  210. DotNETRuntime:EventSource
  211. )
  212. declare -a DotNETRuntime_ExceptionKeyword=(
  213. DotNETRuntime:ExceptionThrown_V1
  214. DotNETRuntime:ExceptionCatchStart
  215. DotNETRuntime:ExceptionCatchStop
  216. DotNETRuntime:ExceptionFinallyStart
  217. DotNETRuntime:ExceptionFinallyStop
  218. DotNETRuntime:ExceptionFilterStart
  219. DotNETRuntime:ExceptionFilterStop
  220. DotNETRuntime:ExceptionThrownStop
  221. )
  222. declare -a DotNETRuntime_ContentionKeyword=(
  223. DotNETRuntime:ContentionStart_V1
  224. DotNETRuntime:ContentionStop
  225. DotNETRuntime:ContentionStop_V1
  226. )
  227. declare -a DotNETRuntime_StackKeyword=(
  228. DotNETRuntime:CLRStackWalk
  229. )
  230. declare -a DotNETRuntime_AppDomainResourceManagementKeyword=(
  231. DotNETRuntime:AppDomainMemAllocated
  232. DotNETRuntime:AppDomainMemSurvived
  233. )
  234. declare -a DotNETRuntime_AppDomainResourceManagementKeyword_ThreadingKeyword=(
  235. DotNETRuntime:ThreadCreated
  236. DotNETRuntime:ThreadTerminated
  237. DotNETRuntime:ThreadDomainEnter
  238. )
  239. declare -a DotNETRuntime_InteropKeyword=(
  240. DotNETRuntime:ILStubGenerated
  241. DotNETRuntime:ILStubCacheHit
  242. )
  243. declare -a DotNETRuntime_JitKeyword_NGenKeyword=(
  244. DotNETRuntime:DCStartCompleteV2
  245. DotNETRuntime:DCEndCompleteV2
  246. DotNETRuntime:MethodDCStartV2
  247. DotNETRuntime:MethodDCEndV2
  248. DotNETRuntime:MethodDCStartVerboseV2
  249. DotNETRuntime:MethodDCEndVerboseV2
  250. DotNETRuntime:MethodLoad
  251. DotNETRuntime:MethodLoad_V1
  252. DotNETRuntime:MethodLoad_V2
  253. DotNETRuntime:MethodUnload
  254. DotNETRuntime:MethodUnload_V1
  255. DotNETRuntime:MethodUnload_V2
  256. DotNETRuntime:MethodLoadVerbose
  257. DotNETRuntime:MethodLoadVerbose_V1
  258. DotNETRuntime:MethodLoadVerbose_V2
  259. DotNETRuntime:MethodUnloadVerbose
  260. DotNETRuntime:MethodUnloadVerbose_V1
  261. DotNETRuntime:MethodUnloadVerbose_V2
  262. )
  263. declare -a DotNETRuntime_JitKeyword=(
  264. DotNETRuntime:MethodJittingStarted
  265. DotNETRuntime:MethodJittingStarted_V1
  266. )
  267. declare -a DotNETRuntime_JitTracingKeyword=(
  268. DotNETRuntime:MethodJitInliningSucceeded
  269. DotNETRuntime:MethodJitInliningFailed
  270. DotNETRuntime:MethodJitTailCallSucceeded
  271. DotNETRuntime:MethodJitTailCallFailed
  272. )
  273. declare -a DotNETRuntime_JittedMethodILToNativeMapKeyword=(
  274. DotNETRuntime:MethodILToNativeMap
  275. )
  276. declare -a DotNETRuntime_LoaderKeyword=(
  277. DotNETRuntime:ModuleDCStartV2
  278. DotNETRuntime:ModuleDCEndV2
  279. DotNETRuntime:DomainModuleLoad
  280. DotNETRuntime:DomainModuleLoad_V1
  281. DotNETRuntime:ModuleLoad
  282. DotNETRuntime:ModuleUnload
  283. DotNETRuntime:AssemblyLoad
  284. DotNETRuntime:AssemblyLoad_V1
  285. DotNETRuntime:AssemblyUnload
  286. DotNETRuntime:AssemblyUnload_V1
  287. DotNETRuntime:AppDomainLoad
  288. DotNETRuntime:AppDomainLoad_V1
  289. DotNETRuntime:AppDomainUnload
  290. DotNETRuntime:AppDomainUnload_V1
  291. )
  292. declare -a DotNETRuntime_LoaderKeyword=(
  293. DotNETRuntime:ModuleLoad_V1
  294. DotNETRuntime:ModuleLoad_V2
  295. DotNETRuntime:ModuleUnload_V1
  296. DotNETRuntime:ModuleUnload_V2
  297. )
  298. declare -a DotNETRuntime_SecurityKeyword=(
  299. DotNETRuntime:StrongNameVerificationStart
  300. DotNETRuntime:StrongNameVerificationStart_V1
  301. DotNETRuntime:StrongNameVerificationStop
  302. DotNETRuntime:StrongNameVerificationStop_V1
  303. DotNETRuntime:AuthenticodeVerificationStart
  304. DotNETRuntime:AuthenticodeVerificationStart_V1
  305. DotNETRuntime:AuthenticodeVerificationStop
  306. DotNETRuntime:AuthenticodeVerificationStop_V1
  307. )
  308. declare -a DotNETRuntime_DebuggerKeyword=(
  309. DotNETRuntime:DebugIPCEventStart
  310. DotNETRuntime:DebugIPCEventEnd
  311. DotNETRuntime:DebugExceptionProcessingStart
  312. DotNETRuntime:DebugExceptionProcessingEnd
  313. )
  314. declare -a DotNETRuntime_CodeSymbolsKeyword=(
  315. DotNETRuntime:CodeSymbols
  316. )
  317. declare -a DotNETRuntime_CompilationKeyword=(
  318. DotNETRuntime:TieredCompilationSettings
  319. DotNETRuntime:TieredCompilationPause
  320. DotNETRuntime:TieredCompilationResume
  321. DotNETRuntime:TieredCompilationBackgroundJitStart
  322. DotNETRuntime:TieredCompilationBackgroundJitStop
  323. DotNETRuntimeRundown:TieredCompilationSettingsDCStart
  324. )
  325. # Separate GCCollectOnly list because our LTTng implementation doesn't set tracepoint verbosity.
  326. # Once tracepoint verbosity is set, we can set verbosity and collapse this with DotNETRuntimePrivate_GCPrivateKeyword.
  327. declare -a DotNETRuntimePrivate_GCPrivateKeyword_GCCollectOnly=(
  328. DotNETRuntimePrivate:GCDecision
  329. DotNETRuntimePrivate:GCDecision_V1
  330. DotNETRuntimePrivate:GCSettings
  331. DotNETRuntimePrivate:GCSettings_V1
  332. DotNETRuntimePrivate:GCPerHeapHistory
  333. DotNETRuntimePrivate:GCPerHeapHistory_V1
  334. DotNETRuntimePrivate:GCGlobalHeapHistory
  335. DotNETRuntimePrivate:GCGlobalHeapHistory_V1
  336. DotNETRuntimePrivate:PrvGCMarkStackRoots
  337. DotNETRuntimePrivate:PrvGCMarkStackRoots_V1
  338. DotNETRuntimePrivate:PrvGCMarkFinalizeQueueRoots
  339. DotNETRuntimePrivate:PrvGCMarkFinalizeQueueRoots_V1
  340. DotNETRuntimePrivate:PrvGCMarkHandles
  341. DotNETRuntimePrivate:PrvGCMarkHandles_V1
  342. DotNETRuntimePrivate:PrvGCMarkCards
  343. DotNETRuntimePrivate:PrvGCMarkCards_V1
  344. DotNETRuntimePrivate:BGCBegin
  345. DotNETRuntimePrivate:BGC1stNonConEnd
  346. DotNETRuntimePrivate:BGC1stConEnd
  347. DotNETRuntimePrivate:BGC2ndNonConBegin
  348. DotNETRuntimePrivate:BGC2ndNonConEnd
  349. DotNETRuntimePrivate:BGC2ndConBegin
  350. DotNETRuntimePrivate:BGC2ndConEnd
  351. DotNETRuntimePrivate:BGCPlanEnd
  352. DotNETRuntimePrivate:BGCSweepEnd
  353. DotNETRuntimePrivate:BGCDrainMark
  354. DotNETRuntimePrivate:BGCRevisit
  355. DotNETRuntimePrivate:BGCOverflow
  356. DotNETRuntimePrivate:BGCAllocWaitBegin
  357. DotNETRuntimePrivate:BGCAllocWaitEnd
  358. DotNETRuntimePrivate:GCFullNotify
  359. DotNETRuntimePrivate:GCFullNotify_V1
  360. DotNETRuntimePrivate:PrvFinalizeObject
  361. DotNETRuntimePrivate:PinPlugAtGCTime
  362. )
  363. declare -a DotNETRuntimePrivate_GCPrivateKeyword=(
  364. DotNETRuntimePrivate:GCDecision
  365. DotNETRuntimePrivate:GCDecision_V1
  366. DotNETRuntimePrivate:GCSettings
  367. DotNETRuntimePrivate:GCSettings_V1
  368. DotNETRuntimePrivate:GCOptimized
  369. DotNETRuntimePrivate:GCOptimized_V1
  370. DotNETRuntimePrivate:GCPerHeapHistory
  371. DotNETRuntimePrivate:GCPerHeapHistory_V1
  372. DotNETRuntimePrivate:GCGlobalHeapHistory
  373. DotNETRuntimePrivate:GCGlobalHeapHistory_V1
  374. DotNETRuntimePrivate:GCJoin
  375. DotNETRuntimePrivate:GCJoin_V1
  376. DotNETRuntimePrivate:PrvGCMarkStackRoots
  377. DotNETRuntimePrivate:PrvGCMarkStackRoots_V1
  378. DotNETRuntimePrivate:PrvGCMarkFinalizeQueueRoots
  379. DotNETRuntimePrivate:PrvGCMarkFinalizeQueueRoots_V1
  380. DotNETRuntimePrivate:PrvGCMarkHandles
  381. DotNETRuntimePrivate:PrvGCMarkHandles_V1
  382. DotNETRuntimePrivate:PrvGCMarkCards
  383. DotNETRuntimePrivate:PrvGCMarkCards_V1
  384. DotNETRuntimePrivate:BGCBegin
  385. DotNETRuntimePrivate:BGC1stNonConEnd
  386. DotNETRuntimePrivate:BGC1stConEnd
  387. DotNETRuntimePrivate:BGC2ndNonConBegin
  388. DotNETRuntimePrivate:BGC2ndNonConEnd
  389. DotNETRuntimePrivate:BGC2ndConBegin
  390. DotNETRuntimePrivate:BGC2ndConEnd
  391. DotNETRuntimePrivate:BGCPlanEnd
  392. DotNETRuntimePrivate:BGCSweepEnd
  393. DotNETRuntimePrivate:BGCDrainMark
  394. DotNETRuntimePrivate:BGCRevisit
  395. DotNETRuntimePrivate:BGCOverflow
  396. DotNETRuntimePrivate:BGCAllocWaitBegin
  397. DotNETRuntimePrivate:BGCAllocWaitEnd
  398. DotNETRuntimePrivate:GCFullNotify
  399. DotNETRuntimePrivate:GCFullNotify_V1
  400. DotNETRuntimePrivate:PrvFinalizeObject
  401. DotNETRuntimePrivate:PinPlugAtGCTime
  402. )
  403. declare -a DotNETRuntimePrivate_StartupKeyword=(
  404. DotNETRuntimePrivate:EEStartupStart
  405. DotNETRuntimePrivate:EEStartupStart_V1
  406. DotNETRuntimePrivate:EEStartupEnd
  407. DotNETRuntimePrivate:EEStartupEnd_V1
  408. DotNETRuntimePrivate:EEConfigSetup
  409. DotNETRuntimePrivate:EEConfigSetup_V1
  410. DotNETRuntimePrivate:EEConfigSetupEnd
  411. DotNETRuntimePrivate:EEConfigSetupEnd_V1
  412. DotNETRuntimePrivate:LdSysBases
  413. DotNETRuntimePrivate:LdSysBases_V1
  414. DotNETRuntimePrivate:LdSysBasesEnd
  415. DotNETRuntimePrivate:LdSysBasesEnd_V1
  416. DotNETRuntimePrivate:ExecExe
  417. DotNETRuntimePrivate:ExecExe_V1
  418. DotNETRuntimePrivate:ExecExeEnd
  419. DotNETRuntimePrivate:ExecExeEnd_V1
  420. DotNETRuntimePrivate:Main
  421. DotNETRuntimePrivate:Main_V1
  422. DotNETRuntimePrivate:MainEnd
  423. DotNETRuntimePrivate:MainEnd_V1
  424. DotNETRuntimePrivate:ApplyPolicyStart
  425. DotNETRuntimePrivate:ApplyPolicyStart_V1
  426. DotNETRuntimePrivate:ApplyPolicyEnd
  427. DotNETRuntimePrivate:ApplyPolicyEnd_V1
  428. DotNETRuntimePrivate:LdLibShFolder
  429. DotNETRuntimePrivate:LdLibShFolder_V1
  430. DotNETRuntimePrivate:LdLibShFolderEnd
  431. DotNETRuntimePrivate:LdLibShFolderEnd_V1
  432. DotNETRuntimePrivate:PrestubWorker
  433. DotNETRuntimePrivate:PrestubWorker_V1
  434. DotNETRuntimePrivate:PrestubWorkerEnd
  435. DotNETRuntimePrivate:PrestubWorkerEnd_V1
  436. DotNETRuntimePrivate:GetInstallationStart
  437. DotNETRuntimePrivate:GetInstallationStart_V1
  438. DotNETRuntimePrivate:GetInstallationEnd
  439. DotNETRuntimePrivate:GetInstallationEnd_V1
  440. DotNETRuntimePrivate:OpenHModule
  441. DotNETRuntimePrivate:OpenHModule_V1
  442. DotNETRuntimePrivate:OpenHModuleEnd
  443. DotNETRuntimePrivate:OpenHModuleEnd_V1
  444. DotNETRuntimePrivate:ExplicitBindStart
  445. DotNETRuntimePrivate:ExplicitBindStart_V1
  446. DotNETRuntimePrivate:ExplicitBindEnd
  447. DotNETRuntimePrivate:ExplicitBindEnd_V1
  448. DotNETRuntimePrivate:ParseXml
  449. DotNETRuntimePrivate:ParseXml_V1
  450. DotNETRuntimePrivate:ParseXmlEnd
  451. DotNETRuntimePrivate:ParseXmlEnd_V1
  452. DotNETRuntimePrivate:InitDefaultDomain
  453. DotNETRuntimePrivate:InitDefaultDomain_V1
  454. DotNETRuntimePrivate:InitDefaultDomainEnd
  455. DotNETRuntimePrivate:InitDefaultDomainEnd_V1
  456. DotNETRuntimePrivate:InitSecurity
  457. DotNETRuntimePrivate:InitSecurity_V1
  458. DotNETRuntimePrivate:InitSecurityEnd
  459. DotNETRuntimePrivate:InitSecurityEnd_V1
  460. DotNETRuntimePrivate:AllowBindingRedirs
  461. DotNETRuntimePrivate:AllowBindingRedirs_V1
  462. DotNETRuntimePrivate:AllowBindingRedirsEnd
  463. DotNETRuntimePrivate:AllowBindingRedirsEnd_V1
  464. DotNETRuntimePrivate:EEConfigSync
  465. DotNETRuntimePrivate:EEConfigSync_V1
  466. DotNETRuntimePrivate:EEConfigSyncEnd
  467. DotNETRuntimePrivate:EEConfigSyncEnd_V1
  468. DotNETRuntimePrivate:FusionBinding
  469. DotNETRuntimePrivate:FusionBinding_V1
  470. DotNETRuntimePrivate:FusionBindingEnd
  471. DotNETRuntimePrivate:FusionBindingEnd_V1
  472. DotNETRuntimePrivate:LoaderCatchCall
  473. DotNETRuntimePrivate:LoaderCatchCall_V1
  474. DotNETRuntimePrivate:LoaderCatchCallEnd
  475. DotNETRuntimePrivate:LoaderCatchCallEnd_V1
  476. DotNETRuntimePrivate:FusionInit
  477. DotNETRuntimePrivate:FusionInit_V1
  478. DotNETRuntimePrivate:FusionInitEnd
  479. DotNETRuntimePrivate:FusionInitEnd_V1
  480. DotNETRuntimePrivate:FusionAppCtx
  481. DotNETRuntimePrivate:FusionAppCtx_V1
  482. DotNETRuntimePrivate:FusionAppCtxEnd
  483. DotNETRuntimePrivate:FusionAppCtxEnd_V1
  484. DotNETRuntimePrivate:Fusion2EE
  485. DotNETRuntimePrivate:Fusion2EE_V1
  486. DotNETRuntimePrivate:Fusion2EEEnd
  487. DotNETRuntimePrivate:Fusion2EEEnd_V1
  488. DotNETRuntimePrivate:SecurityCatchCall
  489. DotNETRuntimePrivate:SecurityCatchCall_V1
  490. DotNETRuntimePrivate:SecurityCatchCallEnd
  491. DotNETRuntimePrivate:SecurityCatchCallEnd_V1
  492. )
  493. declare -a DotNETRuntimePrivate_StackKeyword=(
  494. DotNETRuntimePrivate:CLRStackWalkPrivate
  495. )
  496. declare -a DotNETRuntimePrivate_PerfTrackPrivateKeyword=(
  497. DotNETRuntimePrivate:ModuleRangeLoadPrivate
  498. )
  499. declare -a DotNETRuntimePrivate_BindingKeyword=(
  500. DotNETRuntimePrivate:BindingPolicyPhaseStart
  501. DotNETRuntimePrivate:BindingPolicyPhaseEnd
  502. DotNETRuntimePrivate:BindingNgenPhaseStart
  503. DotNETRuntimePrivate:BindingNgenPhaseEnd
  504. DotNETRuntimePrivate:BindingLookupAndProbingPhaseStart
  505. DotNETRuntimePrivate:BindingLookupAndProbingPhaseEnd
  506. DotNETRuntimePrivate:LoaderPhaseStart
  507. DotNETRuntimePrivate:LoaderPhaseEnd
  508. DotNETRuntimePrivate:BindingPhaseStart
  509. DotNETRuntimePrivate:BindingPhaseEnd
  510. DotNETRuntimePrivate:BindingDownloadPhaseStart
  511. DotNETRuntimePrivate:BindingDownloadPhaseEnd
  512. DotNETRuntimePrivate:LoaderAssemblyInitPhaseStart
  513. DotNETRuntimePrivate:LoaderAssemblyInitPhaseEnd
  514. DotNETRuntimePrivate:LoaderMappingPhaseStart
  515. DotNETRuntimePrivate:LoaderMappingPhaseEnd
  516. DotNETRuntimePrivate:LoaderDeliverEventsPhaseStart
  517. DotNETRuntimePrivate:LoaderDeliverEventsPhaseEnd
  518. DotNETRuntimePrivate:FusionMessageEvent
  519. DotNETRuntimePrivate:FusionErrorCodeEvent
  520. )
  521. declare -a DotNETRuntimePrivate_SecurityPrivateKeyword=(
  522. DotNETRuntimePrivate:EvidenceGenerated
  523. DotNETRuntimePrivate:ModuleTransparencyComputationStart
  524. DotNETRuntimePrivate:ModuleTransparencyComputationEnd
  525. DotNETRuntimePrivate:TypeTransparencyComputationStart
  526. DotNETRuntimePrivate:TypeTransparencyComputationEnd
  527. DotNETRuntimePrivate:MethodTransparencyComputationStart
  528. DotNETRuntimePrivate:MethodTransparencyComputationEnd
  529. DotNETRuntimePrivate:FieldTransparencyComputationStart
  530. DotNETRuntimePrivate:FieldTransparencyComputationEnd
  531. DotNETRuntimePrivate:TokenTransparencyComputationStart
  532. DotNETRuntimePrivate:TokenTransparencyComputationEnd
  533. )
  534. declare -a DotNETRuntimePrivate_PrivateFusionKeyword=(
  535. DotNETRuntimePrivate:NgenBindEvent
  536. )
  537. declare -a DotNETRuntimePrivate_NoKeyword=(
  538. DotNETRuntimePrivate:FailFast
  539. )
  540. declare -a DotNETRuntimePrivate_InteropPrivateKeyword=(
  541. DotNETRuntimePrivate:CCWRefCountChange
  542. )
  543. declare -a DotNETRuntimePrivate_GCHandlePrivateKeyword=(
  544. DotNETRuntimePrivate:PrvSetGCHandle
  545. DotNETRuntimePrivate:PrvDestroyGCHandle
  546. )
  547. declare -a DotNETRuntimePrivate_LoaderHeapPrivateKeyword=(
  548. DotNETRuntimePrivate:AllocRequest
  549. )
  550. declare -a DotNETRuntimePrivate_MulticoreJitPrivateKeyword=(
  551. DotNETRuntimePrivate:MulticoreJit
  552. DotNETRuntimePrivate:MulticoreJitMethodCodeReturned
  553. )
  554. declare -a DotNETRuntimePrivate_DynamicTypeUsageKeyword=(
  555. DotNETRuntimePrivate:IInspectableRuntimeClassName
  556. DotNETRuntimePrivate:WinRTUnbox
  557. DotNETRuntimePrivate:CreateRCW
  558. DotNETRuntimePrivate:RCWVariance
  559. DotNETRuntimePrivate:RCWIEnumerableCasting
  560. DotNETRuntimePrivate:CreateCCW
  561. DotNETRuntimePrivate:CCWVariance
  562. DotNETRuntimePrivate:ObjectVariantMarshallingToNative
  563. DotNETRuntimePrivate:GetTypeFromGUID
  564. DotNETRuntimePrivate:GetTypeFromProgID
  565. DotNETRuntimePrivate:ConvertToCallbackEtw
  566. DotNETRuntimePrivate:BeginCreateManagedReference
  567. DotNETRuntimePrivate:EndCreateManagedReference
  568. DotNETRuntimePrivate:ObjectVariantMarshallingToManaged
  569. )
  570. declare -a EventSource=(
  571. DotNETRuntime:EventSource
  572. )
  573. declare -a LTTng_Kernel_ProcessLifetimeKeyword=(
  574. sched_process_exec
  575. sched_process_exit
  576. )
  577. ######################################
  578. ## Global Variables
  579. ######################################
  580. # Install without waiting for standard input
  581. forceInstall=0
  582. # Declare an array of events to collect.
  583. declare -a eventsToCollect
  584. # Use Perf_Event
  585. usePerf=1
  586. # Use LTTng
  587. useLTTng=1
  588. # LTTng Installed
  589. lttngInstalled=0
  590. # Collect hardware events
  591. collect_HWevents=0
  592. # Set to 1 when the CTRLC_Handler gets invoked.
  593. handlerInvoked=0
  594. # Log file
  595. declare logFile
  596. logFilePrefix='/tmp/perfcollect'
  597. logEnabled=0
  598. # Collect info to pass between processes
  599. collectInfoFile=$(dirname `mktemp -u`)/'perfcollect.sessioninfo'
  600. ######################################
  601. ## Logging Functions
  602. ######################################
  603. LogAppend()
  604. {
  605. if (( $logEnabled == 1 ))
  606. then
  607. echo $* >> $logFile
  608. fi
  609. }
  610. RunSilent()
  611. {
  612. if (( $logEnabled == 1 ))
  613. then
  614. echo "Running \"$*\"" >> $logFile
  615. $* >> $logFile 2>&1
  616. echo "" >> $logFile
  617. else
  618. $* > /dev/null 2>&1
  619. fi
  620. }
  621. RunSilentBackground()
  622. {
  623. if (( $logEnabled == 1 ))
  624. then
  625. echo "Running \"$*\"" >> $logFile
  626. $* >> $logFile 2>&1 & sleep 1
  627. echo "" >> $logFile
  628. else
  629. $* > /dev/null 2>&1 & sleep 1
  630. fi
  631. # When handler is invoked, kill the process.
  632. pid=$!
  633. for (( ; ; ))
  634. do
  635. if [ "$handlerInvoked" == "1" ]
  636. then
  637. kill -INT $pid
  638. break;
  639. else
  640. sleep 1
  641. fi
  642. done
  643. # Wait for the process to exit.
  644. wait $pid
  645. }
  646. InitializeLog()
  647. {
  648. # Pick the log file name.
  649. logFile="$logFilePrefix.log"
  650. while [ -f $logFile ];
  651. do
  652. logFile="$logFilePrefix.$RANDOM.log"
  653. done
  654. # Mark the log as enabled.
  655. logEnabled=1
  656. # Start the log
  657. date=`date`
  658. echo "Log started at ${date}" > $logFile
  659. echo '' >> $logFile
  660. # The system information.
  661. LogAppend 'Machine info: ' `uname -a`
  662. if [ "$perfcmd" != "" ]
  663. then
  664. LogAppend 'perf version:' `$perfcmd --version 2>&1`
  665. fi
  666. if [ "$lttngcmd" != "" ]
  667. then
  668. LogAppend 'LTTng version: ' `$lttngcmd --version`
  669. fi
  670. LogAppend
  671. }
  672. CloseLog()
  673. {
  674. LogAppend "END LOG FILE"
  675. LogAppend "NOTE: It is normal for the log file to end right before the trace is actually compressed. This occurs because the log file is part of the archive, and thus can't be written anymore."
  676. # The log itself doesn't need to be closed,
  677. # but we need to tell the script not to log anymore.
  678. logEnabled=0
  679. }
  680. ######################################
  681. ## Helper Functions
  682. ######################################
  683. ##
  684. # Console text color modification helpers.
  685. ##
  686. RedText()
  687. {
  688. tput=`GetCommandFullPath "tput"`
  689. if [ "$tput" != "" ]
  690. then
  691. $tput setaf 1
  692. fi
  693. }
  694. GreenText()
  695. {
  696. tput=`GetCommandFullPath "tput"`
  697. if [ "$tput" != "" ]
  698. then
  699. $tput setaf 2
  700. fi
  701. }
  702. BlueText()
  703. {
  704. tput=`GetCommandFullPath "tput"`
  705. if [ "$tput" != "" ]
  706. then
  707. $tput setaf 6
  708. fi
  709. }
  710. YellowText()
  711. {
  712. tput=`GetCommandFullPath "tput"`
  713. if [ "$tput" != "" ]
  714. then
  715. $tput setaf 3
  716. fi
  717. }
  718. ResetText()
  719. {
  720. tput=`GetCommandFullPath "tput"`
  721. if [ "$tput" != "" ]
  722. then
  723. $tput sgr0
  724. fi
  725. }
  726. # $1 == Status message
  727. WriteStatus()
  728. {
  729. LogAppend $*
  730. BlueText
  731. echo $1
  732. ResetText
  733. }
  734. # $1 == Message.
  735. WriteWarning()
  736. {
  737. LogAppend $*
  738. YellowText
  739. echo $1
  740. ResetText
  741. }
  742. # $1 == Message.
  743. FatalError()
  744. {
  745. RedText
  746. echo "ERROR: $1"
  747. ResetText
  748. PrintUsage
  749. exit 1
  750. }
  751. EnsureRoot()
  752. {
  753. # Warn non-root users.
  754. if [ `whoami` != "root" ]
  755. then
  756. RedText
  757. echo "This script must be run as root."
  758. ResetText
  759. exit 1;
  760. fi
  761. }
  762. ######################################
  763. # Command Discovery
  764. ######################################
  765. DiscoverCommands()
  766. {
  767. perfcmd=`GetCommandFullPath "perf"`
  768. if [ "$(IsDebian)" == "1" ]
  769. then
  770. # Test perf to see if it successfully runs or fails because it doesn't match the kernel version.
  771. $perfcmd --version > /dev/null 2>&1
  772. if [ "$?" == "1" ]
  773. then
  774. perfoutput=$($perfcmd 2>&1)
  775. if [ $? -eq 1 ]
  776. then
  777. perfMarker="perf_"
  778. if [[ "$perfoutput" == *"$perfMarker"* ]]
  779. then
  780. foundWorkingPerf=0
  781. WriteWarning "Perf is installed, but does not exactly match the version of the running kernel."
  782. WriteWarning "This is often OK, and we'll try to workaround this."
  783. WriteStatus "Attempting to find a working copy of perf."
  784. # Attempt to find an existing version of perf to use.
  785. # Order the search by newest directory first.
  786. baseDir="/usr/bin"
  787. searchPath="$baseDir/perf_*"
  788. for fileName in $(ls -d --sort=time $searchPath)
  789. do
  790. $($fileName > /dev/null 2>&1)
  791. if [ $? -eq 1 ]
  792. then
  793. # If $? == 1, then use this copy of perf.
  794. perfcmd=$fileName
  795. foundWorkingPerf=1
  796. break;
  797. fi
  798. done
  799. if [ $foundWorkingPerf -eq 0 ]
  800. then
  801. FatalError "Unable to find a working copy of perf. Try re-installing via ./perfcollect install."
  802. fi
  803. WriteStatus "...FINISHED"
  804. fi
  805. fi
  806. fi
  807. fi
  808. # Check to see if perf is installed, but doesn't exactly match the current kernel version.
  809. # This happens when the kernel gets upgraded, or when running inside of a container where the
  810. # host and container OS versions don't match.
  811. perfoutput=$($perfcmd 2>&1)
  812. if [ $? -eq 2 ]
  813. then
  814. # Check the beginning of the output to see if it matches the kernel warning.
  815. warningText="WARNING: perf not found for kernel"
  816. if [[ "$perfoutput" == "$warningText"* ]]
  817. then
  818. foundWorkingPerf=0
  819. WriteWarning "Perf is installed, but does not exactly match the version of the running kernel."
  820. WriteWarning "This is often OK, and we'll try to workaround this."
  821. WriteStatus "Attempting to find a working copy of perf."
  822. # Attempt to find an existing version of perf to use.
  823. # Order the search by newest directory first.
  824. baseDir="/usr/lib/linux-tools"
  825. searchPath="$baseDir/*/"
  826. for dirName in $(ls -d --sort=time $searchPath)
  827. do
  828. candidatePerfPath="$dirName""perf"
  829. $($candidatePerfPath > /dev/null 2>&1)
  830. if [ $? -eq 1 ]
  831. then
  832. # If $? == 1, then use this copy of perf.
  833. perfcmd=$candidatePerfPath
  834. foundWorkingPerf=1
  835. break;
  836. fi
  837. done
  838. if [ $foundWorkingPerf -eq 0 ]
  839. then
  840. FatalError "Unable to find a working copy of perf. Try re-installing via ./perfcollect install."
  841. fi
  842. WriteStatus "...FINISHED"
  843. fi
  844. fi
  845. lttngcmd=`GetCommandFullPath "lttng"`
  846. zipcmd=`GetCommandFullPath "zip"`
  847. unzipcmd=`GetCommandFullPath "unzip"`
  848. objdumpcmd=`GetCommandFullPath "objdump"`
  849. }
  850. GetCommandFullPath()
  851. {
  852. echo `command -v $1`
  853. }
  854. ######################################
  855. # Prerequisite Installation
  856. ######################################
  857. IsMariner()
  858. {
  859. local mariner=0
  860. if [ -f /etc/lsb-release ]
  861. then
  862. local flavor=`cat /etc/lsb-release | grep DISTRIB_ID`
  863. if [ "$flavor" == "DISTRIB_ID=\"Mariner\"" ]
  864. then
  865. mariner=1
  866. fi
  867. fi
  868. echo $mariner
  869. }
  870. InstallPerf_Mariner()
  871. {
  872. # Disallow non-root users.
  873. EnsureRoot
  874. # Install perf
  875. tdnf install -y kernel-tools
  876. # Install zip and unzip
  877. tdnf install -y zip unzip
  878. }
  879. IsAlpine()
  880. {
  881. local alpine=0
  882. local apk=`GetCommandFullPath "apk"`
  883. if [ "$apk" != "" ]
  884. then
  885. alpine=1
  886. fi
  887. echo $alpine
  888. }
  889. InstallPerf_Alpine()
  890. {
  891. # Disallow non-root users.
  892. EnsureRoot
  893. # Install perf
  894. apk add perf --repository=http://dl-cdn.alpinelinux.org/alpine/edge/community
  895. # Install zip and unzip
  896. apk add zip unzip
  897. }
  898. IsRHEL()
  899. {
  900. local rhel=0
  901. if [ -f /etc/redhat-release ]
  902. then
  903. rhel=1
  904. fi
  905. echo $rhel
  906. }
  907. InstallPerf_RHEL()
  908. {
  909. # Disallow non-root users.
  910. EnsureRoot
  911. # Install perf
  912. yum install perf zip unzip
  913. }
  914. IsDebian()
  915. {
  916. local debian=0
  917. local uname=`uname -a`
  918. if [[ $uname =~ .*Debian.* ]]
  919. then
  920. debian=1
  921. elif [ -f /etc/debian_version ]
  922. then
  923. debian=1
  924. fi
  925. echo $debian
  926. }
  927. InstallPerf_Debian()
  928. {
  929. # Disallow non-root users.
  930. EnsureRoot
  931. # Check for the existence of the linux-tools package.
  932. pkgName='linux-tools'
  933. pkgCount=`apt-cache search $pkgName | grep -c $pkgName`
  934. if [ "$pkgCount" == "0" ]
  935. then
  936. pkgName='linux-perf'
  937. pkgCount=`apt-cache search $pkgName | grep -c $pkgName`
  938. if [ "$pkgCount" == "0" ]
  939. then
  940. FatalError "Unable to find a perf package to install."
  941. fi
  942. fi
  943. # Install zip and perf.
  944. apt-get install -y zip binutils $pkgName
  945. }
  946. IsSUSE()
  947. {
  948. local suse=0
  949. if [ -f /usr/bin/zypper ]
  950. then
  951. suse=1
  952. fi
  953. echo $suse
  954. }
  955. InstallPerf_SUSE()
  956. {
  957. # Disallow non-root users.
  958. EnsureRoot
  959. # Install perf.
  960. zypper install perf zip unzip
  961. }
  962. IsUbuntu()
  963. {
  964. local ubuntu=0
  965. if [ -f /etc/lsb-release ]
  966. then
  967. local flavor=`cat /etc/lsb-release | grep DISTRIB_ID`
  968. if [ "$flavor" == "DISTRIB_ID=Ubuntu" ]
  969. then
  970. ubuntu=1
  971. fi
  972. fi
  973. echo $ubuntu
  974. }
  975. InstallPerf_Ubuntu()
  976. {
  977. # Disallow non-root users.
  978. EnsureRoot
  979. # Install packages.
  980. BlueText
  981. echo "Installing perf_event packages."
  982. ResetText
  983. # Handle Azure instances.
  984. release=`uname -r`
  985. if [[ "$release" == *"-azure" ]]
  986. then
  987. apt-get install -y linux-tools-azure zip software-properties-common
  988. else
  989. apt-get install -y linux-tools-common linux-tools-`uname -r` linux-cloud-tools-`uname -r` zip software-properties-common
  990. fi
  991. }
  992. InstallPerf()
  993. {
  994. if [ "$(IsUbuntu)" == "1" ]
  995. then
  996. InstallPerf_Ubuntu
  997. elif [ "$(IsSUSE)" == "1" ]
  998. then
  999. InstallPerf_SUSE
  1000. elif [ "$(IsDebian)" == "1" ]
  1001. then
  1002. InstallPerf_Debian
  1003. elif [ "$(IsRHEL)" == "1" ]
  1004. then
  1005. InstallPerf_RHEL
  1006. elif [ "$(IsAlpine)" == "1" ]
  1007. then
  1008. InstallPerf_Alpine
  1009. elif [ "$(IsMariner)" == "1" ]
  1010. then
  1011. InstallPerf_Mariner
  1012. else
  1013. FatalError "Auto install unsupported for this distribution. Install perf manually to continue."
  1014. fi
  1015. }
  1016. InstallLTTng_RHEL()
  1017. {
  1018. # Disallow non-root users.
  1019. EnsureRoot
  1020. local isRHEL7=0
  1021. local isRHEL8=0
  1022. if [ -e /etc/redhat-release ]; then
  1023. local redhatRelease=$(</etc/redhat-release)
  1024. if [[ $redhatRelease == "CentOS Linux release 7."* || $redhatRelease == "Red Hat Enterprise Linux "*"release 7."* ]]; then
  1025. isRHEL7=1
  1026. elif [[ $redhatRelease == "CentOS Linux release 8."* || $redhatRelease == "Red Hat Enterprise Linux "*"release 8."* ]]; then
  1027. isRHEL8=1
  1028. fi
  1029. fi
  1030. if [ "$isRHEL7" == "1" ] || [ "$isRHEL8" == "1" ]
  1031. then
  1032. packageRepo="https://packages.efficios.com/repo.files/EfficiOS-RHEL7-x86-64.repo"
  1033. if [ "$forceInstall" != 1 ]
  1034. then
  1035. # Prompt for confirmation, since we need to add a new repository.
  1036. BlueText
  1037. echo "LTTng installation requires that a new package repo be added to your yum configuration."
  1038. echo "The package repo url is: $packageRepo"
  1039. echo ""
  1040. read -p "Would you like to add the LTTng package repo to your YUM configuration? [Y/N]" resp
  1041. ResetText
  1042. fi
  1043. # Make sure that wget is installed.
  1044. BlueText
  1045. echo "Installing wget. Required to add package repo."
  1046. ResetText
  1047. yum install wget
  1048. # Connect to the LTTng package repo.
  1049. wget -P /etc/yum.repos.d/ $packageRepo
  1050. # Import package signing key.
  1051. rpmkeys --import https://packages.efficios.com/rhel/repo.key
  1052. # Update the yum package database.
  1053. yum updateinfo
  1054. fi
  1055. # Install LTTng
  1056. yum install -y lttng-tools lttng-ust babeltrace
  1057. if [ "$isRHEL7" == "1" ]
  1058. then
  1059. yum install -y kmod-lttng-modules
  1060. else
  1061. YellowText
  1062. echo "LTTng kernel package (kmod-lttng-modules) is not available on this platform."
  1063. ResetText
  1064. fi
  1065. }
  1066. InstallLTTng_Debian()
  1067. {
  1068. # Disallow non-root users.
  1069. EnsureRoot
  1070. # Install LTTng
  1071. apt-get install -y lttng-tools liblttng-ust-dev
  1072. }
  1073. InstallLTTng_SUSE()
  1074. {
  1075. # Disallow non-root users.
  1076. EnsureRoot
  1077. # Package repo url
  1078. packageRepo="http://download.opensuse.org/repositories/devel:/tools:/lttng/openSUSE_13.2/devel:tools:lttng.repo"
  1079. if [ "$forceInstall" != 1 ]
  1080. then
  1081. # Prompt for confirmation, since we need to add a new repository.
  1082. BlueText
  1083. echo "LTTng installation requires that a new package repo be added to your zypper configuration."
  1084. echo "The package repo url is: $packageRepo"
  1085. echo ""
  1086. read -p "Would you like to add the LTTng package repo to your zypper configuration? [Y/N]" resp
  1087. ResetText
  1088. fi
  1089. if [ "$resp" == "Y" ] || [ "$resp" == "y" ] || [ "$forceInstall" == 1 ]
  1090. then
  1091. # Add package repo.
  1092. BlueText
  1093. echo "Adding LTTng repo and running zypper refresh."
  1094. ResetText
  1095. zypper addrepo $packageRepo
  1096. zypper refresh
  1097. # Install packages.
  1098. BlueText
  1099. echo "Installing LTTng packages."
  1100. ResetText
  1101. zypper install lttng-tools lttng-modules lttng-ust-devel
  1102. fi
  1103. }
  1104. InstallLTTng_Ubuntu()
  1105. {
  1106. # Disallow non-root users.
  1107. EnsureRoot
  1108. # Install packages.
  1109. BlueText
  1110. echo "Installing LTTng packages."
  1111. ResetText
  1112. apt-get install -y lttng-tools lttng-modules-dkms liblttng-ust0
  1113. }
  1114. InstallLTTng()
  1115. {
  1116. if command -v lttng &> /dev/null
  1117. then
  1118. lttngInstalled=1
  1119. BlueText
  1120. echo "LTTng already installed."
  1121. ResetText
  1122. return
  1123. fi
  1124. if [ "$(IsUbuntu)" == "1" ]
  1125. then
  1126. InstallLTTng_Ubuntu
  1127. elif [ "$(IsSUSE)" == "1" ]
  1128. then
  1129. InstallLTTng_SUSE
  1130. elif [ "$(IsDebian)" == "1" ]
  1131. then
  1132. InstallLTTng_Debian
  1133. elif [ "$(IsRHEL)" == "1" ]
  1134. then
  1135. InstallLTTng_RHEL
  1136. elif [ "$(IsMariner)" == "1" ]
  1137. then
  1138. echo "Collection of events from lttng-ust is not supported on Mariner for .NET workloads, so no lttng-ust events will be collected."
  1139. elif [ "$(IsAlpine)" == "1" ]
  1140. then
  1141. echo "lttng-tools is not available on Alpine Linux, so no lttng-ust events will be collected."
  1142. else
  1143. FatalError "Auto install unsupported for this distribution. Install lttng and lttng-ust packages manually."
  1144. fi
  1145. }
  1146. SupportsAutoInstall()
  1147. {
  1148. local supportsAutoInstall=0
  1149. if [ "$(IsUbuntu)" == "1" ] || [ "$(IsSUSE)" == "1" ] || [ "$(IsMariner)" == "1" ]
  1150. then
  1151. supportsAutoInstall=1
  1152. fi
  1153. echo $supportsAutoInstall
  1154. }
  1155. EnsurePrereqsInstalled()
  1156. {
  1157. # If perf is not installed, then bail, as it is currently required.
  1158. if [ "$perfcmd" == "" ]
  1159. then
  1160. RedText
  1161. echo "Perf not installed."
  1162. if [ "$(SupportsAutoInstall)" == "1" ]
  1163. then
  1164. echo "Run ./perfcollect install"
  1165. echo "or install perf manually."
  1166. else
  1167. echo "Install perf to proceed."
  1168. fi
  1169. ResetText
  1170. exit 1
  1171. fi
  1172. # Disable LTTng use if running on Alpine or Mariner.
  1173. if [ "$(IsAlpine)" == "1" ] || [ "$(IsMariner)" == "1" ]
  1174. then
  1175. useLTTng=0
  1176. fi
  1177. # If LTTng is installed, consider using it.
  1178. if [ "$lttngcmd" == "" ] && [ "$useLTTng" == "1" ]
  1179. then
  1180. RedText
  1181. echo "LTTng not installed."
  1182. if [ "$(SupportsAutoInstall)" == "1" ]
  1183. then
  1184. echo "Run ./perfcollect install"
  1185. echo "or install LTTng manually."
  1186. else
  1187. echo "Install LTTng to proceed."
  1188. fi
  1189. ResetText
  1190. exit 1
  1191. fi
  1192. # If zip or unzip are not installing, then bail.
  1193. if [ "$zipcmd" == "" ] || [ "$unzipcmd" == "" ]
  1194. then
  1195. RedText
  1196. echo "Zip and unzip are not installed."
  1197. if [ "$(SupportsAutoInstall)" == "1" ]
  1198. then
  1199. echo "Run ./perfcollect install"
  1200. echo "or install zip and unzip manually."
  1201. else
  1202. echo "Install zip and unzip to proceed."
  1203. fi
  1204. ResetText
  1205. exit 1
  1206. fi
  1207. }
  1208. ######################################
  1209. # Argument Processing
  1210. ######################################
  1211. action=''
  1212. inputTraceName=''
  1213. collectionPid=''
  1214. processFilter=''
  1215. graphType=''
  1216. perfOpt=''
  1217. viewer='perf'
  1218. gcCollectOnly=''
  1219. gcOnly=''
  1220. gcWithHeap=''
  1221. events=''
  1222. ProcessArguments()
  1223. {
  1224. # Set the action
  1225. action=$1
  1226. # Actions with no arguments.
  1227. if [ "$action" == "livetrace" ] || [ "$action" == "setenv" ]
  1228. then
  1229. return
  1230. fi
  1231. # Not enough arguments.
  1232. if [ "$#" -le "1" ]
  1233. then
  1234. FatalError "Not enough arguments have been specified."
  1235. fi
  1236. # Validate action name.
  1237. if [ "$action" != "collect" ] && [ "$action" != "view" ] \
  1238. && [ "$action" != "start" ] && [ "$action" != "stop" ]
  1239. then
  1240. FatalError "Invalid action specified."
  1241. fi
  1242. # Set the data file.
  1243. inputTraceName=$2
  1244. if [ "$inputTraceName" == "" ]
  1245. then
  1246. FatalError "Invalid trace name specified."
  1247. fi
  1248. # Process remaining arguments.
  1249. # First copy the args into an array so that we can walk the array.
  1250. args=( "$@" )
  1251. for (( i=2; i<${#args[@]}; i++ ))
  1252. do
  1253. # Get the arg.
  1254. local arg=${args[$i]}
  1255. # Convert the arg to lower case.
  1256. arg=`echo $arg | tr '[:upper:]' '[:lower:]'`
  1257. # Get the arg value.
  1258. if [ ${i+1} -lt $# ]
  1259. then
  1260. local value=${args[$i+1]}
  1261. # Keep the cases of '-events' value to match keyword variables
  1262. if [ "-events" != "$arg" ]
  1263. then
  1264. # Convert the value to lower case.
  1265. value=`echo $value | tr '[:upper:]' '[:lower:]'`
  1266. fi
  1267. fi
  1268. # Match the arg to a known value.
  1269. if [ "-pid" == "$arg" ]
  1270. then
  1271. collectionPid=$value
  1272. i=$i+1
  1273. elif [ "-processfilter" == "$arg" ]
  1274. then
  1275. processFilter=$value
  1276. i=$i+1
  1277. elif [ "-graphtype" == "$arg" ]
  1278. then
  1279. graphType=$value
  1280. i=$i+1
  1281. elif [ "-threadtime" == "$arg" ]
  1282. then
  1283. collect_threadTime=1
  1284. elif [ "-offcpu" == "$arg" ]
  1285. then
  1286. # Perf doesn't support capturing cpu-clock events and sched events concurrently.
  1287. collect_cpu=0
  1288. collect_offcpu=1
  1289. elif [ "-system" == "$arg" ]
  1290. then
  1291. collect_system=1
  1292. elif [ "-hwevents" == "$arg" ]
  1293. then
  1294. collect_HWevents=1
  1295. elif [ "-perfopt" == "$arg" ]
  1296. then
  1297. perfOpt=$value
  1298. i=$i+1
  1299. elif [ "-viewer" == "$arg" ]
  1300. then
  1301. viewer=$value
  1302. i=$i+1
  1303. # Validate the viewer.
  1304. if [ "$viewer" != "perf" ] && [ "$viewer" != "lttng" ]
  1305. then
  1306. FatalError "Invalid viewer specified. Valid values are 'perf' and 'lttng'."
  1307. fi
  1308. elif [ "-nolttng" == "$arg" ]
  1309. then
  1310. useLTTng=0
  1311. elif [ "-noperf" == "$arg" ]
  1312. then
  1313. usePerf=0
  1314. elif [ "-gccollectonly" == "$arg" ]
  1315. then
  1316. gcCollectOnly=1
  1317. elif [ "-gconly" == "$arg" ]
  1318. then
  1319. gcOnly=1
  1320. elif [ "-gcwithheap" == "$arg" ]
  1321. then
  1322. gcWithHeap=1
  1323. elif [ "-events" == "$arg" ]
  1324. then
  1325. events=$value
  1326. i=$i+1
  1327. elif [ "-collectsec" == "$arg" ]
  1328. then
  1329. duration=$value
  1330. i=$i+1
  1331. else
  1332. echo "Unknown arg ${arg}, ignored..."
  1333. fi
  1334. done
  1335. }
  1336. ##
  1337. # LTTng collection
  1338. ##
  1339. lttngSessionName=''
  1340. lttngTraceDir=''
  1341. CreateLTTngSession()
  1342. {
  1343. if [ "$action" == "livetrace" ]
  1344. then
  1345. output=`$lttngcmd create --live`
  1346. else
  1347. output=`$lttngcmd create`
  1348. fi
  1349. lttngSessionName=`echo $output | grep -o "Session.*created." | sed 's/\(Session \| created.\)//g'`
  1350. lttngTraceDir=`echo $output | grep -o "Traces.*" | sed 's/\(Traces will be written in \|\)//g' | sed 's/\(Traces will be output to \|\)//g'`
  1351. }
  1352. SetupLTTngSession()
  1353. {
  1354. # Setup per-event context information.
  1355. RunSilent "$lttngcmd add-context --userspace --type vpid"
  1356. RunSilent "$lttngcmd add-context --userspace --type vtid"
  1357. RunSilent "$lttngcmd add-context --userspace --type procname"
  1358. RunSilent "$lttngcmd add-context --kernel -t pid -t procname"
  1359. if [ "$action" == "livetrace" ]
  1360. then
  1361. RunSilent "$lttngcmd enable-event --userspace --tracepoint DotNETRuntime:EventSource"
  1362. elif [ "$gcCollectOnly" == "1" ]
  1363. then
  1364. usePerf=0
  1365. EnableLTTngEvents ${DotNETRuntime_GCKeyword_GCCollectOnly[@]}
  1366. EnableLTTngEvents ${DotNETRuntimePrivate_GCPrivateKeyword_GCCollectOnly[@]}
  1367. EnableLTTngEvents ${DotNETRuntime_ExceptionKeyword[@]}
  1368. elif [ "$gcOnly" == "1" ]
  1369. then
  1370. usePerf=0
  1371. EnableLTTngEvents ${DotNETRuntime_GCKeyword[@]}
  1372. EnableLTTngEvents ${DotNETRuntimePrivate_GCPrivateKeyword[@]}
  1373. EnableLTTngEvents ${DotNETRuntime_JitKeyword[@]}
  1374. EnableLTTngEvents ${DotNETRuntime_LoaderKeyword[@]}
  1375. EnableLTTngEvents ${DotNETRuntime_ExceptionKeyword[@]}
  1376. elif [ "$gcWithHeap" == "1" ]
  1377. then
  1378. usePerf=0
  1379. EnableLTTngEvents ${DotNETRuntime_GCKeyword[@]}
  1380. EnableLTTngEvents ${DotNETRuntime_GCHeapSurvivalAndMovementKeyword[@]}
  1381. else
  1382. if [ "$events" == "" ]
  1383. then
  1384. # Enable the default set of events.
  1385. EnableLTTngEvents ${DotNETRuntime_ThreadingKeyword[@]}
  1386. EnableLTTngEvents ${DotNETRuntime_ThreadingKeyword_ThreadTransferKeyword[@]}
  1387. EnableLTTngEvents ${DotNETRuntime_NoKeyword[@]}
  1388. EnableLTTngEvents ${DotNETRuntime_ExceptionKeyword[@]}
  1389. EnableLTTngEvents ${DotNETRuntime_ContentionKeyword[@]}
  1390. EnableLTTngEvents ${DotNETRuntime_JitKeyword_NGenKeyword[@]}
  1391. EnableLTTngEvents ${DotNETRuntime_JitKeyword[@]}
  1392. EnableLTTngEvents ${DotNETRuntime_LoaderKeyword[@]}
  1393. EnableLTTngEvents ${DotNETRuntime_GCKeyword_GCCollectOnly[@]}
  1394. EnableLTTngEvents ${DotNETRuntimePrivate_GCPrivateKeyword_GCCollectOnly[@]}
  1395. EnableLTTngEvents ${DotNETRuntimePrivate_BindingKeyword[@]}
  1396. EnableLTTngEvents ${DotNETRuntimePrivate_MulticoreJitPrivateKeyword[@]}
  1397. EnableLTTngEvents ${DotNETRuntime_CompilationKeyword[@]}
  1398. elif [ "$events" == "threading" ]
  1399. then
  1400. EnableLTTngEvents ${DotNETRuntime_ThreadingKeyword[@]}
  1401. else
  1402. # Enable other keywords
  1403. events=(${events//","/" "})
  1404. for event in ${events[@]}
  1405. do
  1406. if [ "${!event}" == "" ] || [ "$( echo `declare -p $event | grep -- -a` )" == "" ]
  1407. then
  1408. echo Invalid keyword $event, skipped...
  1409. continue
  1410. fi
  1411. local -a 'keywords=("${'"$event"'[@]}")'
  1412. if [ "${event#"LTTng_Kernel_"}" != "$event" ]
  1413. then
  1414. EnableLTTngKernelEvents ${keywords[@]}
  1415. else
  1416. EnableLTTngEvents ${keywords[@]}
  1417. fi
  1418. done
  1419. fi
  1420. fi
  1421. }
  1422. DestroyLTTngSession()
  1423. {
  1424. RunSilent "$lttngcmd destroy $lttngSessionName"
  1425. }
  1426. StartLTTngCollection()
  1427. {
  1428. CreateLTTngSession
  1429. SetupLTTngSession
  1430. RunSilent "$lttngcmd start $lttngSessionName"
  1431. }
  1432. StopLTTngCollection()
  1433. {
  1434. RunSilent "$lttngcmd stop $lttngSessionName"
  1435. DestroyLTTngSession
  1436. }
  1437. # $@ == event names to be enabled
  1438. EnableLTTngEvents()
  1439. {
  1440. args=( "$@" )
  1441. for (( i=0; i<${#args[@]}; i++ ))
  1442. do
  1443. RunSilent "$lttngcmd enable-event -s $lttngSessionName -u --tracepoint ${args[$i]}"
  1444. done
  1445. }
  1446. EnableLTTngKernelEvents()
  1447. {
  1448. args=( "$@" )
  1449. for (( i=0; i<${#args[@]}; i++ ))
  1450. do
  1451. RunSilent "$lttngcmd enable-event -s $lttngSessionName -k ${args[$i]}"
  1452. done
  1453. }
  1454. ##
  1455. # Helper that processes collected data.
  1456. # This helper is called when the CTRL+C signal is handled.
  1457. ##
  1458. ProcessCollectedData()
  1459. {
  1460. # Make a new target directory.
  1461. local traceSuffix=".trace"
  1462. local traceName=$inputTraceName
  1463. local directoryName=$traceName$traceSuffix
  1464. mkdir $directoryName
  1465. # Save LTTng trace files.
  1466. if [ "$useLTTng" == "1" ]
  1467. then
  1468. LogAppend "Saving LTTng trace files."
  1469. if [ -d $lttngTraceDir ]
  1470. then
  1471. RunSilent "mkdir lttngTrace"
  1472. RunSilent "cp -r $lttngTraceDir lttngTrace"
  1473. fi
  1474. fi
  1475. if [ "$usePerf" == 1 ]
  1476. then
  1477. # Get any perf-$pid.map files that were used by the
  1478. # trace and store them alongside the trace.
  1479. local writeCrossgenWarning=1
  1480. LogAppend "Saving perf.map files."
  1481. RunSilent "$perfcmd buildid-list --with-hits"
  1482. local mapFiles=`$perfcmd buildid-list --with-hits | grep /tmp/perf- | cut -d ' ' -f 2`
  1483. for mapFile in $mapFiles
  1484. do
  1485. if [ -f $mapFile ]
  1486. then
  1487. LogAppend "Saving $mapFile"
  1488. # Change permissions on the file before saving, as perf will need to access the file later
  1489. # in this script when running perf script.
  1490. RunSilent "chown root $mapFile"
  1491. RunSilent "cp $mapFile ."
  1492. local perfinfoFile=${mapFile/perf/perfinfo}
  1493. LogAppend "Attempting to find ${perfinfoFile}"
  1494. if [ -f $perfinfoFile ]
  1495. then
  1496. LogAppend "Saving $perfinfoFile"
  1497. RunSilent "chown root $perfinfoFile"
  1498. RunSilent "cp $perfinfoFile ."
  1499. else
  1500. LogAppend "Skipping ${perfinfoFile}."
  1501. fi
  1502. else
  1503. LogAppend "Skipping $mapFile. Some managed symbols may not be resolvable, but trace is still valid."
  1504. fi
  1505. # Also check for jit-<pid>.dump files.
  1506. # Convert to jit dump file name.
  1507. local pid=`echo $mapFile | awk -F"-" '{print $NF}' | awk -F"." '{print $1}'`
  1508. local path=`echo $mapFile | awk -F"/" '{OFS="/";NF--;print $0;}'`
  1509. local jitDumpFile="$path/jit-$pid.dump"
  1510. if [ -f $jitDumpFile ]
  1511. then
  1512. LogAppend "Saving $jitDumpFile"
  1513. RunSilent "cp $jitDumpFile ."
  1514. writeCrossgenWarning=0
  1515. fi
  1516. done
  1517. WriteStatus "Generating native image symbol files"
  1518. # Get the list of loaded images and use the path to libcoreclr.so to find crossgen.
  1519. # crossgen is expected to sit next to libcoreclr.so.
  1520. local buildidList=`$perfcmd buildid-list | grep libcoreclr.so | cut -d ' ' -f 2`
  1521. local crossgenCmd=''
  1522. local crossgenDir=''
  1523. for file in $buildidList
  1524. do
  1525. crossgenDir=`dirname "${file}"`
  1526. if [ -f ${crossgenDir}/crossgen ]
  1527. then
  1528. crossgenCmd=${crossgenDir}/crossgen
  1529. LogAppend "Found crossgen at ${crossgenCmd}"
  1530. break
  1531. fi
  1532. done
  1533. OLDIFS=$IFS
  1534. imagePaths=""
  1535. if [ "$crossgenCmd" != "" ]
  1536. then
  1537. local perfinfos=`ls . | grep perfinfo | cut -d ' ' -f 2`
  1538. for perfinfo in $perfinfos
  1539. do
  1540. if [ -f $perfinfo ]
  1541. then
  1542. IFS=";"
  1543. while read command dll guid; do
  1544. if [ $command ]; then
  1545. if [ $command = "ImageLoad" ]; then
  1546. if [ -f $dll ]; then
  1547. imagePaths="${dll}:${imagePaths}"
  1548. fi
  1549. fi
  1550. fi
  1551. done < $perfinfo
  1552. IFS=$OLDIFS
  1553. fi
  1554. done
  1555. IFS=":"
  1556. LogAppend "Generating PerfMaps for native images"
  1557. for path in $imagePaths
  1558. do
  1559. if [ `echo ${path} | grep ^.*\.dll$` ]
  1560. then
  1561. IFS=""
  1562. LogAppend "Generating PerfMap for ${path}"
  1563. LogAppend "Running ${crossgenCmd} /r $imagePaths /CreatePerfMap . ${path}"
  1564. ${crossgenCmd} /r $imagePaths /CreatePerfMap . ${path} >> $logFile 2>&1
  1565. IFS=":"
  1566. else
  1567. LogAppend "Skipping ${path}"
  1568. fi
  1569. done
  1570. else
  1571. if [ "$buildidList" != "" ] && [ $writeCrossgenWarning -eq 1 ]
  1572. then
  1573. LogAppend "crossgen not found, skipping native image map generation."
  1574. WriteStatus "...SKIPPED"
  1575. WriteWarning "Crossgen not found. Framework symbols will be unavailable."
  1576. WriteWarning "See https://github.com/dotnet/coreclr/blob/master/Documentation/project-docs/linux-performance-tracing.md#resolving-framework-symbols for details."
  1577. fi
  1578. fi
  1579. IFS=$OLDIFS
  1580. WriteStatus "...FINISHED"
  1581. if [ "$objdumpcmd" != "" ]
  1582. then
  1583. # Create debuginfo files (separate symbols) for all modules in the trace.
  1584. WriteStatus "Saving native symbols"
  1585. # Get the list of DSOs with hits in the trace file (those that are actually used).
  1586. # Filter out /tmp/perf-$pid.map files and files that end in .dll.
  1587. local dsosWithHits=`$perfcmd buildid-list --with-hits | grep -v /tmp/perf- | grep -v .dll$`
  1588. for dso in $dsosWithHits
  1589. do
  1590. # Build up tuples of buildid and binary path.
  1591. local processEntry=0
  1592. if [ -f $dso ]
  1593. then
  1594. local pathToBinary=$dso
  1595. processEntry=1
  1596. else
  1597. local buildid=$dso
  1598. pathToBinary=''
  1599. fi
  1600. # Once we have a tuple for a binary path that exists, process it.
  1601. if [ "$processEntry" == "1" ]
  1602. then
  1603. # Get the binary name without path.
  1604. local binaryName=`basename $pathToBinary`
  1605. # Build the debuginfo file name.
  1606. local destFileName=$binaryName.debuginfo
  1607. # Build the destination directory for the debuginfo file.
  1608. local currentDir=`pwd`
  1609. local destDir=$currentDir/debuginfo/$buildid
  1610. # Build the full path to the debuginfo file.
  1611. local destPath=$destDir/$destFileName
  1612. # Check to see if the DSO contains symbols, and if so, build the debuginfo file.
  1613. local noSymbols=`$objdumpcmd -t $pathToBinary | grep "no symbols" -c`
  1614. if [ "$noSymbols" == "0" ]
  1615. then
  1616. LogAppend "Generating debuginfo for $binaryName with buildid=$buildid"
  1617. RunSilent "mkdir -p $destDir"
  1618. RunSilent "objcopy --only-keep-debug $pathToBinary $destPath"
  1619. else
  1620. LogAppend "Skipping $binaryName with buildid=$buildid. No symbol information."
  1621. fi
  1622. fi
  1623. done
  1624. WriteStatus "...FINISHED"
  1625. fi
  1626. WriteStatus "Resolving JIT and R2R symbols"
  1627. originalFile="perf.data"
  1628. inputFile="perf-jit.data"
  1629. RunSilent $perfcmd inject --input $originalFile --jit --output $inputFile
  1630. WriteStatus "...FINISHED"
  1631. WriteStatus "Exporting perf.data file"
  1632. outputDumpFile="perf.data.txt"
  1633. LogAppend "Running $perfcmd script -i $inputFile --fields comm,pid,tid,cpu,time,period,event,ip,sym,dso,trace > $outputDumpFile"
  1634. $perfcmd script -i $inputFile --fields comm,pid,tid,cpu,time,period,event,ip,sym,dso,trace > $outputDumpFile 2>>$logFile
  1635. LogAppend
  1636. # Try capturing without the cpu field which is unavailable in some containerized environments.
  1637. if [ $? -ne 0 ]
  1638. then
  1639. LogAppend "Running $perfcmd script -i $inputFile --fields comm,pid,tid,time,period,event,ip,sym,dso,trace > $outputDumpFile"
  1640. $perfcmd script -i $inputFile --fields comm,pid,tid,time,period,event,ip,sym,dso,trace > $outputDumpFile 2>>$logFile
  1641. LogAppend
  1642. fi
  1643. # If the dump file is zero length, try to collect without the period field, which was added recently.
  1644. if [ ! -s $outputDumpFile ]
  1645. then
  1646. LogAppend "Running $perfcmd script -i $inputFile --fields comm,pid,tid,time,event,ip,sym,dso,trace > $outputDumpFile"
  1647. $perfcmd script -i $inputFile --fields comm,pid,tid,time,event,ip,sym,dso,trace > $outputDumpFile 2>>$logFile
  1648. LogAppend
  1649. fi
  1650. WriteStatus "...FINISHED"
  1651. fi
  1652. WriteStatus "Compressing trace files"
  1653. # Move all collected files to the new directory.
  1654. RunSilent "mv -f * $directoryName"
  1655. # Close the log - this stops all writing to the log, so that we can move it into the archive.
  1656. CloseLog
  1657. # Move the log file to the new directory and rename it to the standard log name.
  1658. RunSilent "mv $logFile $directoryName/perfcollect.log"
  1659. # Compress the data.
  1660. local archiveSuffix=".zip"
  1661. local archiveName=$directoryName$archiveSuffix
  1662. RunSilent "$zipcmd -r $archiveName $directoryName"
  1663. # Move back to the original directory.
  1664. popd > /dev/null
  1665. # Move the archive.
  1666. RunSilent "mv $tempDir/$archiveName ."
  1667. WriteStatus "...FINISHED"
  1668. WriteStatus "Cleaning up artifacts"
  1669. # Delete the temp directory.
  1670. RunSilent "rm -rf $tempDir $collectInfoFile"
  1671. WriteStatus "...FINISHED"
  1672. # Tell the user where the trace is.
  1673. WriteStatus
  1674. WriteStatus "Trace saved to $archiveName"
  1675. }
  1676. ##
  1677. # Handle the CTRL+C signal.
  1678. ##
  1679. CTRLC_Handler()
  1680. {
  1681. # Mark the handler invoked.
  1682. handlerInvoked=1
  1683. }
  1684. EndCollect()
  1685. {
  1686. # The user must either use "collect stop" or CTRL+C to stop collection.
  1687. if [ "$action" == "stop" ]
  1688. then
  1689. # Recover trace info in the previous program.
  1690. source $collectInfoFile # TODO: exit and dispose upon missing file
  1691. # New program started, so go back to the temp directory.
  1692. pushd $tempDir > /dev/null
  1693. fi
  1694. if [ "$useLTTng" == "1" ]
  1695. then
  1696. StopLTTngCollection
  1697. fi
  1698. # Update the user.
  1699. WriteStatus
  1700. WriteStatus "...STOPPED."
  1701. WriteStatus
  1702. WriteStatus "Starting post-processing. This may take some time."
  1703. WriteStatus
  1704. # The user used CTRL+C to stop collection.
  1705. # When this happens, we catch the signal and finish our work.
  1706. ProcessCollectedData
  1707. }
  1708. ##
  1709. # Print usage information.
  1710. ##
  1711. PrintUsage()
  1712. {
  1713. echo "This script uses perf_event and LTTng to collect and view performance traces for .NET applications."
  1714. echo "For detailed collection and viewing steps, view this script in a text editor or viewer."
  1715. echo ""
  1716. echo "./perfcollect <action> <tracename>"
  1717. echo "Valid Actions: collect start/stop view livetrace install"
  1718. echo ""
  1719. echo "collect options:"
  1720. echo "By default, collection includes CPU samples collected every ms."
  1721. echo " -pid : Only collect data from the specified process id."
  1722. echo " -threadtime : Collect events for thread time analysis (on and off cpu)."
  1723. echo " -offcpu : Collect events for off-cpu analysis."
  1724. echo " -hwevents : Collect (some) hardware counters."
  1725. echo ""
  1726. echo "start:"
  1727. echo " Start collection, but with Lttng trace ONLY. It needs to be used with 'stop' action."
  1728. echo ""
  1729. echo "stop:"
  1730. echo " Stop collection if 'start' action is used."
  1731. echo ""
  1732. echo "view options:"
  1733. echo " -processfilter : Filter data by the specified process name."
  1734. echo " -graphtype : Specify the type of graph. Valid values are 'caller' and 'callee'. Default is 'callee'."
  1735. echo " -viewer : Specify the data viewer. Valid values are 'perf' and 'lttng'. Default is 'perf'."
  1736. echo ""
  1737. echo "livetrace:"
  1738. echo " Print EventSource events directly to the console. Root privileges not required."
  1739. echo ""
  1740. echo "install options:"
  1741. echo " Useful for first-time setup. Installs/upgrades perf_event and LTTng."
  1742. echo " -force : Force installation of required packages without prompt"
  1743. echo ""
  1744. }
  1745. ##
  1746. # Validate and set arguments.
  1747. ##
  1748. BuildPerfRecordArgs()
  1749. {
  1750. # Start with default collection arguments that record at realtime priority, all CPUs (-a), and collect call stacks (-g)
  1751. collectionArgs="record -k 1 -g"
  1752. # Filter to a single process if desired
  1753. if [ "$collectionPid" != "" ]
  1754. then
  1755. collectionArgs="$collectionArgs --pid=$collectionPid"
  1756. else
  1757. collectionArgs="$collectionArgs -a"
  1758. fi
  1759. # Enable CPU Collection
  1760. if [ $collect_cpu -eq 1 ]
  1761. then
  1762. collectionArgs="$collectionArgs"
  1763. eventsToCollect=( "${eventsToCollect[@]}" "cpu-clock" )
  1764. # If only collecting CPU events, set the sampling rate to 1000.
  1765. # Otherwise, use the default sampling rate to avoid sampling sched events.
  1766. if [ $collect_threadTime -eq 0 ] && [ $collect_offcpu -eq 0 ]
  1767. then
  1768. collectionArgs="$collectionArgs -F 1000"
  1769. fi
  1770. fi
  1771. if [ $collect_system -eq 1 ]
  1772. then
  1773. collectionArgs="$collectionArgs -e major-faults -e minor-faults"
  1774. fi
  1775. # Enable HW counters event collection
  1776. if [ $collect_HWevents -eq 1 ]
  1777. then
  1778. collectionArgs="$collectionArgs -e cycles,instructions,branches,cache-misses"
  1779. fi
  1780. # Enable context switches.
  1781. if [ $collect_threadTime -eq 1 ]
  1782. then
  1783. eventsToCollect=( "${eventsToCollect[@]}" "sched:sched_stat_sleep" "sched:sched_switch" "sched:sched_process_exit" )
  1784. fi
  1785. # Enable offcpu collection
  1786. if [ $collect_offcpu -eq 1 ]
  1787. then
  1788. eventsToCollect=( "${eventsToCollect[@]}" "sched:sched_stat_sleep" "sched:sched_switch" "sched:sched_process_exit" )
  1789. fi
  1790. # Build up the set of events.
  1791. local eventString=""
  1792. local comma=","
  1793. for (( i=0; i<${#eventsToCollect[@]}; i++ ))
  1794. do
  1795. # Get the arg.
  1796. eventName=${eventsToCollect[$i]}
  1797. # Build up the comma separated list.
  1798. if [ "$eventString" == "" ]
  1799. then
  1800. eventString=$eventName
  1801. else
  1802. eventString="$eventString$comma$eventName"
  1803. fi
  1804. done
  1805. if [ ! -z ${duration} ]
  1806. then
  1807. durationString="sleep ${duration}"
  1808. fi
  1809. # Add the events onto the collection command line args.
  1810. collectionArgs="$collectionArgs -e $eventString $durationString"
  1811. }
  1812. DoCollect()
  1813. {
  1814. # Ensure the script is run as root.
  1815. EnsureRoot
  1816. # Build collection args.
  1817. # Places the resulting args in $collectionArgs
  1818. BuildPerfRecordArgs
  1819. # Trap CTRL+C
  1820. trap CTRLC_Handler SIGINT
  1821. # Create a temp directory to use for collection.
  1822. local tempDir=`mktemp -d`
  1823. LogAppend "Created temp directory $tempDir"
  1824. # Switch to the directory.
  1825. pushd $tempDir > /dev/null
  1826. # Start LTTng collection.
  1827. if [ "$useLTTng" == "1" ]
  1828. then
  1829. StartLTTngCollection
  1830. fi
  1831. # Tell the user that collection has started and how to exit.
  1832. if [ "$duration" != "" ]
  1833. then
  1834. WriteStatus "Collection started. Collection will automatically stop in $duration second(s). Press CTRL+C to stop early."
  1835. elif [ "$action" == "start" ]
  1836. then
  1837. WriteStatus "Collection started."
  1838. else
  1839. WriteStatus "Collection started. Press CTRL+C to stop."
  1840. fi
  1841. # Start perf record.
  1842. if [ "$action" == "start" ]
  1843. then
  1844. # Skip perf, which can only be stopped by CTRL+C.
  1845. # Pass trace directory and session name to the stop process.
  1846. popd > /dev/null
  1847. usePerf=0
  1848. declare -p | grep -e lttngTraceDir -e lttngSessionName -e tempDir -e usePerf -e useLttng -e logFile > $collectInfoFile
  1849. else
  1850. if [ "$usePerf" == "1" ]
  1851. then
  1852. if [ ! -z ${duration} ]
  1853. then
  1854. RunSilent $perfcmd $collectionArgs
  1855. else
  1856. RunSilentBackground $perfcmd $collectionArgs
  1857. fi
  1858. else
  1859. # Wait here until CTRL+C handler gets called when user types CTRL+C.
  1860. LogAppend "Waiting for CTRL+C handler to get called."
  1861. waitTime=0
  1862. for (( ; ; ))
  1863. do
  1864. if [ "$handlerInvoked" == "1" ]
  1865. then
  1866. break;
  1867. fi
  1868. # Wait and then check to see if the handler has been invoked or we've crossed the duration threshold.
  1869. sleep 1
  1870. waitTime=$waitTime+1
  1871. if (( duration > 0 && duration <= waitTime ))
  1872. then
  1873. break;
  1874. fi
  1875. done
  1876. fi
  1877. # End collection if action is 'collect'.
  1878. EndCollect
  1879. fi
  1880. }
  1881. DoLiveTrace()
  1882. {
  1883. # Start the session
  1884. StartLTTngCollection
  1885. # View the event stream (until the user hits CTRL+C)
  1886. WriteStatus "Listening for events from LTTng. Hit CTRL+C to stop."
  1887. $lttngcmd view
  1888. # Stop the LTTng sessoin
  1889. StopLTTngCollection
  1890. }
  1891. # $1 == Path to directory containing trace files
  1892. PropSymbolsAndMapFilesForView()
  1893. {
  1894. # Get the current directory
  1895. local currentDir=`pwd`
  1896. # Copy map files to /tmp since they aren't supported by perf buildid-cache.
  1897. local mapFiles=`find -name *.map`
  1898. for mapFile in $mapFiles
  1899. do
  1900. echo "Copying $mapFile to /tmp."
  1901. cp $mapFile /tmp
  1902. done
  1903. # Cache all debuginfo files saved with the trace in the buildid cache.
  1904. local debugInfoFiles=`find $currentDir -name *.debuginfo`
  1905. for debugInfoFile in $debugInfoFiles
  1906. do
  1907. echo "Caching $debugInfoFile in buildid cache using perf buildid-cache."
  1908. $perfcmd buildid-cache --add=$debugInfoFile
  1909. done
  1910. }
  1911. SetEnvironment()
  1912. {
  1913. WriteStatus "Starting a new shell configured for profiling."
  1914. WriteStatus "When done, type 'exit' to exit the profiling shell."
  1915. bash -c 'export COMPlus_PerfMapEnabled=1;export COMPlus_EnableEventLog=1; exec bash'
  1916. WriteStatus "Profiling shell exited."
  1917. }
  1918. DoView()
  1919. {
  1920. # Generate a temp directory to extract the trace files into.
  1921. local tempDir=`mktemp -d`
  1922. # Extract the trace files.
  1923. $unzipcmd $inputTraceName -d $tempDir
  1924. # Move the to temp directory.
  1925. pushd $tempDir
  1926. cd `ls`
  1927. # Select the viewer.
  1928. if [ "$viewer" == "perf" ]
  1929. then
  1930. # Prop symbols and map files.
  1931. PropSymbolsAndMapFilesForView `pwd`
  1932. # Choose the view
  1933. if [ "$graphType" == "" ]
  1934. then
  1935. graphType="callee"
  1936. elif [ "$graphType" != "callee" ] && [ "$graphType" != "caller"]
  1937. then
  1938. FatalError "Invalid graph type specified. Valid values are 'callee' and 'caller'."
  1939. fi
  1940. # Filter to specific process names if desired.
  1941. if [ "$processFilter" != "" ]
  1942. then
  1943. processFilter="--comms=$processFilter"
  1944. fi
  1945. # Execute the viewer.
  1946. $perfcmd report -n -g graph,0.5,$graphType $processFilter $perfOpt
  1947. elif [ "$viewer" == "lttng" ]
  1948. then
  1949. babeltrace lttngTrace/ | more
  1950. fi
  1951. # Switch back to the original directory.
  1952. popd
  1953. # Delete the temp directory.
  1954. rm -rf $tempDir
  1955. }
  1956. #####################################
  1957. ## Main Script Start
  1958. #####################################
  1959. # No arguments
  1960. if [ "$#" == "0" ]
  1961. then
  1962. PrintUsage
  1963. exit 0
  1964. fi
  1965. # Install perf if requested. Do this before all other validation.
  1966. if [ "$1" == "install" ]
  1967. then
  1968. if [ "$2" == "-force" ]
  1969. then
  1970. forceInstall=1
  1971. fi
  1972. InstallPerf
  1973. InstallLTTng
  1974. exit 0
  1975. fi
  1976. # Discover external commands that will be called by this script.
  1977. DiscoverCommands
  1978. # Initialize the log.
  1979. if [ "$1" != "stop" ]
  1980. then
  1981. InitializeLog
  1982. fi
  1983. # Process arguments.
  1984. ProcessArguments $@
  1985. # Ensure prerequisites are installed.
  1986. EnsurePrereqsInstalled
  1987. # Take the appropriate action.
  1988. if [ "$action" == "collect" ] || [ "$action" == "start" ]
  1989. then
  1990. DoCollect
  1991. elif [ "$action" == "stop" ]
  1992. then
  1993. EndCollect
  1994. elif [ "$action" == "setenv" ]
  1995. then
  1996. SetEnvironment
  1997. elif [ "$action" == "view" ]
  1998. then
  1999. DoView
  2000. elif [ "$action" == "livetrace" ]
  2001. then
  2002. DoLiveTrace
  2003. fi

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小蓝xlanll/article/detail/115323
推荐阅读
相关标签
  

闽ICP备14008679号