How do I profile a Haskell application via stack ghci? - haskell-stack

I'm running stack ghci --profile (I determined this from https://docs.haskellstack.org/en/stable/GUIDE/#debugging) however I don't see any files generated that end with .prof?
Where is the profile data output to? Or how can I verify profiling is enabled?

Related

Can not load or initialize mscordaccore.dll when analyzing a core dump with dotnet-dump analyze

I am trying to analyze a core dump using dotnet-dump tool via cmd:
tmp>dotnet-dump analyze core.2293
Loading core dump: core.2293 ...
Ready to process analysis commands. Type 'help' to list available commands or 'help [command]' to get detailed help on a command.
Type 'quit' or 'exit' to exit the session.
As documentation tells it brings up an interactive session that accepts a variety of instructions to get debug info.
In my case, every command fails with the message like this:
> pe -lines
Failed to load data access module, 0x80004002
Can not load or initialize mscordaccore.dll. The target runtime may not be initialized.
For more information see https://go.microsoft.com/fwlink/?linkid=2135652
>
p/s Link above doesn't help much.
Do you have any suggestions on how to fix it?
Solved. The limitation is that process dumps are not portable. It is not possible to diagnose dumps collected on Linux with Windows and vice-versa.
The dump was collected on a Linux machine. And I were trying to analyze it on a Windows machine.
To analyze it properly you should set up a Linux environment. In my case, it was done by creating a docker container with an sdk:alpine image.

Read Performance counter in Mac from terminal

I would like to know how to get
performance monitoring counter measurements on a Mac. With Linux, we
can use the "perf stat" command to get measurements. With a Mac it's
harder. Specifically, I would like to know how I can get the number of
branch mispredictions and the number of branches executed for a
program running from the command line, preferably without recompiling
the program. I have done some Googling but what I need is a solution;
if you can show me how you brought up a terminal, typed in some
command (maybe using some tool you downloaded), and got the number of
mispredictions for, say /bin/ls, that would be great.
Official macOS tool to work with profiling, both based on software events and on hardware events (performance counters), is Instruments tool - https://help.apple.com/instruments/mac/current/. It seems to be part of XCode development tools.
This tool have some limited variants to collect profiles from command-line mode, check https://help.apple.com/instruments/mac/current/#/devb14ffaa5
https://help.apple.com/instruments/mac/current/#/devba105ecc
Launch Instruments from the command line
You can use the open command to launch any app in OS X via Terminal,
including Instruments.
Launch Terminal (in /Applications/Utilities/).
Run the following command:
open /Applications/Xcode.app/Contents/Applications/Instruments.app
The Instruments app launches.
Note: You can also use either of two command-line utilities to profile
an app without actually displaying the Instruments user interface.
instruments — This utility profiles an app using a specified template. The results can be saved to a file and then manually opened
in the main Instruments app for viewing and analysis. To learn more,
go to Profile with the instruments command-line tool.
To get IPC or branches, use GUI to create profile with usage of counters usage (1 or 2) and save it as template, and then use CLI tool instruments to collect trace data. Trace file can be viewed with Instruments GUI; there was incomplete attempt to decode that files.
The page https://medium.com/#pavelkucera/counting-branch-mispredictions-on-macos-7397ae8c5b51 also lists another variant to work with hardware counters on macOS, the https://github.com/opcm/pcm project:
You first have to build the tool, but then it is easy to use:
run pmu-query.py
enter “BR_INST_RETIRED.NOT_TAKEN”, the result should be similar to: cpu/umask=0x10,event=0xC4,name=BR_INST_RETIRED.NOT_TAKEN/
run ./pcm-core.x -e event where “event” stands for the result from the previous step
This gives you continuous results for all the running processes. Find
info on how to profile a single process in ./pmc-core.x --help
The good news is that results are easily readable as they can be
output as csv file. The bad news is that profiling a single process
still includes activity from other processes.

Windows Performance Analyzer Missing ImageId Event

