|
1 // Copyright (c) 2004-2010 Nokia Corporation and/or its subsidiary(-ies). |
|
2 // All rights reserved. |
|
3 // This component and the accompanying materials are made available |
|
4 // under the terms of the License "Eclipse Public License v1.0" |
|
5 // which accompanies this distribution, and is available |
|
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
7 // |
|
8 // Initial Contributors: |
|
9 // Nokia Corporation - initial contribution. |
|
10 // |
|
11 // Contributors: |
|
12 // |
|
13 // Description: |
|
14 // Kernel Event handler for Run Mode Debug. |
|
15 // |
|
16 |
|
17 #include <e32def.h> |
|
18 #include <e32def_private.h> |
|
19 #include <e32cmn.h> |
|
20 #include <e32cmn_private.h> |
|
21 #include <kernel/arm/arm.h> |
|
22 #include <kernel/kernel.h> |
|
23 #include <kernel/kern_priv.h> |
|
24 #include <nk_trace.h> |
|
25 |
|
26 #include <rm_debug_api.h> |
|
27 #include "debug_logging.h" |
|
28 #include "d_process_tracker.h" |
|
29 #include "d_rmd_stepping.h" |
|
30 #include "rm_debug_kerneldriver.h" |
|
31 #include "rm_debug_driver.h" |
|
32 #include "rm_debug_eventhandler.h" |
|
33 |
|
34 |
|
35 DRM_DebugEventHandler::DRM_DebugEventHandler() |
|
36 : DKernelEventHandler(EventHandler, this) |
|
37 { |
|
38 LOG_MSG("DRM_DebugEventHandler::DRM_DebugEventHandler()"); |
|
39 |
|
40 for(TInt i=0; i<EEventLimit; i++) |
|
41 { |
|
42 iEventHandlers[i] = &DRM_DebugChannel::HandleUnsupportedEvent; |
|
43 } |
|
44 iEventHandlers[EEventUserTrace] = &DRM_DebugChannel::HandleUserTrace; |
|
45 iEventHandlers[EEventRemoveLibrary] = &DRM_DebugChannel::RemoveLibrary; |
|
46 iEventHandlers[EEventAddLibrary] = &DRM_DebugChannel::AddLibrary; |
|
47 iEventHandlers[EEventStartThread] = &DRM_DebugChannel::StartThread; |
|
48 iEventHandlers[EEventSwExc] = &DRM_DebugChannel::HandleSwException; |
|
49 iEventHandlers[EEventHwExc] = &DRM_DebugChannel::HandleHwException; |
|
50 iEventHandlers[EEventKillThread] = &DRM_DebugChannel::HandleEventKillThread; |
|
51 iEventHandlers[EEventAddProcess] = &DRM_DebugChannel::HandleAddProcessEvent; |
|
52 iEventHandlers[EEventRemoveProcess] = &DRM_DebugChannel::HandleRemoveProcessEvent; |
|
53 } |
|
54 |
|
55 TInt DRM_DebugEventHandler::Create(DLogicalDevice* aDevice, DLogicalChannel* aChannel, DThread* aClient) |
|
56 { |
|
57 LOG_MSG3("DRM_DebugEventHandler::Create(), aClientthread=0x%08x id=%d", aClient, aClient->iId); |
|
58 |
|
59 TInt err; |
|
60 err = aDevice->Open(); |
|
61 if (err != KErrNone) |
|
62 return err; |
|
63 iDevice = aDevice; |
|
64 |
|
65 iChannel = (DRM_DebugChannel*)aChannel; //Don't add ref the channel, since channel closes the event handler before it ever gets destroyed. |
|
66 |
|
67 err = aClient->Open(); |
|
68 if (err != KErrNone) |
|
69 return err; |
|
70 iClientThread = aClient; |
|
71 |
|
72 // Use a semaphore to protect our data structures from concurrent access. |
|
73 err = Kern::SemaphoreCreate(iProtectionLock, _L("RM_DebugEventHandlerLock"), 1 /* Initial count */); |
|
74 if (err != KErrNone) |
|
75 return err; |
|
76 |
|
77 |
|
78 return Add(); |
|
79 } |
|
80 |
|
81 |
|
82 DRM_DebugEventHandler::~DRM_DebugEventHandler() |
|
83 { |
|
84 LOG_MSG("DRM_DebugEventHandler::~DRM_DebugEventHandler()"); |
|
85 |
|
86 if (iProtectionLock) |
|
87 iProtectionLock->Close(NULL); |
|
88 |
|
89 if (iDevice) |
|
90 iDevice->Close(NULL); |
|
91 |
|
92 if (iClientThread) |
|
93 Kern::SafeClose((DObject*&)iClientThread, NULL); |
|
94 |
|
95 } |
|
96 |
|
97 |
|
98 TInt DRM_DebugEventHandler::Start() |
|
99 { |
|
100 LOG_MSG("DRM_DebugEventHandler::Start()"); |
|
101 |
|
102 iTracking = ETrue; |
|
103 |
|
104 return KErrNone; |
|
105 } |
|
106 |
|
107 |
|
108 TInt DRM_DebugEventHandler::Stop() |
|
109 { |
|
110 LOG_MSG("DRM_DebugEventHandler::Stop()"); |
|
111 |
|
112 iTracking = EFalse; |
|
113 |
|
114 return KErrNone; |
|
115 } |
|
116 |
|
117 |
|
118 TUint DRM_DebugEventHandler::EventHandler(TKernelEvent aType, TAny* a1, TAny* a2, TAny* aThis) |
|
119 { |
|
120 return ((DRM_DebugEventHandler*)aThis)->HandleEvent(aType, a1, a2); |
|
121 } |
|
122 |
|
123 |
|
124 |
|
125 TUint DRM_DebugEventHandler::HandleEvent(TKernelEvent aType, TAny* a1, TAny* a2) |
|
126 { |
|
127 |
|
128 /* |
|
129 * Check if we are tracking things at all OR |
|
130 * this event is beyond the limit of known events OR |
|
131 * this event is from the debug thread itself (don't want to debug ourselves) OR |
|
132 * this event has a handler (there is no point in proceeding without a handler) |
|
133 */ |
|
134 if( (!iTracking) || |
|
135 (aType > (TUint32)EEventLimit) || |
|
136 (iClientThread == &Kern::CurrentThread()) || |
|
137 (iEventHandlers[aType] == &DRM_DebugChannel::HandleUnsupportedEvent) ) |
|
138 { |
|
139 return ERunNext; |
|
140 } |
|
141 |
|
142 return HandleSpecificEvent(aType,a1,a2) && aType == EEventHwExc ? EExcHandled : ERunNext; |
|
143 |
|
144 |
|
145 } |
|
146 |
|
147 TBool DRM_DebugEventHandler::HandleSpecificEvent(TKernelEvent aType, TAny* a1, TAny* a2) |
|
148 { |
|
149 TBool ret = EFalse; |
|
150 |
|
151 NKern::ThreadEnterCS(); |
|
152 LockDataAccess(); |
|
153 |
|
154 |
|
155 if (iChannel) |
|
156 { |
|
157 ret = (iChannel->*(iEventHandlers[aType]))(a1, a2); |
|
158 } |
|
159 ReleaseDataAccess(); |
|
160 NKern::ThreadLeaveCS(); |
|
161 |
|
162 switch(aType) |
|
163 { |
|
164 case EEventHwExc: |
|
165 case EEventKillThread: |
|
166 { |
|
167 LOG_MSG2("DRM_DebugEventHandler::HandleEvent() -> FSWait(), kernel event type: %d", (TUint32)aType); |
|
168 TheDProcessTracker.FSWait(); |
|
169 LOG_MSG("DRM_DebugEventHandler::HandleEvent() <- FSWait()"); |
|
170 break; |
|
171 } |
|
172 default: |
|
173 break; |
|
174 } |
|
175 return ret; |
|
176 } |
|
177 |