if the application allocates aggressively, so many events will be fired so quickly that
events will be lost even when the
/BufferSizeMB qualifier is used to set the size very large (e.g. 500Meg). For these reasons it
- is usually a better idea to use the .NET SampAlloc
+ is usually a better idea to use the .NET SampAlloc
option instead if at all possible.
@@ -4143,7 +4143,7 @@
Advanced Options
reported is likely to be close to the true statistics.
The overhead of turning on .NET SampAlloc CheckBox is much less than the
- .NET Alloc CheckBox. Typically the overhead is
+ .NET Alloc CheckBox. Typically the overhead is
10-20% (unlike 2X or more), and produces 200 Meg per minute of trace. This is
a bit more expensive than turning on /threadTime however low enough that you can
leave it on in production (especially if the application does not allocate heavily).
@@ -5413,7 +5413,7 @@
Thread Time is not Elapsed Wall Clock Time
add up to more than elapsed wall clock time. This is easy to determine this is the case (because you will
see more than one thread as children of the activity), and you can even see the overlap
(by looking at the 'when' column of each of the children). Still it is something to
- be aware of. See Understanding Thread Time and for more.
+ be aware of. See Understanding Thread Time and for more.
It is also possible that the thread time will be LESS than elapsed wall clock time.
From ee7ef7605fc23fca8a2a7d674ea6d21cbb5c330b Mon Sep 17 00:00:00 2001
From: Bart Vries
Date: Wed, 11 Jun 2025 14:48:06 +0200
Subject: [PATCH 002/148] Throw exception then TdhEnumerateProviders fails,
which allows looking at the hr instead of causing an NRE which masks the
exception. (#2177)
---
src/TraceEvent/TraceEventSession.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/TraceEvent/TraceEventSession.cs b/src/TraceEvent/TraceEventSession.cs
index 728559c11..8752bfa17 100644
--- a/src/TraceEvent/TraceEventSession.cs
+++ b/src/TraceEvent/TraceEventSession.cs
@@ -1779,7 +1779,7 @@ internal static SortedDictionary ProviderNameToGuid
}
else
{
- Trace.WriteLine("TdhEnumerateProviders failed HR = " + hr);
+ throw new Exception("TdhEnumerateProviders failed HR = " + hr);
}
}
}
From 5cbea4fa83bbb7b20d449234840896478f0dc8ba Mon Sep 17 00:00:00 2001
From: Copilot <198982749+Copilot@users.noreply.github.com>
Date: Thu, 19 Jun 2025 15:23:42 -0700
Subject: [PATCH 003/148] Add AutomationProperties.Name to Process Selection
DataGrid for accessibility (#2239)
* Initial plan for issue
* Add AutomationProperties.Name to Process selection DataGrid for accessibility
Co-authored-by: brianrob <6210322+brianrob@users.noreply.github.com>
* Update name casing.
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: brianrob <6210322+brianrob@users.noreply.github.com>
Co-authored-by: Brian Robbins
---
src/PerfView/Dialogs/SelectProcess.xaml | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/src/PerfView/Dialogs/SelectProcess.xaml b/src/PerfView/Dialogs/SelectProcess.xaml
index 83c03b548..8798a5019 100644
--- a/src/PerfView/Dialogs/SelectProcess.xaml
+++ b/src/PerfView/Dialogs/SelectProcess.xaml
@@ -61,7 +61,8 @@
AutoGenerateColumns="False"
MouseDoubleClick="OKClicked"
IsReadOnly="True"
- ColumnHeaderStyle="{StaticResource ColumnHeaderStyle}">
+ ColumnHeaderStyle="{StaticResource ColumnHeaderStyle}"
+ AutomationProperties.Name="Process Selection Table">
```
I gave up on updating the Azure packages as they cause PerfView to fail at runtime. Would require a bit more time.
---
PerfView.sln | 10 +-
src/Directory.Build.props | 2 +-
src/Directory.Packages.props | 34 +-
src/PerfView/ClrStats.cs | 48 +-
src/PerfView/Dialogs/SelectProcess.xaml | 2 +
src/PerfView/EventViewer/EventWindow.xaml | 2 +
src/PerfView/GcStats.cs | 17 +-
.../GuiUtilities/WebBrowser/WebBrowser.xaml | 4 +-
.../WebBrowser/WebBrowser.xaml.cs | 17 +-
src/PerfView/MainWindow.xaml | 2 +-
src/PerfView/PerfView.csproj | 17 +-
src/PerfView/PerfViewData.cs | 129 +++--
src/PerfView/StackViewer/PerfDataGrid.xaml | 2 +
.../EventCounterVisualization.html | 6 +-
.../SupportFiles/HtmlReportUsersGuide.htm | 14 +-
.../SupportFiles/PerfViewWebVideos.htm | 18 +-
src/PerfView/SupportFiles/UsersGuide.htm | 532 +++++++++---------
src/PerfView/Themes/DarkTheme.xaml | 43 +-
src/PerfView/app.manifest | 10 +
19 files changed, 523 insertions(+), 386 deletions(-)
diff --git a/PerfView.sln b/PerfView.sln
index 033049177..e55ed9e79 100644
--- a/PerfView.sln
+++ b/PerfView.sln
@@ -1,4 +1,5 @@
-Microsoft Visual Studio Solution File, Format Version 12.00
+
+Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.4.32821.20
MinimumVisualStudioVersion = 15.0
@@ -38,6 +39,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
CONTRIBUTING.md = CONTRIBUTING.md
src\Directory.Build.props = src\Directory.Build.props
src\Directory.Build.targets = src\Directory.Build.targets
+ src\Directory.Packages.props = src\Directory.Packages.props
src\PerfViewCollect\PerfViewCollect.csproj = src\PerfViewCollect\PerfViewCollect.csproj
README.md = README.md
EndProjectSection
@@ -407,13 +409,13 @@ Global
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
+ GlobalSection(NestedProjects) = preSolution
+ {DE35BED9-0E03-4DAC-A003-1ACBBF816973} = {1CAEF854-2923-45FA-ACB8-6523A7E45896}
+ EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {9F85A2A3-E0DF-4826-9BBA-4DFFA0F17150}
EndGlobalSection
GlobalSection(TestCaseManagementSettings) = postSolution
CategoryFile = PerfView2.vsmdi
EndGlobalSection
- GlobalSection(NestedProjects) = preSolution
- {DE35BED9-0E03-4DAC-A003-1ACBBF816973} = {1CAEF854-2923-45FA-ACB8-6523A7E45896}
- EndGlobalSection
EndGlobal
diff --git a/src/Directory.Build.props b/src/Directory.Build.props
index 929e2686f..7814d0993 100644
--- a/src/Directory.Build.props
+++ b/src/Directory.Build.props
@@ -6,7 +6,7 @@
- 8.0
+ 11.0strict
diff --git a/src/Directory.Packages.props b/src/Directory.Packages.props
index 89b599aca..1a545da2b 100644
--- a/src/Directory.Packages.props
+++ b/src/Directory.Packages.props
@@ -19,27 +19,27 @@
-
-
-
-
-
+
+
+
+
+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
-
+
-
-
-
-
+
+
+
+
diff --git a/src/PerfView/ClrStats.cs b/src/PerfView/ClrStats.cs
index 574281211..19156a78a 100644
--- a/src/PerfView/ClrStats.cs
+++ b/src/PerfView/ClrStats.cs
@@ -16,20 +16,41 @@ public static void ToHtml(TextWriter writer, List perProc, string
{
if (!justBody)
{
- writer.WriteLine("");
- writer.WriteLine("");
- writer.WriteLine("{0}", Path.GetFileNameWithoutExtension(fileName));
- writer.WriteLine("");
- writer.WriteLine("");
- writer.WriteLine("");
- writer.WriteLine("");
+ writer.WriteLine($$"""
+
+
+ {{Path.GetFileNameWithoutExtension(fileName)}}
+
+
+
+
+
Contention Stacks - This view aggregates Contention events.
Contention event is fired when a thread tries to acquire a managed lock that is currently owned
by another thread. Note that each event has useful event data that is folded by default.
- For example, unfolding EventData DurationNs reveals individual pauses of each thread: this can be useful
+ For example, unfolding EventData DurationNs reveals individual pauses of each thread: this can be useful
to correlate a particular long wait to another events in the trace. Note that not all contention events
are real OS-level waits: the runtime may first spin wait to try acquire the lock fast. The metric
represents the amount of time spent to acquire the lock in milliseconds.
@@ -8031,7 +8038,7 @@
If your symbols are on an Azure DevOps artifacts store, or your source code is not public,
- then PerfView may prompt you to sign in. Support currently exists for Azure DevOps and private
+ then PerfView may prompt you to sign in. Support currently exists for Azure DevOps and private
GitHub repositories. If installed, PerfView will try to use the Git Credential Manager
which is typically installed with Git For Windows. If Git Credential Manager is not installed,
PerfView will fall back to alternate authentication mechanisms. The authentication mechanisms
@@ -8042,7 +8049,7 @@
Git Credential Manager. This is the most flexible option for developers
using Git. It works alongside your Git installation to sign into private repositories.
Support is currently enabled for Azure DevOps and GitHub. We hope to add GitLab and BitBucket
- support in the future.
+ support in the future.
PerfView will search for the Git Credential Manager executable (git-credential-manager-core.exe)
in a number of well-known locations, but if it can't be found, then the option will be
unavailable. If you have installed Git Credential Manager in a non-standard location, you can
@@ -8058,12 +8065,12 @@
into Visual Studio or VS Code using credentials that can access your Azure DevOps repo.
If you sign into Visual Studio with several different accounts, you may need to select the
right one in Tools/Options/Azure Service Authentication.
- See the Authentication and the Azure SDK
+ See the Authentication and the Azure SDK
blog posting for more information.
Device Code Flow for GitHub. This option, for GitHub only, uses a Device Code
- to grant PerfView access to GitHub private repositories.
+ to grant PerfView access to GitHub private repositories.
PerfView will prompt you with an 8 digit device code which you use to log into GitHub.com using
any web browser. The browser could be running on a different device, if necessary.
When you enter the code into the browser and approve the app, the dialog will automatically close
@@ -8071,10 +8078,10 @@
to access.
- Basic HTTP Authentication. This option allows you to use Basic HTTP authentication
- when connecting to a symbol server. To use it, you should specify the username and password in the URL for your symbol server. For example:
- SRV*SymbolCachePath*https://username:password@symbolstore.url;. This scheme is active by default but
- used only if the URL contains username and password information.
+ Basic HTTP Authentication. This option allows you to use Basic HTTP authentication
+ when connecting to a symbol server. To use it, you should specify the username and password in the URL for your symbol server. For example:
+ SRV*SymbolCachePath*https://username:password@symbolstore.url;. This scheme is active by default but
+ used only if the URL contains username and password information.
@@ -9164,63 +9171,64 @@
}
+
+
+ Version 1.8.28 2/4/16
+
- Version 1.8.28 2/4/16
-
-
- Added support doing performance investigations with Linux Perf Events data. Basically if
- collect data with the bash script https://raw.githubusercontent.com/dotnet/corefx-tools/master/src/performance/perfcollect/perfcollect
- it will runt the Linux 'perf' tool that will collect CPU samples, convert them to a .data.txt file
- (which is a textual representation of the data) and then ZIP it into a .trace.zip file PerfView
- knows how to decode either the uncompressed .data.txt file or the zipped .trace.zip file and
- display it as a stack view. Thus you can now do linux performance investigations with PerfView.
-
-
+ Added support doing performance investigations with Linux Perf Events data. Basically if
+ collect data with the bash script https://raw.githubusercontent.com/dotnet/corefx-tools/master/src/performance/perfcollect/perfcollect
+ it will runt the Linux 'perf' tool that will collect CPU samples, convert them to a .data.txt file
+ (which is a textual representation of the data) and then ZIP it into a .trace.zip file PerfView
+ knows how to decode either the uncompressed .data.txt file or the zipped .trace.zip file and
+ display it as a stack view. Thus you can now do linux performance investigations with PerfView.
+
+
+
+ Version 1.8.25 2/2/16
+
- Version 1.8.25 2/2/16
-
-
- Improvements in Start-Stop time. UNKNOWN_ASYNC displayed more often, some AWAIT time shown more often.
-
-
+ Improvements in Start-Stop time. UNKNOWN_ASYNC displayed more often, some AWAIT time shown more often.
+
+
+
+ Version 1.8.24 1/27/16
+
- Version 1.8.24 1/27/16
-
-
- When opening 'Drill Into' windows, the columns are not in the order of the parent window in the ByName view.
- Fixed this.
-
-
+ When opening 'Drill Into' windows, the columns are not in the order of the parent window in the ByName view.
+ Fixed this.
+
+
+
+ Version 1.8.23 1/26/16
+
- Version 1.8.23 1/26/16
-
-
- Merging failed on Win7 and Win2k8 systems in PerfView Version 1.8. This means you could still analyze on
- the machine where you collected, but symbols would fail to look up if you took the trace off the system.
- Fixed by including an old version of KernelTraceControl.dll an used it on Win7 systems.
-
-
+ Merging failed on Win7 and Win2k8 systems in PerfView Version 1.8. This means you could still analyze on
+ the machine where you collected, but symbols would fail to look up if you took the trace off the system.
+ Fixed by including an old version of KernelTraceControl.dll an used it on Win7 systems.
+
+
+
+ Version 1.8.22 1/23/16
+
- Version 1.8.22 1/23/16
-
-
- Fixed ArgumentOutOfRange exceptions thrown in EventView for some events (strings with length prefixes)
-
-
Don't crash if regular expressions are incorrect in Events view.
-
+ Fixed ArgumentOutOfRange exceptions thrown in EventView for some events (strings with length prefixes)
+
Don't crash if regular expressions are incorrect in Events view.
+
+
+
+ Version 1.8.21 1/18/16
+
- Version 1.8.21 1/18/16
-
-
- Extended perfView.xml file format so that it can more easily consume 'ad hoc' creation of stacks.
- It still accepts the 'interned' scheme where you give IDs to each frame and stack and use those
- to create samples, but now you can specify the samples inline with the sample like this
-
+ Extended perfView.xml file format so that it can more easily consume 'ad hoc' creation of stacks.
+ It still accepts the 'interned' scheme where you give IDs to each frame and stack and use those
+ to create samples, but now you can specify the samples inline with the sample like this
+
- While this format is inefficient (you repeat many strings in many stacks), it is sometimes
- convenient, and it is easy enough to support. There are more details which I will blog about in
- the near future.
-
-
+ While this format is inefficient (you repeat many strings in many stacks), it is sometimes
+ convenient, and it is easy enough to support. There are more details which I will blog about in
+ the near future.
+
+
+
+ Version 1.8.20 1/13/16
+
- Version 1.8.20 1/13/16
-
-
- Improved the robustness of the UserCommand 'Listen' command in the face of bad events.
-
-
+ Improved the robustness of the UserCommand 'Listen' command in the face of bad events.
+
+
+
+ Version 1.8.19 1/7/16
+
- Version 1.8.19 1/7/16
-
-
- Significantly improved the Thread Time with Start-Stop Activities. The goal here is
- that this view replaces the ASP.NET and Service Request view, and we are probably most of
- the way there now. I need to validate this more and then probably obsolete the other views.
-
-
+ Significantly improved the Thread Time with Start-Stop Activities. The goal here is
+ that this view replaces the ASP.NET and Service Request view, and we are probably most of
+ the way there now. I need to validate this more and then probably obsolete the other views.
+
+
+
+ Version 1.8.15 12/4/15
+
- Version 1.8.15 12/4/15
-
-
- Fixed a fairly serious bug associated with the Events Viewer where you don't see some CLR events
- (They appear in the left pane, but you never see them in the right pane even though there are
- instances of them in the file). Note that version 1.8.0 does not have this bug, it was introduced
- relatively recently.
-
-
- Added ActivityInfo and StartStopActivity fields to Events View. ActivityInfo will show you the
- creation and start time (and the raw ID) of the System.Threading.Tasks.Task that logged the event.
- StartStopActivity shows you the name of the start-stop activity that
- is logged the event.
-
-
+ Fixed a fairly serious bug associated with the Events Viewer where you don't see some CLR events
+ (They appear in the left pane, but you never see them in the right pane even though there are
+ instances of them in the file). Note that version 1.8.0 does not have this bug, it was introduced
+ relatively recently.
- Version 1.8.15 12/4/15
-
-
- Fixed a fairly serious bug associated with the Events Viewer where you don't see some CLR events
- (They appear in the left pane, but you never see them in the right pane even though there are
- instances of them in the file). Note that version 1.8.0 does not have this bug, it was introduced
- relatively recently.
-
-
- Added ActivityInfo and StartStopActivity fields to Events View. ActivityInfo will show you the
- creation and start time (and the raw ID) of the System.Threading.Tasks.Task that logged the event.
- StartStopActivity shows you the name of the start-stop activity that
- is logged the event.
-
-
+ Added ActivityInfo and StartStopActivity fields to Events View. ActivityInfo will show you the
+ creation and start time (and the raw ID) of the System.Threading.Tasks.Task that logged the event.
+ StartStopActivity shows you the name of the start-stop activity that
+ is logged the event.
+
+
+
+ Version 1.8.15 12/4/15
+
- Version 1.8.11 11/16/15
-
-
- Fix excessive warnings when converting ETL files. Might also fix some StartStop Activity issues.
-
-
+ Fixed a fairly serious bug associated with the Events Viewer where you don't see some CLR events
+ (They appear in the left pane, but you never see them in the right pane even though there are
+ instances of them in the file). Note that version 1.8.0 does not have this bug, it was introduced
+ relatively recently.
- Version 1.8.10 11/12/15
-
-
- Significant improvement in how activity tracking works. Hopefully the stacks associated with 'with Tasks' views
- will be better.
-
-
- Added JIT Inlining feature that enables viewing all successful and failed inlining attempts, including the
- JIT-supplied reason for why inlining wasn't performed in the failure cases.
-
-
- Added finalization feature that tracks finalized objects and provides a table of each type with a finalized object
- and the associated number of times an object of that type was finalized.
-
-
+ Added ActivityInfo and StartStopActivity fields to Events View. ActivityInfo will show you the
+ creation and start time (and the raw ID) of the System.Threading.Tasks.Task that logged the event.
+ StartStopActivity shows you the name of the start-stop activity that
+ is logged the event.
+
+
+
+ Version 1.8.11 11/16/15
+
- Version 1.8.9 11/1/15
-
-
- There is a bug in RC candidates of V4.6.1 where NGEN createPdb only works if the path of the NGEN image
- is in the Native Image Cache (NIC), but V4.6.1 uses hard links for NGEN images that come from the install itself.
- The result is that you don't get symbols for mscorlib, system, and system.core. This adds a work-around
- for this (normally all paths to the NIC path before calling NGEN CreatePdb), until the runtime is fixed.
-
-
+ Fix excessive warnings when converting ETL files. Might also fix some StartStop Activity issues.
+
+
+
+ Version 1.8.10 11/12/15
+
- Version 1.8.8 10/31/15
-
-
- Added support for .NET V4.6.2 convention for NGEN PDB line numbers. This means that if data is collected on
- a V4.6.2 then the lack of access IL PDBS are not available at data collection time is not longer an
- impediment to getting line number information (that is access to the corresponding IL pdb with line number
- information is no longer needed to create an NGEN pdb that has line number information).
-
-
+ Significant improvement in how activity tracking works. Hopefully the stacks associated with 'with Tasks' views
+ will be better.
- Version 1.8.7 10/22/15
-
-
- Integrated changes that allow DyanamicTraceEventParser to do everything that RegisteredTraceEventParser can do.
- Removed the calls to RegisteredTraceEventParser. This could break things but should not. So far things look
- OK.
-
-
+ Added JIT Inlining feature that enables viewing all successful and failed inlining attempts, including the
+ JIT-supplied reason for why inlining wasn't performed in the failure cases.
- Version 1.8.6 10/12/15
-
-
- Integrated Lee's update of CLRMD that should make PerfView able to extract heap dumps from debugger dumps of
- .NET Native processes.
-
-
Added the DotNet (Telemetry) event ETW provider by default.
-
+ Added finalization feature that tracks finalized objects and provides a table of each type with a finalized object
+ and the associated number of times an object of that type was finalized.
+
+
+
+ Version 1.8.9 11/1/15
+
- Version 1.8.5 10/6/15
-
-
- Made 'Any Stacks (with StartStop Activities)' and 'Any StartStopTree' public.
-
-
+ There is a bug in RC candidates of V4.6.1 where NGEN createPdb only works if the path of the NGEN image
+ is in the Native Image Cache (NIC), but V4.6.1 uses hard links for NGEN images that come from the install itself.
+ The result is that you don't get symbols for mscorlib, system, and system.core. This adds a work-around
+ for this (normally all paths to the NIC path before calling NGEN CreatePdb), until the runtime is fixed.
+
+
+
+ Version 1.8.8 10/31/15
+
- Version 1.8.3 9/23/15
-
-
- Turned off System.Threading.Tasks.Task events that are verbose and only needed for debugging. This was
- useful before so that any traces I get have detailed information for debugging, but are now impacting
- the cost of using PerfView in production when Tasks are used heavily.
-
-
+ Added support for .NET V4.6.2 convention for NGEN PDB line numbers. This means that if data is collected on
+ a V4.6.2 then the lack of access IL PDBS are not available at data collection time is not longer an
+ impediment to getting line number information (that is access to the corresponding IL pdb with line number
+ information is no longer needed to create an NGEN pdb that has line number information).
+
+
+
+ Version 1.8.7 10/22/15
+
- Version 1.8.2 9/13/15
-
-
/InMemoryCircularBuffer option was broken (Would throw a file not found exception in SetFileName). Fixed this.
-
+ Integrated changes that allow DyanamicTraceEventParser to do everything that RegisteredTraceEventParser can do.
+ Removed the calls to RegisteredTraceEventParser. This could break things but should not. So far things look
+ OK.
+
+
+
+ Version 1.8.6 10/12/15
+
- Version 1.8.1 9/3/15
-
-
- Fixed issue where Debug versions were asserting that two stacks were attached to the same event
- because kernel and user mode stacks were not being stitched together properly (mostly in rare cases
- where thread-starts were happening)
-
-
+ Integrated Lee's update of CLRMD that should make PerfView able to extract heap dumps from debugger dumps of
+ .NET Native processes.
-
+
Added the DotNet (Telemetry) event ETW provider by default.
+
+
+
+ Version 1.8.5 10/6/15
+
- Version 1.8.0 8/30/15
-
-
Release to Web.
-
+ Made 'Any Stacks (with StartStop Activities)' and 'Any StartStopTree' public.
+
+
+
+ Version 1.8.3 9/23/15
+
- Version 1.7.31 8/19/15
-
-
- Update code that does merging so it works properly on Win10. It does not have an effect if you look
- at the events with PerfView, but on Win10 until this change, data collected with PerfView would not
- parse EventSource events properly in WPA.
-
-
+ Turned off System.Threading.Tasks.Task events that are verbose and only needed for debugging. This was
+ useful before so that any traces I get have detailed information for debugging, but are now impacting
+ the cost of using PerfView in production when Tasks are used heavily.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+ Version 1.8.2 9/13/15
+
+
/InMemoryCircularBuffer option was broken (Would throw a file not found exception in SetFileName). Fixed this.
+
+
+
+ Version 1.8.1 9/3/15
+
+
+ Fixed issue where Debug versions were asserting that two stacks were attached to the same event
+ because kernel and user mode stacks were not being stitched together properly (mostly in rare cases
+ where thread-starts were happening)
+
+
+
+
+ Version 1.8.0 8/30/15
+
+
Release to Web.
+
+
+
+ Version 1.7.31 8/19/15
+
+
+ Update code that does merging so it works properly on Win10. It does not have an effect if you look
+ at the events with PerfView, but on Win10 until this change, data collected with PerfView would not
+ parse EventSource events properly in WPA.
+