I have an application, that I want to profile using Windows Performance Analyzer. It all works, but I don't get any reasonable stack traces from my application.
The application in question is a demo application. This is to give me a good feeling if all checks out. Then I want to profile another application. Since I have full control over my demo application, I included some marker functions, that should show up in the stack trace.
When running the application on Windwos 71, Process Explorer shows the correct stack trace for the part, that I want to profile. Here is the stack trace with the marker functions in lines 7 - 9:
Since I installed all performance analytics tools insinde a Windows 10 VM2, I started profiling there. The first thing to notice: Process Explorer does not show the correct stack trace. The marker functions that I implemented are nowhere to be found.
Nevertheless, I recorded performance traces using UIforETW and Windows Performance Recorder. When opening them in WPA and focussing on the target application, this is the stack trace:
All the information, I'm interested in is missing. The stack shows up as <Application>.exe!<Missing ImageId event>
What did I do wrong?
If this gives you a hint, here is the relevant software, that is installed:
1: The Windows 7 computer has Visual Studio (C#) installed.
2: The Windows 10 VM dowsn't have Visual Studio, but has WinDBG (Preview) and Windows Performance Toolkit installed.
I tagged delphi, because the target application is written in Delphi.
The Windows 10 WPA (as well as Windows 8.1, to a lesser extent) dropped support for older debug symbol formats; it now only supports the "RSDS" format that has been standard since MSVC 7. PE files using older symbol file formats (for example, VB6 generates NB10 PDB files) will result in that "Missing ImageId event" error.
(The message itself is technically incorrect; there likely is an ImageId even in the trace file but it is looking for an ImageId/DbgID_RSDS event, which can't be generated for non-RSDS PDBs)
<Missing ImageId event> will also be reported when the session is not merged with the "NT Kernel Logger" which provides some information necessary to resolve the symbols.
The "proper" way to stop the session is:
xperf.exe -stop my_trace -stop -d merged_trace.etl
Note that second -stop in necessary to stop another session (implicitly "NT Kernel Logger"), and -d to merge both into the merged_trace.etl.

How to build an application that displays more stack information in Process Monitor?

I've just discovered Sysinternal's Process Monitor and love the insights it gives on what a process is doing. However, when I try to see detail of a software call to the kernel, the stack is filled with "unknowns". How should I build my application so that function names appear at the stack trace?
Often compiling it with /Zi, and linking it with /debug should be enough.
You should get a PDB file which contains all the debug information of your application. As long as you don't move the executable or PDB, Process Monitor should normally find it.
If you have multiple versions of your application, or if you want to investigate the call stack on other machines, it might be better to set up a Symbol Server. You then need to store all your EXE's and PDB files into the Symbol Server (using the symstore utility), and set up your system so that Process Monitor uses the Symbol Server to find the debug information. The information at http://support.microsoft.com/kb/311503 should get your started.
One way that works normally is to set an environment variable _NT_SYMBOL_PATH:
set _NT_SYMBOL_PATH=symsrv*symsrv.dll*\\yourserver\symbols*http://msdl.microsoft.com/download/symbols
... where \\yourserver\symbols would be a share that is writable and readable, but could just as well be a local path on your computer. This is where the symbols get cached for repeated use.

How to extract stack traces from minidumps?

I've got a whole bunch of minidumps which were recorded during the runtime of an application through MiniDumpWriteDump. The minidumps were created on a machine with a different OS version than my development machine.
Now I'm trying to write a program to extract stack traces from the minidumps, using dbghelp.dll. I'm walking the MINIDUMP_MODULE_LIST and call SymLoadModule64, but this fails to download the pdbs (kernel32 etc.) from the public symbol server. If I add "C:\Windows\System32" to the symbol path it finds the dlls and downloads the symbols, but of course they don't match the dlls from the minidump, so the results are useless.
So how do I tell dbghelp.dll to download and use the proper pdbs?
[edit]
I forgot to state that SymLoadModule64 only takes a filename and no version/checksum information, so obviously with SymLoadModule64 alone it's impossible for dbghelp to figure out which pdb to download.
The information is actually available in the MINIDUMP_MODULE_LIST but I don't know how to pass it back to the dbghelp API.
There is SymLoadModuleEx which takes additional parameters, but I have no idea if that's what I need or what I should pass for the additional parameters.
[edit]
No luck so far, though I've noticed there's also dbgeng.dll distributed together with dbghelp.dll in the debugging SDK. MSDN looks quite well documented and says it's the same engine as windbg uses. Maybe I can use that to extract the stack traces.
If anyone can point me to some introduction to using dbgeng.dll to process minidumps that would probably help too, as the MSDN documents only the individual components but not how they work together.
Just in case anyone else wants to automate extracting stack traces from dumps, here's what I ended up doing:
Like I mentioned in the update it's possible to use dbgeng.dll instead of dbghelp.dll, which seems to be the same engine WinDbg uses. After some trial and error here's how to get a good stack trace with the same symbol loading mechanism as WinDbg.
call DebugCreate to get an instance of the debug engine
query for IDebugClient4, IDebugControl4, IDebugSymbols3
use IDebugSymbols3.SetSymbolOptions to configure how symbols are loaded (see MSDN for the options WinDbg uses)
use IDebugSymbols3.SetSymbolPath to set the symbol path like you would do in WinDbg
use IDebugClient4.OpenDumpFileWide to open the dump
use IDebugControl4.WaitForEvent to wait until the dump is loaded
use IDebugSymbols3.SetScopeFromStoredEvent to select the exception stored in the dump
use IDebugControl4.GetStackTrace to fetch the last few stack frames
use IDebugClient4.SetOutputCallbacks to register a listener receiving the decoded stack trace
use IDebugControl4.OutputStackTrace to process the stack frames
use IDebugClient4.SetOutputCallbacks to unregister the callback
release the interfaces
The call to WaitForEvent seems to be important because without it the following calls fail to extract the stack trace.
Also there still seems to be some memory leak in there, can't tell if it's me not cleaning up properly or something internal to dbgeng.dll, but I can just restart the process every 20 dumps or so, so I didn't investigate more.
An easy way to automate the analysis of multiple minidump files is to use the scripts written by John Robbins in his article "Automating Analyzing Tons Of Minidump Files With WinDBG And PowerShell" (you can grab the code on GitHub).
This is easy to tweak to have it perform whatever WinDbg commands you'd like it to, if the default setup is not sufficient.

Resources