branch | RCL_3 |
changeset 21 | e7d2d738d3c2 |
parent 0 | a41df078684a |
20:597aaf25e343 | 21:e7d2d738d3c2 |
---|---|
57 |
57 |
58 // |
58 // |
59 // DRM_DebugDriverFactory constructor |
59 // DRM_DebugDriverFactory constructor |
60 // |
60 // |
61 DRM_DebugDriverFactory::DRM_DebugDriverFactory() |
61 DRM_DebugDriverFactory::DRM_DebugDriverFactory() |
62 { |
62 { |
63 iVersion = TVersion(KMajorVersionNumber,KMinorVersionNumber,KBuildVersionNumber); |
63 iVersion = TVersion(KMajorVersionNumber,KMinorVersionNumber,KBuildVersionNumber); |
64 } |
64 } |
65 |
65 |
66 // |
66 // |
67 // DRM_DebugDriverFactory::Create |
67 // DRM_DebugDriverFactory::Create |
68 // |
68 // |
69 TInt DRM_DebugDriverFactory::Create(DLogicalChannelBase*& aChannel) |
69 TInt DRM_DebugDriverFactory::Create(DLogicalChannelBase*& aChannel) |
70 { |
70 { |
71 if (iOpenChannels != 0) |
71 if (iOpenChannels != 0) |
72 return KErrInUse; // a channel is already open |
72 return KErrInUse; // a channel is already open |
73 |
73 |
74 aChannel = new DRM_DebugChannel(this); |
74 aChannel = new DRM_DebugChannel(this); |
75 |
75 |
76 return aChannel ? KErrNone : KErrNoMemory; |
76 return aChannel ? KErrNone : KErrNoMemory; |
77 } |
77 } |
78 |
78 |
79 // |
79 // |
80 // DRM_DebugDriverFactory::Install |
80 // DRM_DebugDriverFactory::Install |
81 // |
81 // |
82 TInt DRM_DebugDriverFactory::Install() |
82 TInt DRM_DebugDriverFactory::Install() |
83 { |
83 { |
84 return(SetName(&KRM_DebugDriverName)); |
84 return(SetName(&KRM_DebugDriverName)); |
85 } |
85 } |
86 |
86 |
87 // |
87 // |
88 // DRM_DebugDriverFactory::Install |
88 // DRM_DebugDriverFactory::Install |
89 // |
89 // |
90 void DRM_DebugDriverFactory::GetCaps(TDes8& aDes) const |
90 void DRM_DebugDriverFactory::GetCaps(TDes8& aDes) const |
91 { |
91 { |
92 TCapsRM_DebugDriver b; |
92 TCapsRM_DebugDriver b; |
93 b.iVersion = TVersion(KMajorVersionNumber, KMinorVersionNumber, KBuildVersionNumber); |
93 b.iVersion = TVersion(KMajorVersionNumber, KMinorVersionNumber, KBuildVersionNumber); |
94 |
94 |
95 Kern::InfoCopy(aDes,(TUint8*)&b,sizeof(b)); |
95 Kern::InfoCopy(aDes,(TUint8*)&b,sizeof(b)); |
96 } |
96 } |
97 |
97 |
98 ///////////////////////////////////////////////////////////////////////// |
98 ///////////////////////////////////////////////////////////////////////// |
99 // |
99 // |
100 // DRM_DebugChannel implementation |
100 // DRM_DebugChannel implementation |
101 // |
101 // |
104 // |
104 // |
105 // DRM_DebugChannel constructor |
105 // DRM_DebugChannel constructor |
106 // |
106 // |
107 DRM_DebugChannel::DRM_DebugChannel(DLogicalDevice* aLogicalDevice) |
107 DRM_DebugChannel::DRM_DebugChannel(DLogicalDevice* aLogicalDevice) |
108 : iExcludedROMAddressStart(ROM_LINEAR_BASE), |
108 : iExcludedROMAddressStart(ROM_LINEAR_BASE), |
109 iExcludedROMAddressEnd(0), |
109 iExcludedROMAddressEnd(0), |
110 iPageSize(0x1000), |
110 iPageSize(0x1000), |
111 iBreakManager(0), |
111 iBreakManager(0), |
112 iStepper(0), |
112 iStepper(0), |
113 iStepLock(0), |
113 iStepLock(0), |
114 iDfcQ(NULL), |
114 iDfcQ(NULL), |
115 iInitialisedCodeModifier(0), |
115 iInitialisedCodeModifier(0), |
116 iAsyncGetValueRequest(NULL) |
116 iAsyncGetValueRequest(NULL) |
117 { |
117 { |
118 LOG_MSG("DRM_DebugChannel::DRM_DebugChannel()"); |
118 LOG_MSG("DRM_DebugChannel::DRM_DebugChannel()"); |
119 |
119 |
120 iDevice = aLogicalDevice; |
120 iDevice = aLogicalDevice; |
121 |
121 |
122 iClientThread = &Kern::CurrentThread(); |
122 iClientThread = &Kern::CurrentThread(); |
123 iClientThread->Open(); |
123 iClientThread->Open(); |
124 |
124 |
125 LOG_MSG3("DRM_DebugChannel::DRM_DebugChannel() clientThread = 0x%08x, id=%d", |
|
126 iClientThread, iClientThread->iId ); |
|
127 |
|
128 |
|
125 iPageSize = Kern::RoundToPageSize(1); |
129 iPageSize = Kern::RoundToPageSize(1); |
126 } |
130 } |
127 |
131 |
128 // |
132 // |
129 // DRM_DebugChannel destructor |
133 // DRM_DebugChannel destructor |
130 // |
134 // |
131 DRM_DebugChannel::~DRM_DebugChannel() |
135 DRM_DebugChannel::~DRM_DebugChannel() |
132 { |
136 { |
133 LOG_MSG("DRM_DebugChannel::~DRM_DebugChannel()"); |
137 LOG_MSG("DRM_DebugChannel::~DRM_DebugChannel()"); |
134 |
138 |
135 if (iAsyncGetValueRequest) |
139 if (iAsyncGetValueRequest) |
136 { |
140 { |
137 Kern::QueueRequestComplete(iClientThread, iAsyncGetValueRequest, KErrCancel); // does nothing if request not pending |
141 Kern::QueueRequestComplete(iClientThread, iAsyncGetValueRequest, KErrCancel); // does nothing if request not pending |
138 Kern::DestroyClientRequest(iAsyncGetValueRequest); |
142 Kern::DestroyClientRequest(iAsyncGetValueRequest); |
139 } |
143 } |
140 |
144 |
141 NKern::ThreadEnterCS(); |
145 NKern::ThreadEnterCS(); |
142 Kern::SafeClose((DObject*&)iClientThread, NULL); |
146 Kern::SafeClose((DObject*&)iClientThread, NULL); |
143 NKern::ThreadLeaveCS(); |
147 NKern::ThreadLeaveCS(); |
144 |
148 |
145 // Close breakpoint manager |
149 // Close breakpoint manager |
146 if (iBreakManager) |
150 if (iBreakManager) |
147 { |
151 { |
148 NKern::ThreadEnterCS(); |
152 NKern::ThreadEnterCS(); |
149 delete iBreakManager; |
153 delete iBreakManager; |
150 NKern::ThreadLeaveCS(); |
154 NKern::ThreadLeaveCS(); |
151 } |
155 } |
152 |
156 |
153 // Close stepping manager |
157 // Close stepping manager |
154 if (iStepper) |
158 if (iStepper) |
155 { |
159 { |
156 NKern::ThreadEnterCS(); |
160 NKern::ThreadEnterCS(); |
157 delete iStepper; |
161 delete iStepper; |
158 NKern::ThreadLeaveCS(); |
162 NKern::ThreadLeaveCS(); |
159 } |
163 } |
160 |
164 |
161 //close the debug process list |
165 //close the debug process list |
162 iDebugProcessList.Close(); |
166 iDebugProcessList.Close(); |
163 |
167 |
164 DestroyDfcQ(); |
168 DestroyDfcQ(); |
165 |
169 |
166 //close the code modifier |
170 //close the code modifier |
167 if (iInitialisedCodeModifier) |
171 if (iInitialisedCodeModifier) |
168 { |
172 { |
169 DebugSupport::CloseCodeModifier(); |
173 DebugSupport::CloseCodeModifier(); |
170 } |
174 } |
171 } |
175 } |
172 |
176 |
173 void DRM_DebugChannel::DestroyDfcQ() |
177 void DRM_DebugChannel::DestroyDfcQ() |
174 { |
178 { |
175 LOG_MSG("DRM_DebugChannel::DestroyDfcQ()"); |
179 LOG_MSG("DRM_DebugChannel::DestroyDfcQ()"); |
176 if (iDfcQ) |
180 if (iDfcQ) |
183 |
187 |
184 // |
188 // |
185 // DRM_DebugChannel::DoCreate |
189 // DRM_DebugChannel::DoCreate |
186 // |
190 // |
187 TInt DRM_DebugChannel::DoCreate(TInt /*aUnit*/, const TDesC* anInfo, const TVersion& aVer) |
191 TInt DRM_DebugChannel::DoCreate(TInt /*aUnit*/, const TDesC* anInfo, const TVersion& aVer) |
188 { |
192 { |
189 LOG_MSG("DRM_DebugChannel::DoCreate()"); |
193 LOG_MSG("DRM_DebugChannel::DoCreate()"); |
190 TInt err = Kern::CreateClientDataRequest(iAsyncGetValueRequest); |
194 TInt err = Kern::CreateClientDataRequest(iAsyncGetValueRequest); |
191 if(err != KErrNone) |
195 if(err != KErrNone) |
192 return err; |
196 return err; |
193 |
197 |
194 if (!Kern::QueryVersionSupported(TVersion(KMajorVersionNumber, KMinorVersionNumber, KBuildVersionNumber), aVer)) |
198 if (!Kern::QueryVersionSupported(TVersion(KMajorVersionNumber, KMinorVersionNumber, KBuildVersionNumber), aVer)) |
195 return KErrNotSupported; |
199 return KErrNotSupported; |
196 |
200 |
197 // Do the security check here so that any arbitrary application doesn't make |
201 // Do the security check here so that any arbitrary application doesn't make |
198 // use of Trk kernel driver. |
202 // use of Trk kernel driver. |
199 if (!DoSecurityCheck()) |
203 if (!DoSecurityCheck()) |
200 { |
204 { |
201 LOG_MSG("DRM_DebugChannel::DoCreate() - permission denied!"); |
205 LOG_MSG("DRM_DebugChannel::DoCreate() - permission denied!"); |
202 return KErrPermissionDenied; |
206 return KErrPermissionDenied; |
203 } |
207 } |
204 |
208 |
205 if (anInfo) |
209 if (anInfo) |
206 { |
210 { |
207 // this is the end address of the user library. |
211 // this is the end address of the user library. |
208 // this doesn't seem to be valid for EKA2. |
212 // this doesn't seem to be valid for EKA2. |
209 // right now we dont need this for EKA2 since we are not worried |
213 // right now we dont need this for EKA2 since we are not worried |
210 // about kernel being stopped as kernel is multithreaded. |
214 // about kernel being stopped as kernel is multithreaded. |
211 // just retaining this for future use. |
215 // just retaining this for future use. |
212 TBuf8<32> buf; |
216 TBuf8<32> buf; |
213 TInt err = Kern::ThreadRawRead(iClientThread, anInfo, &buf, 32); |
217 TInt err = Kern::ThreadRawRead(iClientThread, anInfo, &buf, 32); |
214 if(err != KErrNone) |
218 if(err != KErrNone) |
215 return err; |
219 return err; |
216 |
220 } |
217 //iExcludedROMAddressEnd = *(TUint32 *)(&(buf.Ptr()[20])); |
|
218 } |
|
219 |
221 |
220 // Allocate a D_RMD_Breakpoints class as a breakpoint manager |
222 // Allocate a D_RMD_Breakpoints class as a breakpoint manager |
221 NKern::ThreadEnterCS(); |
223 NKern::ThreadEnterCS(); |
222 iBreakManager = new D_RMD_Breakpoints(this); |
224 iBreakManager = new D_RMD_Breakpoints(this); |
223 NKern::ThreadLeaveCS(); |
225 NKern::ThreadLeaveCS(); |
224 if (iBreakManager == NULL) |
226 if (iBreakManager == NULL) |
225 { |
227 { |
226 LOG_MSG("DRM_DebugChannel::DRM_DebugChannel - could not construct breakpoint manager"); |
228 LOG_MSG("DRM_DebugChannel::DRM_DebugChannel - could not construct breakpoint manager"); |
227 return KErrNoMemory; |
229 return KErrNoMemory; |
228 } |
230 } |
229 |
231 |
230 // Initialise the new breakpoint manager object |
232 // Initialise the new breakpoint manager object |
231 iBreakManager->Init(); |
233 iBreakManager->Init(); |
232 |
234 |
233 // Allocate a DRMDStepping class as the stepping manager |
235 // Allocate a DRMDStepping class as the stepping manager |
234 NKern::ThreadEnterCS(); |
236 NKern::ThreadEnterCS(); |
235 iStepper = new DRMDStepping(this); |
237 iStepper = new DRMDStepping(this); |
236 NKern::ThreadLeaveCS(); |
238 NKern::ThreadLeaveCS(); |
237 if (iStepper == NULL) |
239 if (iStepper == NULL) |
238 { |
240 { |
239 LOG_MSG("DRM_DebugChannel::DRM_DebugChannel - could not construct stepper manager"); |
241 LOG_MSG("DRM_DebugChannel::DRM_DebugChannel - could not construct stepper manager"); |
240 return KErrNoMemory; |
242 return KErrNoMemory; |
241 } |
243 } |
242 |
244 |
243 // Initialize the code modifier for managing breakpoints. |
245 // Initialize the code modifier for managing breakpoints. |
244 TUint caps; //ignored for now |
246 TUint caps; //ignored for now |
245 err = DebugSupport::InitialiseCodeModifier(caps, NUMBER_OF_MAX_BREAKPOINTS); |
247 err = DebugSupport::InitialiseCodeModifier(caps, NUMBER_OF_MAX_BREAKPOINTS); |
246 //if code modifier initializer failed, |
248 //if code modifier initializer failed, |
247 //return here, since we can't set an breakpoints |
249 //return here, since we can't set an breakpoints |
248 if(err != KErrNone) |
250 if(err != KErrNone) |
249 { |
251 { |
250 return err; |
252 return err; |
251 } |
253 } |
252 else |
254 else |
253 { |
255 { |
254 iInitialisedCodeModifier = ETrue; |
256 iInitialisedCodeModifier = ETrue; |
255 } |
257 } |
256 |
258 |
257 //create and set the driver's Dfc queue |
259 //create and set the driver's Dfc queue |
258 err = CreateDfcQ(); |
260 err = CreateDfcQ(); |
259 if(err != KErrNone) |
261 if(err != KErrNone) |
260 { |
262 { |
271 if (err != KErrNone) |
273 if (err != KErrNone) |
272 return err; |
274 return err; |
273 |
275 |
274 //return KErrNone; |
276 //return KErrNone; |
275 return iEventHandler->Start(); |
277 return iEventHandler->Start(); |
276 } |
278 } |
277 |
279 |
278 // |
280 /** |
279 // DRM_DebugChannel::SendMsg |
281 Forward call to either synch or asynch methods while serialising all calls via lock. |
280 // |
282 |
283 Protect access via a the event handler lock to |
|
284 serialise all calls and protect concurrent access to data structures |
|
285 |
|
286 @param aMsg pointer to a TMessageBase object |
|
287 |
|
288 @return error returned by called methods |
|
289 |
|
290 @see DRM_DebugEventHandler::HandleSpecificEvent where lock is also used |
|
291 @see DRM_DebugEventHandler::iProtectionLock |
|
292 |
|
293 */ |
|
281 TInt DRM_DebugChannel::SendMsg(TMessageBase* aMsg) |
294 TInt DRM_DebugChannel::SendMsg(TMessageBase* aMsg) |
282 { |
295 { |
283 LOG_MSG("DRM_DebugChannel::SendMsg()"); |
296 DThread * currThread = &Kern::CurrentThread(); |
284 |
297 LOG_MSG3("DRM_DebugChannel::SendMsg() currThread = 0x%08x, iClientThread=0x%08x", currThread, iClientThread ); |
298 |
|
299 iEventHandler->LockDataAccess(); |
|
300 |
|
285 TThreadMessage& m = *(TThreadMessage*)aMsg; |
301 TThreadMessage& m = *(TThreadMessage*)aMsg; |
286 TInt id = m.iValue; |
302 TInt id = m.iValue; |
287 TInt err = KErrNone; |
303 TInt err = KErrNone; |
288 |
304 |
289 if (id != (TInt)ECloseMsg && id != KMaxTInt && id < 0) |
305 if (id != (TInt)ECloseMsg && id != KMaxTInt && id < 0) |
296 } |
312 } |
297 else |
313 else |
298 { |
314 { |
299 err = DLogicalChannel::SendMsg(aMsg); |
315 err = DLogicalChannel::SendMsg(aMsg); |
300 } |
316 } |
317 |
|
318 iEventHandler->ReleaseDataAccess(); |
|
301 return err; |
319 return err; |
302 } |
320 } |
303 |
321 |
304 // |
322 // |
305 // DRM_DebugChannel::SendRequest |
323 // DRM_DebugChannel::SendRequest |
328 // |
346 // |
329 // DRM_DebugChannel::PreAsyncGetValue |
347 // DRM_DebugChannel::PreAsyncGetValue |
330 // |
348 // |
331 TInt DRM_DebugChannel::PreAsyncGetValue(TEventInfo* aValue, TRequestStatus* aStatus) |
349 TInt DRM_DebugChannel::PreAsyncGetValue(TEventInfo* aValue, TRequestStatus* aStatus) |
332 { |
350 { |
333 LOG_MSG("DRM_DebugChannel::PreAsyncGetValue()"); |
351 LOG_MSG3("DRM_DebugChannel::PreAsyncGetValue() TEventInfo=0x%08x, TRequestStatus=0x%08x", |
352 aValue, aStatus ); |
|
334 |
353 |
335 iAsyncGetValueRequest->Reset(); |
354 iAsyncGetValueRequest->Reset(); |
336 |
355 |
337 TInt err = iAsyncGetValueRequest->SetStatus(aStatus); |
356 TInt err = iAsyncGetValueRequest->SetStatus(aStatus); |
338 if (err != KErrNone) |
357 if (err != KErrNone) |
362 // New: The cancel call does not take an enum parameter describing |
381 // New: The cancel call does not take an enum parameter describing |
363 // the request to be cancelled. Rather it supplies a pointer |
382 // the request to be cancelled. Rather it supplies a pointer |
364 // to a user-side struct defining the cancellation |
383 // to a user-side struct defining the cancellation |
365 // |
384 // |
366 void DRM_DebugChannel::DoCancel(TInt aReqNo) |
385 void DRM_DebugChannel::DoCancel(TInt aReqNo) |
367 { |
386 { |
368 LOG_MSG("DRM_DebugChannel::DoCancel()"); |
387 LOG_MSG("DRM_DebugChannel::DoCancel()"); |
369 |
388 |
370 TRMD_DebugCancelInfo info; |
389 TRMD_DebugCancelInfo info; |
371 |
390 |
372 TInt err = Kern::ThreadRawRead(iClientThread,(TAny*)aReqNo,(TAny*)&info,sizeof(info)); |
391 TInt err = Kern::ThreadRawRead(iClientThread,(TAny*)aReqNo,(TAny*)&info,sizeof(info)); |
373 if (err != KErrNone) |
392 if (err != KErrNone) |
374 { |
393 { |
375 // How do we cancel something we know nothing about??? |
394 // How do we cancel something we know nothing about??? |
376 LOG_MSG("DRM_DebugChannel::DoCancel - bad arguments"); |
395 LOG_MSG("DRM_DebugChannel::DoCancel - bad arguments"); |
377 return; |
396 return; |
378 } |
397 } |
379 |
398 |
380 // Find the process |
399 // Find the process |
381 DTargetProcess* pProcess = TheDProcessTracker.FindProcess(info.iProcessName); |
400 DTargetProcess* pProcess = TheDProcessTracker.FindProcess(info.iProcessName); |
382 if (pProcess == NULL) |
401 if (pProcess == NULL) |
383 { |
402 { |
384 // We are doomed. We don't know which event to cancel.. |
403 // We are doomed. We don't know which event to cancel.. |
385 LOG_MSG2("Cannot determine which process is being debugged: %S", &(info.iProcessName)); |
404 LOG_MSG2("Cannot determine which process is being debugged: %S", &(info.iProcessName)); |
386 |
405 |
387 return; |
406 return; |
388 } |
407 } |
389 |
408 |
390 // Find the agent |
409 // Find the agent |
391 DDebugAgent* debugAgent = pProcess->Agent(info.iAgentId); |
410 DDebugAgent* debugAgent = pProcess->Agent(info.iAgentId); |
392 if (debugAgent == NULL) |
411 if (debugAgent == NULL) |
393 { |
412 { |
394 // Bad agent means there is no tracking agent |
413 // Bad agent means there is no tracking agent |
395 LOG_MSG2("Cannot locate debug agent with pid 0x%0x16lx",info.iAgentId); |
414 LOG_MSG2("Cannot locate debug agent with pid 0x%0x16lx",info.iAgentId); |
396 return; |
415 return; |
397 } |
416 } |
398 |
417 |
399 // Agent completes/pends the request as appropriate. |
418 // Agent completes/pends the request as appropriate. |
400 debugAgent->CancelGetEvent(); |
419 debugAgent->CancelGetEvent(); |
401 |
420 |
402 } |
421 } |
403 |
422 |
404 // |
423 // |
405 // DRM_DebugChannel::DoRequest |
424 // DRM_DebugChannel::DoRequest |
406 // |
425 // |
407 void DRM_DebugChannel::DoRequest(TInt aReqNo, TRequestStatus* aStatus, TAny* a1, TAny* a2) |
426 void DRM_DebugChannel::DoRequest(TInt aReqNo, TRequestStatus* aStatus, TAny* a1, TAny* a2) |
408 { |
427 { |
409 LOG_MSG("DRM_DebugChannel::DoRequest()"); |
428 LOG_MSG4("DRM_DebugChannel::DoRequest(), iClientThread=0x%08x, tid=0x%08x, TRequestStatus=0x%08x", |
429 iClientThread, I64LOW(iClientThread->iId), aStatus); |
|
410 |
430 |
411 switch(aReqNo) |
431 switch(aReqNo) |
412 { |
432 { |
413 case RRM_DebugDriver::ERequestGetEvent: |
433 case RRM_DebugDriver::ERequestGetEvent: |
414 { |
434 { |
415 TEventMetaData eventMetaData; |
435 TEventMetaData eventMetaData; |
416 TInt err = Kern::ThreadRawRead(iClientThread, a2, (TUint8 *)&eventMetaData, sizeof(TEventMetaData) ); |
436 TInt err = Kern::ThreadRawRead(iClientThread, a2, (TUint8 *)&eventMetaData, sizeof(TEventMetaData) ); |
417 if (err != KErrNone) |
437 if (err != KErrNone) |
418 { |
438 { |
419 LOG_MSG("Error: could not read argument data from the DSS (TEventMetaData)"); |
439 LOG_MSG("Error: could not read argument data from the DSS (TEventMetaData)"); |
420 |
440 |
421 // We could not read information from the user, so the a2 argument is probably wrong |
441 // We could not read information from the user, so the a2 argument is probably wrong |
422 Kern::RequestComplete(iClientThread, aStatus, KErrArgument); |
442 Kern::RequestComplete(iClientThread, aStatus, KErrArgument); |
423 return; |
443 return; |
424 } |
444 } |
425 |
445 |
426 // Find the process |
446 // Find the process |
427 DTargetProcess* pProcess = TheDProcessTracker.FindProcess(eventMetaData.iTargetProcessName); |
447 DTargetProcess* pProcess = TheDProcessTracker.FindProcess(eventMetaData.iTargetProcessName); |
428 if (pProcess == NULL) |
448 if (pProcess == NULL) |
429 { |
449 { |
430 LOG_MSG("Cannot identify process being debugged"); |
450 LOG_MSG("Cannot identify process being debugged"); |
431 |
451 |
432 // We could not locate the process, so the user asked for the wrong one. |
452 // We could not locate the process, so the user asked for the wrong one. |
433 Kern::RequestComplete(iClientThread, aStatus, KErrArgument); |
453 Kern::RequestComplete(iClientThread, aStatus, KErrArgument); |
434 return; |
454 return; |
435 } |
455 } |
436 |
456 |
437 // Find the agent |
457 // Find the agent |
438 DDebugAgent* debugAgent = pProcess->Agent(eventMetaData.iDebugAgentProcessId); |
458 DDebugAgent* debugAgent = pProcess->Agent(eventMetaData.iDebugAgentProcessId); |
459 LOG_MSG5(" For agent pid=%d, DTargetProcess=0x%08x, Agent=0x%08x, iAsyncGetValueRequest0x%08x", |
|
460 I64LOW(eventMetaData.iDebugAgentProcessId), pProcess, debugAgent, iAsyncGetValueRequest ); |
|
461 |
|
439 if (debugAgent == NULL) |
462 if (debugAgent == NULL) |
440 { |
463 { |
441 // Bad agent means there is no tracking agent |
464 // Bad agent means there is no tracking agent |
442 LOG_MSG2("Cannot locate debug agent with pid 0x%0x16lx",eventMetaData.iDebugAgentProcessId); |
465 LOG_MSG2("Cannot locate debug agent with pid 0x%0x16lx",eventMetaData.iDebugAgentProcessId); |
443 return; |
466 return; |
444 } |
467 } |
445 // Agent completes/pends the request as appropriate. |
468 // Agent completes/pends the request as appropriate. |
446 debugAgent->GetEvent(iAsyncGetValueRequest, (TEventInfo*)a1, iClientThread); |
469 debugAgent->GetEvent(iAsyncGetValueRequest, iClientThread); |
447 |
470 |
448 break; |
471 break; |
449 } |
472 } |
450 default: |
473 default: |
451 { |
474 { |
452 // Don't know what to do, should not get here! |
475 // Don't know what to do, should not get here! |
453 LOG_MSG("DRM_DebugChannel::DoRequest was passed an unsupported request aReqNo"); |
476 LOG_MSG("DRM_DebugChannel::DoRequest was passed an unsupported request aReqNo"); |
454 |
477 |
455 Kern::RequestComplete(iClientThread, aStatus, KErrNotSupported); |
478 Kern::RequestComplete(iClientThread, aStatus, KErrNotSupported); |
456 } |
479 } |
457 } |
480 } |
458 } |
481 } |
459 |
482 |
460 // |
483 // |
461 // DRM_DebugChannel::DoControl |
484 // DRM_DebugChannel::DoControl |
462 // |
485 // |
463 TInt DRM_DebugChannel::DoControl(TInt aFunction, TAny* a1, TAny* a2) |
486 TInt DRM_DebugChannel::DoControl(TInt aFunction, TAny* a1, TAny* a2) |
464 { |
487 { |
465 LOG_MSG("DRM_DebugChannel::DoControl()"); |
488 LOG_MSG("DRM_DebugChannel::DoControl()"); |
466 |
489 |
467 LOG_MSG2("DoControl Function %d", aFunction); |
490 LOG_MSG2("DoControl Function %d", aFunction); |
468 |
491 |
469 TInt err = KErrBadHandle; |
492 TInt err = KErrBadHandle; |
470 DThread* threadObj = NULL; |
493 DThread* threadObj = NULL; |
471 |
494 |
472 switch(aFunction) |
495 switch(aFunction) |
473 { |
496 { |
474 /* Security first */ |
497 /* Security first */ |
475 case RRM_DebugDriver::EControlIsDebuggable: |
498 case RRM_DebugDriver::EControlIsDebuggable: |
476 { |
499 { |
477 err = IsDebuggable((TUint32)a1); |
500 err = IsDebuggable((TUint32)a1); |
478 break; |
501 break; |
479 } |
502 } |
480 case RRM_DebugDriver::EControlSetBreak: |
503 case RRM_DebugDriver::EControlSetBreak: |
481 { |
504 { |
482 err = SetBreak((TSetBreakInfo*)a1); |
505 err = SetBreak((TSetBreakInfo*)a1); |
483 break; |
506 break; |
484 } |
507 } |
485 case RRM_DebugDriver::EControlClearBreak: |
508 case RRM_DebugDriver::EControlClearBreak: |
486 { |
509 { |
487 err = iBreakManager->DoClearBreak((TInt32)a1); |
510 err = iBreakManager->DoClearBreak((TInt32)a1); |
488 break; |
511 break; |
489 } |
512 } |
490 case RRM_DebugDriver::EControlModifyBreak: |
513 case RRM_DebugDriver::EControlModifyBreak: |
491 { |
514 { |
492 err = iBreakManager->DoModifyBreak((TModifyBreakInfo*)a1); |
515 err = iBreakManager->DoModifyBreak((TModifyBreakInfo*)a1); |
493 break; |
516 break; |
494 } |
517 } |
495 case RRM_DebugDriver::EControlModifyProcessBreak: |
518 case RRM_DebugDriver::EControlModifyProcessBreak: |
496 { |
519 { |
497 err = iBreakManager->DoModifyProcessBreak((TModifyProcessBreakInfo*)a1); |
520 err = iBreakManager->DoModifyProcessBreak((TModifyProcessBreakInfo*)a1); |
498 break; |
521 break; |
499 } |
522 } |
500 case RRM_DebugDriver::EControlBreakInfo: |
523 case RRM_DebugDriver::EControlBreakInfo: |
501 { |
524 { |
502 err = iBreakManager->DoBreakInfo((TGetBreakInfo*)a1); |
525 err = iBreakManager->DoBreakInfo((TGetBreakInfo*)a1); |
503 break; |
526 break; |
504 } |
527 } |
505 case RRM_DebugDriver::EControlSuspendThread: |
528 case RRM_DebugDriver::EControlSuspendThread: |
506 { |
529 { |
507 threadObj = DebugUtils::OpenThreadHandle((TUint32)a1); |
530 threadObj = DebugUtils::OpenThreadHandle((TUint32)a1); |
508 if (threadObj) |
531 if (threadObj) |
509 { |
532 { |
510 err = DoSuspendThread(threadObj); |
533 err = DoSuspendThread(threadObj); |
511 } |
534 } |
512 break; |
535 break; |
513 } |
536 } |
514 case RRM_DebugDriver::EControlResumeThread: |
537 case RRM_DebugDriver::EControlResumeThread: |
515 { |
538 { |
516 threadObj = DebugUtils::OpenThreadHandle((TUint32)a1); |
539 threadObj = DebugUtils::OpenThreadHandle((TUint32)a1); |
517 if (threadObj) |
540 if (threadObj) |
518 { |
541 { |
519 err = DoResumeThread(threadObj); |
542 err = DoResumeThread(threadObj); |
520 } |
543 } |
521 break; |
544 break; |
522 } |
545 } |
523 case RRM_DebugDriver::EControlStepRange: |
546 case RRM_DebugDriver::EControlStepRange: |
524 { |
547 { |
525 threadObj = DebugUtils::OpenThreadHandle((TUint32)a1); |
548 threadObj = DebugUtils::OpenThreadHandle((TUint32)a1); |
526 if (threadObj) |
549 if (threadObj) |
527 { |
550 { |
528 err = StepRange(threadObj, (TRM_DebugStepInfo*)a2); |
551 err = StepRange(threadObj, (TRM_DebugStepInfo*)a2); |
529 } |
552 } |
530 break; |
553 break; |
531 } |
554 } |
532 case RRM_DebugDriver::EControlReadMemory: |
555 case RRM_DebugDriver::EControlReadMemory: |
533 { |
556 { |
534 threadObj = DebugUtils::OpenThreadHandle((TUint32)a1); |
557 threadObj = DebugUtils::OpenThreadHandle((TUint32)a1); |
535 if (threadObj) |
558 if (threadObj) |
536 { |
559 { |
537 err = ReadMemory(threadObj, (TRM_DebugMemoryInfo*)a2); |
560 err = ReadMemory(threadObj, (TRM_DebugMemoryInfo*)a2); |
538 } |
561 } |
539 break; |
562 break; |
540 } |
563 } |
541 case RRM_DebugDriver::EControlWriteMemory: |
564 case RRM_DebugDriver::EControlWriteMemory: |
542 { |
565 { |
543 threadObj = DebugUtils::OpenThreadHandle((TUint32)a1); |
566 threadObj = DebugUtils::OpenThreadHandle((TUint32)a1); |
544 if (threadObj) |
567 if (threadObj) |
545 { |
568 { |
546 err = WriteMemory(threadObj, (TRM_DebugMemoryInfo*)a2); |
569 err = WriteMemory(threadObj, (TRM_DebugMemoryInfo*)a2); |
547 } |
570 } |
548 break; |
571 break; |
549 } |
572 } |
550 case RRM_DebugDriver::EControlReadRegistersLegacy: |
573 case RRM_DebugDriver::EControlReadRegistersLegacy: |
551 { |
574 { |
552 threadObj = DebugUtils::OpenThreadHandle((TUint32)a1); |
575 threadObj = DebugUtils::OpenThreadHandle((TUint32)a1); |
553 if (threadObj) |
576 if (threadObj) |
554 { |
577 { |
555 err = ReadRegistersLegacy(threadObj, (TRM_DebugRegisterInfo*)a2); |
578 err = ReadRegistersLegacy(threadObj, (TRM_DebugRegisterInfo*)a2); |
556 } |
579 } |
557 break; |
580 break; |
558 } |
581 } |
559 case RRM_DebugDriver::EControlWriteRegistersLegacy: |
582 case RRM_DebugDriver::EControlWriteRegistersLegacy: |
560 { |
583 { |
561 threadObj = DebugUtils::OpenThreadHandle((TUint32)a1); |
584 threadObj = DebugUtils::OpenThreadHandle((TUint32)a1); |
562 if (threadObj) |
585 if (threadObj) |
563 { |
586 { |
564 err = WriteRegistersLegacy(threadObj, (TRM_DebugRegisterInfo*)a2); |
587 err = WriteRegistersLegacy(threadObj, (TRM_DebugRegisterInfo*)a2); |
565 } |
588 } |
566 break; |
589 break; |
567 } |
590 } |
568 case RRM_DebugDriver::EControlReadRegisters: |
591 case RRM_DebugDriver::EControlReadRegisters: |
569 { |
592 { |
570 threadObj = DebugUtils::OpenThreadHandle((TUint32)a1); |
593 threadObj = DebugUtils::OpenThreadHandle((TUint32)a1); |
571 if (threadObj) |
594 if (threadObj) |
572 { |
595 { |
573 err = ReadRegisters(threadObj, (TRM_DebugRegisterInformation*)a2); |
596 err = ReadRegisters(threadObj, (TRM_DebugRegisterInformation*)a2); |
574 } |
597 } |
575 break; |
598 break; |
576 } |
599 } |
577 case RRM_DebugDriver::EControlWriteRegisters: |
600 case RRM_DebugDriver::EControlWriteRegisters: |
578 { |
601 { |
579 threadObj = DebugUtils::OpenThreadHandle((TUint32)a1); |
602 threadObj = DebugUtils::OpenThreadHandle((TUint32)a1); |
580 if (threadObj) |
603 if (threadObj) |
581 { |
604 { |
582 err = WriteRegisters(threadObj, (TRM_DebugRegisterInformation*)a2); |
605 err = WriteRegisters(threadObj, (TRM_DebugRegisterInformation*)a2); |
583 } |
606 } |
584 break; |
607 break; |
585 } |
608 } |
586 case RRM_DebugDriver::EControlGetDebugFunctionalityBufSize: |
609 case RRM_DebugDriver::EControlGetDebugFunctionalityBufSize: |
587 { |
610 { |
588 LOG_MSG("RRM_DebugDriver::EControlGetDebugFunctionalityBufSize\n"); |
611 LOG_MSG("RRM_DebugDriver::EControlGetDebugFunctionalityBufSize\n"); |
589 |
612 |
590 TDebugFunctionality df; |
613 TDebugFunctionality df; |
591 |
614 |
592 TUint size = df.GetDebugFunctionalityBufSize(); |
615 TUint size = df.GetDebugFunctionalityBufSize(); |
593 |
616 |
594 // Return size to user-side in a safe manner |
617 // Return size to user-side in a safe manner |
595 err = Kern::ThreadRawWrite(iClientThread, a1, (TUint8*)&size, sizeof(TUint), iClientThread); |
618 err = Kern::ThreadRawWrite(iClientThread, a1, (TUint8*)&size, sizeof(TUint), iClientThread); |
596 break; |
619 break; |
597 } |
620 } |
598 case RRM_DebugDriver::EControlGetDebugFunctionality: |
621 case RRM_DebugDriver::EControlGetDebugFunctionality: |
599 { |
622 { |
600 LOG_MSG("RRM_DebugDriver::EControlGetDebugFunctionality\n"); |
623 LOG_MSG("RRM_DebugDriver::EControlGetDebugFunctionality\n"); |
601 |
624 |
602 TDebugFunctionality df; |
625 TDebugFunctionality df; |
603 |
626 |
604 TUint32 dfsize = df.GetDebugFunctionalityBufSize(); |
627 TUint32 dfsize = df.GetDebugFunctionalityBufSize(); |
606 // Alloc tmp buffer for Debug Functionality data |
629 // Alloc tmp buffer for Debug Functionality data |
607 NKern::ThreadEnterCS(); |
630 NKern::ThreadEnterCS(); |
608 TUint8* dfbuffer = (TUint8*)Kern::AllocZ(dfsize); |
631 TUint8* dfbuffer = (TUint8*)Kern::AllocZ(dfsize); |
609 NKern::ThreadLeaveCS(); |
632 NKern::ThreadLeaveCS(); |
610 if (dfbuffer==NULL) |
633 if (dfbuffer==NULL) |
611 { |
634 { |
612 LOG_MSG2("Could not allocate memory for %d bytes\n",dfsize); |
635 LOG_MSG2("Could not allocate memory for %d bytes\n",dfsize); |
613 |
636 |
614 // could not allocate memory |
637 // could not allocate memory |
615 return KErrNoMemory; |
638 return KErrNoMemory; |
616 } |
639 } |
617 |
640 |
618 // Temporary descriptor to hold DF data |
641 // Temporary descriptor to hold DF data |
619 TPtr8 tmpPtr(dfbuffer,0,dfsize); |
642 TPtr8 tmpPtr(dfbuffer,0,dfsize); |
620 |
643 |
621 // Obtain the DF data |
644 // Obtain the DF data |
622 if (df.GetDebugFunctionality(tmpPtr) ) |
645 if (df.GetDebugFunctionality(tmpPtr) ) |
623 { |
646 { |
624 // Return the DF data to the user-side |
647 // Return the DF data to the user-side |
625 err = Kern::ThreadDesWrite(iClientThread, a1, tmpPtr, 0, KChunkShiftBy0, iClientThread); |
648 err = Kern::ThreadDesWrite(iClientThread, a1, tmpPtr, 0, KChunkShiftBy0, iClientThread); |
626 } |
649 } |
627 else |
650 else |
628 { |
651 { |
629 // Failed. |
652 // Failed. |
630 err = KErrGeneral; |
653 err = KErrGeneral; |
631 } |
654 } |
632 |
655 |
633 // Free tmp buffer |
656 // Free tmp buffer |
634 NKern::ThreadEnterCS(); |
657 NKern::ThreadEnterCS(); |
635 Kern::Free(dfbuffer); |
658 Kern::Free(dfbuffer); |
636 NKern::ThreadLeaveCS(); |
659 NKern::ThreadLeaveCS(); |
637 break; |
660 break; |
638 } |
661 } |
639 case RRM_DebugDriver::EControlAttachProcess: |
662 case RRM_DebugDriver::EControlAttachProcess: |
640 { |
663 { |
641 LOG_MSG("RRM_DebugDriver::EControlAttachProcess"); |
664 LOG_MSG("RRM_DebugDriver::EControlAttachProcess"); |
642 |
665 |
643 err = AttachProcess(a1,a2); |
666 err = AttachProcess(a1,a2); |
644 break; |
667 break; |
645 } |
668 } |
646 case RRM_DebugDriver::EControlDetachProcess: |
669 case RRM_DebugDriver::EControlDetachProcess: |
647 { |
670 { |
648 LOG_MSG("RRM_DebugDriver::EControlDetachProcess"); |
671 LOG_MSG("RRM_DebugDriver::EControlDetachProcess"); |
649 |
672 |
650 err = DetachProcess(a1,a2); |
673 err = DetachProcess(a1,a2); |
651 break; |
674 break; |
652 } |
675 } |
653 case RRM_DebugDriver::EControlDetachAgent: |
676 case RRM_DebugDriver::EControlDetachAgent: |
654 { |
677 { |
655 LOG_MSG("RRM_DebugDriver::EControlDetachAgent"); |
678 LOG_MSG("RRM_DebugDriver::EControlDetachAgent"); |
656 |
679 |
657 err = DetachAgent(a1,a2); |
680 err = DetachAgent(a1,a2); |
658 break; |
681 break; |
659 } |
682 } |
660 case RRM_DebugDriver::EControlSetEventAction: |
683 case RRM_DebugDriver::EControlSetEventAction: |
661 { |
684 { |
662 LOG_MSG("RRM_DebugDriver::EControlSetEventAction"); |
685 LOG_MSG("RRM_DebugDriver::EControlSetEventAction"); |
663 |
686 |
664 err = SetEventAction(a1,a2); |
687 err = SetEventAction(a1,a2); |
665 break; |
688 break; |
666 } |
689 } |
667 case RRM_DebugDriver::EControlGetMemoryOperationMaxBlockSize: |
690 case RRM_DebugDriver::EControlGetMemoryOperationMaxBlockSize: |
668 { |
691 { |
669 LOG_MSG("RRM_DebugDriver::EControlGetMemoryOperationMaxBlockSize\n"); |
692 LOG_MSG("RRM_DebugDriver::EControlGetMemoryOperationMaxBlockSize\n"); |
670 |
693 |
671 TUint32 maxSize = TDebugFunctionality::GetMemoryOperationMaxBlockSize(); |
694 TUint32 maxSize = TDebugFunctionality::GetMemoryOperationMaxBlockSize(); |
672 |
695 |
673 // Return size to user-side in a safe manner |
696 // Return size to user-side in a safe manner |
674 err = Kern::ThreadRawWrite(iClientThread, a1, (TUint8*)&maxSize, sizeof(TUint32), iClientThread); |
697 err = Kern::ThreadRawWrite(iClientThread, a1, (TUint8*)&maxSize, sizeof(TUint32), iClientThread); |
675 break; |
698 break; |
676 } |
699 } |
677 case RRM_DebugDriver::EControlGetList: |
700 case RRM_DebugDriver::EControlGetList: |
678 { |
701 { |
679 LOG_MSG("RRM_DebugDriver::EControlGetList\n"); |
702 LOG_MSG("RRM_DebugDriver::EControlGetList\n"); |
680 err = GetList((TListInformation*)a1); |
703 err = GetList((TListInformation*)a1); |
681 break; |
704 break; |
682 } |
705 } |
683 case RRM_DebugDriver::EControlStep: |
706 case RRM_DebugDriver::EControlStep: |
684 { |
707 { |
685 LOG_MSG("RRM_DebugDriver::EControlStep\n"); |
708 LOG_MSG("RRM_DebugDriver::EControlStep\n"); |
686 |
709 |
687 err = Step((TUint32)a1,(TUint32)a2); |
710 err = Step((TUint32)a1,(TUint32)a2); |
688 break; |
711 break; |
689 } |
712 } |
690 case RRM_DebugDriver::EControlKillProcess: |
713 case RRM_DebugDriver::EControlKillProcess: |
691 { |
714 { |
692 LOG_MSG("RRM_DebugDriver::EControlKillProcess\n"); |
715 LOG_MSG("RRM_DebugDriver::EControlKillProcess\n"); |
693 |
716 |
694 err = KillProcess((TUint32)a1,(TUint32)a2); |
717 err = KillProcess((TUint32)a1,(TUint32)a2); |
695 break; |
718 break; |
696 } |
719 } |
697 default: |
720 default: |
698 { |
721 { |
699 err = KErrGeneral; |
722 err = KErrGeneral; |
700 } |
723 } |
701 } |
724 } |
702 |
725 |
703 if (KErrNone != err) |
726 if (KErrNone != err) |
704 { |
727 { |
705 LOG_MSG2("Error %d from control function", err); |
728 LOG_MSG2("Error %d from control function", err); |
706 } |
729 } |
707 |
730 |
708 if (threadObj) |
731 if (threadObj) |
709 { |
732 { |
710 // Close the thread handle which has been opened by DebugUtils::OpenThreadHandle |
733 // Close the thread handle which has been opened by DebugUtils::OpenThreadHandle |
711 threadObj->Close(NULL); |
734 threadObj->Close(NULL); |
712 } |
735 } |
713 |
736 |
714 return err; |
737 return err; |
715 } |
738 } |
716 |
739 |
717 void DRM_DebugChannel::HandleMsg(TMessageBase* aMsg) |
740 void DRM_DebugChannel::HandleMsg(TMessageBase* aMsg) |
718 { |
741 { |
719 LOG_MSG("DRM_DebugChannel::HandleMsg()"); |
742 LOG_MSG("DRM_DebugChannel::HandleMsg()"); |
720 |
743 |
721 TThreadMessage& m = *(TThreadMessage*)aMsg; |
744 TThreadMessage& m = *(TThreadMessage*)aMsg; |
722 TInt id = m.iValue; |
745 TInt id = m.iValue; |
723 |
746 |
724 if (id == (TInt)ECloseMsg) |
747 if (id == (TInt)ECloseMsg) |
725 { |
748 { |
726 if (iEventHandler) |
749 if (iEventHandler) |
727 { |
750 { |
728 iEventHandler->Stop(); |
751 iEventHandler->Stop(); |
729 iEventHandler->Close(); |
752 iEventHandler->Close(); |
730 iEventHandler = NULL; |
753 iEventHandler = NULL; |
731 } |
754 } |
732 m.Complete(KErrNone, EFalse); |
755 m.Complete(KErrNone, EFalse); |
733 return; |
756 return; |
734 } |
757 } |
735 |
758 |
736 if (id == KMaxTInt) |
759 if (id == KMaxTInt) |
737 { |
760 { |
738 // DoCancel |
761 // DoCancel |
739 DoCancel(m.Int0()); |
762 DoCancel(m.Int0()); |
740 m.Complete(KErrNone, ETrue); |
763 m.Complete(KErrNone, ETrue); |
741 return; |
764 return; |
742 } |
765 } |
743 |
766 |
744 if (id < 0) |
767 if (id < 0) |
745 { |
768 { |
746 // DoRequest |
769 // DoRequest |
747 TRequestStatus* pStatus = (TRequestStatus*)m.Ptr0(); |
770 TRequestStatus* pStatus = (TRequestStatus*)m.Ptr0(); |
748 DoRequest(~id, pStatus, m.Ptr1(), m.Ptr2()); |
771 DoRequest(~id, pStatus, m.Ptr1(), m.Ptr2()); |
749 m.Complete(KErrNone, ETrue); |
772 m.Complete(KErrNone, ETrue); |
750 } |
773 } |
751 else |
774 else |
752 { |
775 { |
753 // DoControl |
776 // DoControl |
754 TInt err = DoControl(id, m.Ptr0(), m.Ptr1()); |
777 TInt err = DoControl(id, m.Ptr0(), m.Ptr1()); |
755 m.Complete(err, ETrue); |
778 m.Complete(err, ETrue); |
756 } |
779 } |
757 } |
780 } |
758 |
781 |
759 // |
782 // |
760 // DRM_DebugChannel::RemoveProcess |
783 // DRM_DebugChannel::RemoveProcess |
761 // |
784 // |
762 TBool DRM_DebugChannel::RemoveProcess(TAny* a1, TAny* a2) |
785 TBool DRM_DebugChannel::RemoveProcess(TAny* a1, TAny* a2) |
763 { |
786 { |
764 LOG_EVENT_MSG("DRM_DebugChannel::RemoveProcess()"); |
787 LOG_MSG("DRM_DebugChannel::RemoveProcess()"); |
765 |
788 |
766 DProcess *aProcess = (DProcess*)a1; |
789 DProcess *aProcess = (DProcess*)a1; |
767 |
790 |
768 // Sanity check |
791 // Sanity check |
769 if (!aProcess) |
792 if (!aProcess) |
795 } |
818 } |
796 else |
819 else |
797 { |
820 { |
798 LOG_MSG2("Error in getting memory info: %d", err); |
821 LOG_MSG2("Error in getting memory info: %d", err); |
799 } |
822 } |
800 |
|
801 } |
823 } |
802 |
824 |
803 if (!codeAddress || !codeSize) |
825 if (!codeAddress || !codeSize) |
804 { |
826 { |
805 LOG_EVENT_MSG2("Code segment not available for process %d", aProcess->iId); |
827 LOG_EVENT_MSG2("Code segment not available for process %d", aProcess->iId); |
829 |
851 |
830 // |
852 // |
831 // DRM_DebugChannel::StartThread |
853 // DRM_DebugChannel::StartThread |
832 // |
854 // |
833 TBool DRM_DebugChannel::StartThread(TAny* a1, TAny* a2) |
855 TBool DRM_DebugChannel::StartThread(TAny* a1, TAny* a2) |
834 { |
856 { |
835 LOG_EVENT_MSG("DRM_DebugChannel::StartThread()"); |
857 LOG_EVENT_MSG("DRM_DebugChannel::StartThread()"); |
836 |
858 |
837 DThread *aThread = (DThread*)a1; |
859 DThread *aThread = (DThread*)a1; |
838 if(!aThread) |
860 if(!aThread) |
839 { |
861 { |
879 LOG_EVENT_MSG("\tCode segment is NULL"); |
901 LOG_EVENT_MSG("\tCode segment is NULL"); |
880 } |
902 } |
881 } |
903 } |
882 } |
904 } |
883 return EFalse; |
905 return EFalse; |
884 } |
906 } |
885 |
907 |
886 // |
908 // |
887 // DRM_DebugChannel::HandleAddProcessEvent |
909 // DRM_DebugChannel::HandleAddProcessEvent |
888 // |
910 // |
889 TBool DRM_DebugChannel::HandleAddProcessEvent(TAny* a1, TAny* a2) |
911 TBool DRM_DebugChannel::HandleAddProcessEvent(TAny* a1, TAny* a2) |
890 { |
912 { |
891 LOG_EVENT_MSG("DRM_DebugChannel::AddProcess()"); |
913 LOG_EVENT_MSG("DRM_DebugChannel::AddProcess()"); |
892 |
914 |
893 DProcess *aProcess = (DProcess*)a1; |
915 DProcess *aProcess = (DProcess*)a1; |
894 // a2 points to the thread creating the new process. |
916 // a2 points to the thread creating the new process. |
895 DThread *aThread = (DThread*)a2; |
917 DThread *aThread = (DThread*)a2; |
903 |
925 |
904 TDriverEventInfo info; |
926 TDriverEventInfo info; |
905 info.iEventType = EEventsAddProcess; |
927 info.iEventType = EEventsAddProcess; |
906 info.iProcessId = aProcess->iId; |
928 info.iProcessId = aProcess->iId; |
907 |
929 |
908 info.iCreatorThreadId = aThread ? aThread->iId : 0; |
930 info.iCreatorThreadId = aThread ? aThread->iId : 0; |
909 info.iProcessIdValid = ETrue; |
931 info.iProcessIdValid = ETrue; |
910 |
932 |
911 // Copy TUids |
933 // Copy TUids |
912 info.iUids = aProcess->iUids; |
934 info.iUids = aProcess->iUids; |
913 |
935 |
943 { |
965 { |
944 LOG_EVENT_MSG("DRM_DebugChannel::AddProcess - No iName for this process"); |
966 LOG_EVENT_MSG("DRM_DebugChannel::AddProcess - No iName for this process"); |
945 } |
967 } |
946 |
968 |
947 return EFalse; |
969 return EFalse; |
948 } |
970 } |
949 |
971 |
950 // |
972 // |
951 // DRM_DebugChannel::HandleRemoveProcessEvent |
973 // DRM_DebugChannel::HandleRemoveProcessEvent |
952 // |
974 // |
953 TBool DRM_DebugChannel::HandleRemoveProcessEvent(TAny* a1, TAny* a2) |
975 TBool DRM_DebugChannel::HandleRemoveProcessEvent(TAny* a1, TAny* a2) |
954 { |
976 { |
955 LOG_EVENT_MSG("DRM_DebugChannel::RemoveProcess()"); |
977 LOG_MSG("DRM_DebugChannel::HandleRemoveProcessEvent()"); |
956 |
978 |
957 DProcess *aProcess = (DProcess*)a1; |
979 DProcess *aProcess = (DProcess*)a1; |
958 if(!aProcess) |
980 if(!aProcess) |
959 { |
981 { |
960 LOG_MSG("Error getting DProcess object"); |
982 LOG_MSG("Error getting DProcess object"); |
1002 { |
1024 { |
1003 LOG_EVENT_MSG("DRM_DebugChannel::AddProcess - No iName for this process"); |
1025 LOG_EVENT_MSG("DRM_DebugChannel::AddProcess - No iName for this process"); |
1004 } |
1026 } |
1005 |
1027 |
1006 return EFalse; |
1028 return EFalse; |
1007 } |
1029 } |
1008 |
1030 |
1009 // |
1031 // |
1010 // DRM_DebugChannel::AddLibrary |
1032 // DRM_DebugChannel::AddLibrary |
1011 // |
1033 // |
1012 TBool DRM_DebugChannel::AddLibrary(TAny* a1, TAny* a2) |
1034 TBool DRM_DebugChannel::AddLibrary(TAny* a1, TAny* a2) |
1013 { |
1035 { |
1014 LOG_EVENT_MSG("DRM_DebugChannel::AddLibrary()"); |
1036 LOG_EVENT_MSG("DRM_DebugChannel::AddLibrary()"); |
1015 |
1037 |
1016 DLibrary *aLibrary = (DLibrary*)a1; |
1038 DLibrary *aLibrary = (DLibrary*)a1; |
1017 DThread *aThread = (DThread*)a2; |
1039 DThread *aThread = (DThread*)a2; |
1018 |
1040 |
1019 // sanity check |
1041 // sanity check |
1020 if (!aLibrary) |
1042 if (!aLibrary) |
1021 { |
1043 { |
1022 LOG_EVENT_MSG("DRM_DebugChannel::AddLibrary called with no library specified"); |
1044 LOG_EVENT_MSG("DRM_DebugChannel::AddLibrary called with no library specified"); |
1023 return EFalse; |
1045 return EFalse; |
1024 } |
1046 } |
1025 |
1047 |
1026 if (!aThread) |
1048 if (!aThread) |
1027 { |
1049 { |
1028 LOG_EVENT_MSG("DRM_DebugChannel::AddLibrary called with no thread specified"); |
1050 LOG_EVENT_MSG("DRM_DebugChannel::AddLibrary called with no thread specified"); |
1029 return EFalse; |
1051 return EFalse; |
1030 } |
1052 } |
1031 |
1053 |
1032 LOG_EVENT_MSG2(("Lib loaded: %S"), aLibrary->iName); |
1054 LOG_EVENT_MSG2(("Lib loaded: %S"), aLibrary->iName); |
1033 |
1055 |
1034 if (aThread) |
1056 if (aThread) |
1035 { |
1057 { |
1036 // make sure this is not the debugger thread |
1058 // make sure this is not the debugger thread |
1037 if ((aThread != iClientThread) && (aThread->iOwningProcess->iId != iClientThread->iOwningProcess->iId)) |
1059 if ((aThread != iClientThread) && (aThread->iOwningProcess->iId != iClientThread->iOwningProcess->iId)) |
1038 { |
1060 { |
1039 TDriverEventInfo info; |
1061 TDriverEventInfo info; |
1040 |
1062 |
1041 info.iEventType = EEventsAddLibrary; |
1063 info.iEventType = EEventsAddLibrary; |
1042 info.iProcessId = aThread->iOwningProcess->iId; |
1064 info.iProcessId = aThread->iOwningProcess->iId; |
1043 info.iProcessIdValid = ETrue; |
1065 info.iProcessIdValid = ETrue; |
1045 info.iThreadIdValid = ETrue; |
1067 info.iThreadIdValid = ETrue; |
1046 |
1068 |
1047 //get the code address |
1069 //get the code address |
1048 DCodeSeg* codeSeg = aLibrary->iCodeSeg; |
1070 DCodeSeg* codeSeg = aLibrary->iCodeSeg; |
1049 if (!codeSeg) |
1071 if (!codeSeg) |
1050 { |
1072 { |
1051 LOG_EVENT_MSG2("Code segment not available for library %S", aLibrary->iName); |
1073 LOG_EVENT_MSG2("Code segment not available for library %S", aLibrary->iName); |
1052 return EFalse; |
1074 return EFalse; |
1053 } |
1075 } |
1054 |
1076 |
1055 // Uid3 |
1077 // Uid3 |
1056 info.iUids = codeSeg->iUids; |
1078 info.iUids = codeSeg->iUids; |
1057 info.iUidsValid = ETrue; |
1079 info.iUidsValid = ETrue; |
1058 |
1080 |
1059 TModuleMemoryInfo memoryInfo; |
1081 TModuleMemoryInfo memoryInfo; |
1060 TInt err = codeSeg->GetMemoryInfo(memoryInfo, NULL); //NULL for DProcess should be ok; |
1082 TInt err = codeSeg->GetMemoryInfo(memoryInfo, NULL); //NULL for DProcess should be ok; |
1061 if (err != KErrNone) |
1083 if (err != KErrNone) |
1062 { |
1084 { |
1063 LOG_EVENT_MSG2("Error in getting memory info: %d", err); |
1085 LOG_EVENT_MSG2("Error in getting memory info: %d", err); |
1064 return EFalse; |
1086 return EFalse; |
1065 } |
1087 } |
1066 |
1088 |
1067 info.iCodeAddress = memoryInfo.iCodeBase; |
1089 info.iCodeAddress = memoryInfo.iCodeBase; |
1068 info.iDataAddress = memoryInfo.iInitialisedDataBase; |
1090 info.iDataAddress = memoryInfo.iInitialisedDataBase; |
1069 |
1091 |
1070 info.iFileName.Copy(*(aLibrary->iName)); //just the name, without uid info. |
1092 info.iFileName.Copy(*(aLibrary->iName)); //just the name, without uid info. |
1071 |
1093 |
1072 //queue up or complete the event |
1094 //queue up or complete the event |
1073 info.iArg1 = a1; |
1095 info.iArg1 = a1; |
1074 info.iArg2 = a2; |
1096 info.iArg2 = a2; |
1075 NotifyEvent(info); |
1097 NotifyEvent(info); |
1076 } |
1098 } |
1077 |
1099 |
1078 } |
1100 } |
1079 return EFalse; |
1101 return EFalse; |
1080 } |
1102 } |
1081 |
1103 |
1082 // |
1104 // |
1083 // DRM_DebugChannel::RemoveLibrary |
1105 // DRM_DebugChannel::RemoveLibrary |
1084 // |
1106 // |
1085 TBool DRM_DebugChannel::RemoveLibrary(TAny* a1, TAny* a2) |
1107 TBool DRM_DebugChannel::RemoveLibrary(TAny* a1, TAny* a2) |
1162 |
1184 |
1163 // |
1185 // |
1164 // DRM_DebugChannel::HandleEventKillThread |
1186 // DRM_DebugChannel::HandleEventKillThread |
1165 // |
1187 // |
1166 TBool DRM_DebugChannel::HandleEventKillThread(TAny* a1, TAny* a2) |
1188 TBool DRM_DebugChannel::HandleEventKillThread(TAny* a1, TAny* a2) |
1167 { |
1189 { |
1168 LOG_EVENT_MSG("DRM_DebugChannel::HandleEventKillThread"); |
1190 |
1191 LOG_MSG2("DRM_DebugChannel::HandleEventKillThread(Thread a1=0x%08x)", a1 ); |
|
1169 |
1192 |
1170 DThread* currentThread = &Kern::CurrentThread(); |
1193 DThread* currentThread = &Kern::CurrentThread(); |
1171 if (!currentThread) |
1194 if (!currentThread) |
1172 { |
1195 { |
1173 LOG_MSG("Error getting current thread"); |
1196 LOG_MSG("Error getting current thread"); |
1174 __NK_ASSERT_DEBUG(currentThread); |
1197 __NK_ASSERT_DEBUG(currentThread); |
1175 return EFalse; |
1198 return EFalse; |
1176 } |
1199 } |
1177 |
1200 |
1178 // a1 should point to the current thread, check this to make sure it does |
1201 // a1 should point to the current thread, check this to make sure it does |
1179 __NK_ASSERT_DEBUG((DThread*)a1 == currentThread); |
1202 __NK_ASSERT_DEBUG((DThread*)a1 == currentThread); |
1180 |
1203 |
1181 TDriverEventInfo info; |
1204 TDriverEventInfo info; |
1185 info.iThreadId = currentThread->iId; |
1208 info.iThreadId = currentThread->iId; |
1186 info.iThreadIdValid = ETrue; |
1209 info.iThreadIdValid = ETrue; |
1187 // 14 should probably be replaced by PC_REGISTER, for some reason PC_REGISTER had been replaced with 14 in the code |
1210 // 14 should probably be replaced by PC_REGISTER, for some reason PC_REGISTER had been replaced with 14 in the code |
1188 TInt err = ReadKernelRegisterValue(currentThread, 14, info.iCurrentPC); |
1211 TInt err = ReadKernelRegisterValue(currentThread, 14, info.iCurrentPC); |
1189 if(err != KErrNone) |
1212 if(err != KErrNone) |
1190 { |
1213 { |
1191 LOG_EVENT_MSG2("DRM_DebugChannel::HandleEventKillThread - Non-zero error code discarded: %d", err); |
1214 LOG_EVENT_MSG2("DRM_DebugChannel::HandleEventKillThread - Non-zero error code discarded: %d", err); |
1192 } |
1215 } |
1193 |
1216 |
1194 if (currentThread->iExitType == EExitPanic) |
1217 if (currentThread->iExitType == EExitPanic) |
1195 { |
1218 { |
1196 info.iPanicCategory.Copy(currentThread->iExitCategory); |
1219 info.iPanicCategory.Copy(currentThread->iExitCategory); |
1197 } |
1220 } |
1198 info.iExceptionNumber = currentThread->iExitReason; |
1221 info.iExceptionNumber = currentThread->iExitReason; |
1199 info.iExitType = currentThread->iExitType; |
1222 info.iExitType = currentThread->iExitType; |
1200 info.iEventType = EEventsKillThread; |
1223 info.iEventType = EEventsKillThread; |
1201 |
1224 |
1202 // Are we debugging this process - decide based on iFileName |
1225 // Are we debugging this process - decide based on iFileName |
1224 info.iArg1 = a1; |
1247 info.iArg1 = a1; |
1225 info.iArg2 = a2; |
1248 info.iArg2 = a2; |
1226 NotifyEvent(info); |
1249 NotifyEvent(info); |
1227 |
1250 |
1228 return ETrue; |
1251 return ETrue; |
1229 } |
1252 } |
1230 |
1253 |
1231 // |
1254 // |
1232 // DRM_DebugChannel::HandleSwException |
1255 // DRM_DebugChannel::HandleSwException |
1233 // |
1256 // |
1234 TBool DRM_DebugChannel::HandleSwException(TAny* a1, TAny* a2) |
1257 TBool DRM_DebugChannel::HandleSwException(TAny* a1, TAny* a2) |
1235 { |
1258 { |
1236 LOG_EVENT_MSG("DRM_DebugChannel::HandleSwException"); |
1259 LOG_EVENT_MSG("DRM_DebugChannel::HandleSwException"); |
1237 TExcType aExcType = (TExcType)(TInt)a1; |
1260 TExcType aExcType = (TExcType)(TInt)a1; |
1238 |
1261 |
1239 TDriverEventInfo info; |
1262 TDriverEventInfo info; |
1240 |
1263 |
1241 DThread* currentThread = &Kern::CurrentThread(); |
1264 DThread* currentThread = &Kern::CurrentThread(); |
1242 if (!currentThread) |
1265 if (!currentThread) |
1243 { |
1266 { |
1244 LOG_MSG("Error getting current thread"); |
1267 LOG_MSG("Error getting current thread"); |
1245 __NK_ASSERT_DEBUG(currentThread); |
1268 __NK_ASSERT_DEBUG(currentThread); |
1246 return EFalse; |
1269 return EFalse; |
1247 } |
1270 } |
1248 |
1271 |
1249 info.iProcessId = currentThread->iOwningProcess->iId; |
1272 info.iProcessId = currentThread->iOwningProcess->iId; |
1250 info.iProcessIdValid = ETrue; |
1273 info.iProcessIdValid = ETrue; |
1251 info.iThreadId = currentThread->iId; |
1274 info.iThreadId = currentThread->iId; |
1252 info.iThreadIdValid = ETrue; |
1275 info.iThreadIdValid = ETrue; |
1253 TInt err = ReadKernelRegisterValue(currentThread, PC_REGISTER, info.iCurrentPC); |
1276 TInt err = ReadKernelRegisterValue(currentThread, PC_REGISTER, info.iCurrentPC); |
1254 if(err != KErrNone) |
1277 if(err != KErrNone) |
1255 { |
1278 { |
1256 LOG_EVENT_MSG2("DRM_DebugChannel::HandleSwException - Non-zero error code discarded: %d", err); |
1279 LOG_EVENT_MSG2("DRM_DebugChannel::HandleSwException - Non-zero error code discarded: %d", err); |
1257 } |
1280 } |
1258 info.iExceptionNumber = aExcType; |
1281 info.iExceptionNumber = aExcType; |
1259 info.iEventType = EEventsSwExc; |
1282 info.iEventType = EEventsSwExc; |
1260 info.iArg1 = a1; |
1283 info.iArg1 = a1; |
1261 info.iArg2 = a2; |
1284 info.iArg2 = a2; |
1262 |
1285 |
1263 NotifyEvent(info); |
1286 NotifyEvent(info); |
1264 |
1287 |
1265 return EFalse; |
1288 return EFalse; |
1266 } |
1289 } |
1267 |
1290 |
1268 // |
1291 // |
1269 // DRM_DebugChannel::HandleHwException |
1292 // DRM_DebugChannel::HandleHwException |
1270 // |
1293 // |
1271 TBool DRM_DebugChannel::HandleHwException(TAny* a1, TAny* a2) |
1294 TBool DRM_DebugChannel::HandleHwException(TAny* a1, TAny* a2) |
1272 { |
1295 { |
1273 LOG_EVENT_MSG("DRM_DebugChannel::HandleHwException()"); |
|
1274 TArmExcInfo* aExcInfo = (TArmExcInfo*)a1; |
1296 TArmExcInfo* aExcInfo = (TArmExcInfo*)a1; |
1275 |
1297 |
1276 // sanity check |
1298 // sanity check |
1277 if (!aExcInfo) |
1299 if (!aExcInfo) |
1278 { |
1300 { |
1279 LOG_MSG("DRM_DebugChannel::HandleHwException called with no aExcInfo"); |
1301 LOG_MSG("DRM_DebugChannel::HandleHwException called with no aExcInfo"); |
1280 __NK_ASSERT_DEBUG(aExcInfo); |
1302 __NK_ASSERT_DEBUG(aExcInfo); |
1281 return EFalse; |
1303 return EFalse; |
1282 } |
1304 } |
1283 |
1305 |
1284 TDriverEventInfo info; |
1306 TDriverEventInfo info; |
1285 |
1307 |
1286 DThread* currentThread = &Kern::CurrentThread(); |
1308 DThread* currentThread = &Kern::CurrentThread(); |
1287 LOG_EVENT_MSG2("DRM_DebugChannel::HandleHwException current thread = 0x%x", currentThread); |
|
1288 |
1309 |
1289 if (!currentThread) |
1310 if (!currentThread) |
1290 { |
1311 { |
1291 LOG_MSG("Error getting current thread"); |
1312 LOG_MSG("Error getting current thread"); |
1292 __NK_ASSERT_DEBUG(currentThread); |
1313 __NK_ASSERT_DEBUG(currentThread); |
1293 return EFalse; |
1314 return EFalse; |
1294 } |
1315 } |
1295 |
1316 |
1296 info.iProcessId = currentThread->iOwningProcess->iId; |
1317 info.iProcessId = currentThread->iOwningProcess->iId; |
1297 info.iProcessIdValid = ETrue; |
1318 info.iProcessIdValid = ETrue; |
1298 info.iThreadId = currentThread->iId; |
1319 info.iThreadId = currentThread->iId; |
1299 info.iThreadIdValid = ETrue; |
1320 info.iThreadIdValid = ETrue; |
1300 info.iRmdArmExcInfo.iFaultAddress= aExcInfo->iFaultAddress; |
1321 info.iRmdArmExcInfo.iFaultAddress= aExcInfo->iFaultAddress; |
1301 info.iRmdArmExcInfo.iFaultStatus= aExcInfo->iFaultStatus; |
1322 info.iRmdArmExcInfo.iFaultStatus= aExcInfo->iFaultStatus; |
1302 LOG_EVENT_MSG3("DRM_DebugChannel::HandleHwException iFaultAddress=0x%x, iFaultStatus=0x%x", |
1323 |
1303 aExcInfo->iFaultAddress, aExcInfo->iFaultStatus); |
1324 LOG_MSG5("DRM_DebugChannel::HandleHwException current thread = 0x%08x, CritSect count=%d,\n" |
1325 " iFaultAddress=0x%08x, iFaultStatus=0x%08x", |
|
1326 currentThread, currentThread->iNThread.iCsCount, aExcInfo->iFaultAddress, aExcInfo->iFaultStatus); |
|
1304 |
1327 |
1305 info.iRmdArmExcInfo.iR0= aExcInfo->iR0; |
1328 info.iRmdArmExcInfo.iR0= aExcInfo->iR0; |
1306 info.iRmdArmExcInfo.iR1= aExcInfo->iR1; |
1329 info.iRmdArmExcInfo.iR1= aExcInfo->iR1; |
1307 info.iRmdArmExcInfo.iR2= aExcInfo->iR2; |
1330 info.iRmdArmExcInfo.iR2= aExcInfo->iR2; |
1308 info.iRmdArmExcInfo.iR3= aExcInfo->iR3; |
1331 info.iRmdArmExcInfo.iR3= aExcInfo->iR3; |
1318 info.iRmdArmExcInfo.iR12= aExcInfo->iR12; |
1341 info.iRmdArmExcInfo.iR12= aExcInfo->iR12; |
1319 |
1342 |
1320 info.iRmdArmExcInfo.iR13= aExcInfo->iR13; |
1343 info.iRmdArmExcInfo.iR13= aExcInfo->iR13; |
1321 info.iRmdArmExcInfo.iR14= aExcInfo->iR14; |
1344 info.iRmdArmExcInfo.iR14= aExcInfo->iR14; |
1322 info.iRmdArmExcInfo.iR15= aExcInfo->iR15; |
1345 info.iRmdArmExcInfo.iR15= aExcInfo->iR15; |
1323 LOG_EVENT_MSG5(" R12=0x%x, R13=0x%x, R14=0x%x, R15=0x%x ", |
|
1324 aExcInfo->iR12, aExcInfo->iR13, aExcInfo->iR14, aExcInfo->iR15); |
|
1325 |
1346 |
1326 info.iRmdArmExcInfo.iCpsr= aExcInfo->iCpsr; |
1347 info.iRmdArmExcInfo.iCpsr= aExcInfo->iCpsr; |
1327 info.iRmdArmExcInfo.iR13Svc= aExcInfo->iR13Svc; |
1348 info.iRmdArmExcInfo.iR13Svc= aExcInfo->iR13Svc; |
1328 info.iRmdArmExcInfo.iR14Svc= aExcInfo->iR14Svc; |
1349 info.iRmdArmExcInfo.iR14Svc= aExcInfo->iR14Svc; |
1329 info.iRmdArmExcInfo.iSpsrSvc= aExcInfo->iSpsrSvc; |
1350 info.iRmdArmExcInfo.iSpsrSvc= aExcInfo->iSpsrSvc; |
1330 LOG_EVENT_MSG5(" iCpsr=0x%x, iR13Svc=0x%x, iR14Svc=0x%x, iSpsrSvc=0x%x ", |
1351 LOG_MSG5(" iCpsr=0x%x, iExcCode=0x%x, R14=0x%x, R15=0x%x", |
1331 aExcInfo->iCpsr, aExcInfo->iR13Svc, aExcInfo->iR14Svc, aExcInfo->iSpsrSvc); |
1352 aExcInfo->iCpsr, aExcInfo->iExcCode, aExcInfo->iR14, aExcInfo->iR15); |
1332 |
1353 |
1333 switch (aExcInfo->iExcCode) |
1354 switch (aExcInfo->iExcCode) |
1334 { |
1355 { |
1335 case 0: |
1356 case 0: |
1336 info.iExceptionNumber = EExcCodeAbort; |
1357 info.iExceptionNumber = EExcCodeAbort; |
1337 LOG_EVENT_MSG(" iExcCode == 0 => EExcCodeAbort"); |
1358 LOG_EVENT_MSG(" iExcCode == 0 => EExcCodeAbort"); |
1338 break; |
1359 break; |
1339 case 1: |
1360 case 1: |
1346 break; |
1367 break; |
1347 default: |
1368 default: |
1348 // new event? Something gone wrong? |
1369 // new event? Something gone wrong? |
1349 __NK_ASSERT_DEBUG(EFalse); |
1370 __NK_ASSERT_DEBUG(EFalse); |
1350 return EFalse; |
1371 return EFalse; |
1351 |
1372 } |
1352 } |
1373 |
1353 info.iEventType = EEventsHwExc; |
1374 info.iEventType = EEventsHwExc; |
1354 |
1375 |
1355 info.iArg1 = a1; |
1376 info.iArg1 = a1; |
1356 info.iArg2 = a2; |
1377 info.iArg2 = a2; |
1357 |
1378 |
1360 return HandleInvalidOpCodeException(info, currentThread); |
1381 return HandleInvalidOpCodeException(info, currentThread); |
1361 } |
1382 } |
1362 |
1383 |
1363 NotifyEvent(info); |
1384 NotifyEvent(info); |
1364 return EFalse; |
1385 return EFalse; |
1365 } |
1386 } |
1366 |
1387 |
1367 // |
1388 // |
1368 // DRM_DebugChannel::HandUserTrace |
1389 // DRM_DebugChannel::HandUserTrace |
1369 // |
1390 // |
1370 TBool DRM_DebugChannel::HandleUserTrace(TAny* a1, TAny* a2) |
1391 TBool DRM_DebugChannel::HandleUserTrace(TAny* a1, TAny* a2) |
1371 { |
1392 { |
1372 LOG_EVENT_MSG("DRM_DebugChannel::HandleUserTrace()"); |
1393 LOG_EVENT_MSG("DRM_DebugChannel::HandleUserTrace()"); |
1373 |
1394 |
1374 DThread* currentThread = &Kern::CurrentThread(); |
1395 DThread* currentThread = &Kern::CurrentThread(); |
1375 if (!currentThread) |
1396 if (!currentThread) |
1376 { |
1397 { |
1377 LOG_EVENT_MSG("Error getting current thread"); |
1398 LOG_EVENT_MSG("Error getting current thread"); |
1378 __NK_ASSERT_DEBUG(currentThread); |
1399 __NK_ASSERT_DEBUG(currentThread); |
1379 return EFalse; |
1400 return EFalse; |
1380 } |
1401 } |
1381 |
1402 |
1382 TDriverEventInfo info; |
1403 TDriverEventInfo info; |
1383 info.iProcessId = currentThread->iOwningProcess->iId; |
1404 info.iProcessId = currentThread->iOwningProcess->iId; |
1384 info.iProcessIdValid = ETrue; |
1405 info.iProcessIdValid = ETrue; |
1385 info.iThreadId = currentThread->iId; |
1406 info.iThreadId = currentThread->iId; |
1400 info.iMessageStatus = ESingleMessage; |
1421 info.iMessageStatus = ESingleMessage; |
1401 |
1422 |
1402 NotifyEvent(info); |
1423 NotifyEvent(info); |
1403 |
1424 |
1404 return EFalse; |
1425 return EFalse; |
1405 } |
1426 } |
1406 |
1427 |
1407 // |
1428 // |
1408 // DRM_DebugChannel::HandleException |
1429 // DRM_DebugChannel::HandleException |
1409 // |
1430 // |
1410 TBool DRM_DebugChannel::HandleInvalidOpCodeException(TDriverEventInfo& aEventInfo, DThread* aCurrentThread) |
1431 TBool DRM_DebugChannel::HandleInvalidOpCodeException(TDriverEventInfo& aEventInfo, DThread* aCurrentThread) |
1411 { |
1432 { |
1412 LOG_EVENT_MSG("DRM_DebugChannel::HandleInvalidOpCodeException()"); |
1433 LOG_MSG("DRM_DebugChannel::HandleInvalidOpCodeException()"); |
1413 |
1434 |
1414 TInt err = KErrNone; |
1435 TInt err = KErrNone; |
1415 |
1436 |
1416 TUint32 inst = KArmBreakPoint; |
1437 TUint32 inst = KArmBreakPoint; |
1417 TInt instSize = 4; |
1438 TInt instSize = 4; |
1418 |
1439 |
1419 // change these for thumb mode |
1440 // change these for thumb mode |
1420 TUint32 regValue; |
1441 TUint32 regValue; |
1421 err = ReadKernelRegisterValue(aCurrentThread, STATUS_REGISTER, regValue); |
1442 err = ReadKernelRegisterValue(aCurrentThread, STATUS_REGISTER, regValue); |
1422 if(err != KErrNone) |
1443 if(err != KErrNone) |
1423 { |
1444 { |
1424 LOG_EVENT_MSG2("DRM_DebugChannel::HandleInvalidOpCodeException - Non-zero error code discarded: %d", err); |
1445 LOG_MSG2("DRM_DebugChannel::HandleInvalidOpCodeException - Non-zero error code discarded: %d", err); |
1425 } |
1446 } |
1447 |
|
1426 if (regValue & ECpuThumb) |
1448 if (regValue & ECpuThumb) |
1427 { |
1449 { |
1428 inst = KThumbBreakPoint; |
1450 inst = KThumbBreakPoint; |
1429 instSize = 2; |
1451 instSize = 2; |
1430 } |
1452 } |
1431 |
1453 |
1432 TUint32 instruction = 0; |
1454 TUint32 instruction = 0; |
1433 err = Kern::ThreadRawRead(aCurrentThread, (TUint32 *)aEventInfo.iRmdArmExcInfo.iR15, (TUint8 *)&instruction, instSize); |
1455 err = Kern::ThreadRawRead(aCurrentThread, (TUint32 *)aEventInfo.iRmdArmExcInfo.iR15, (TUint8 *)&instruction, instSize); |
1434 |
1456 |
1435 if (KErrNone != err) |
1457 if (KErrNone != err) |
1436 LOG_EVENT_MSG2("Error reading instruction at currentpc: %d", err); |
1458 LOG_MSG2("Error reading instruction at currentpc: %d", err); |
1437 |
1459 |
1438 if (!memcompare((TUint8 *)&inst, instSize, (TUint8 *)&instruction, instSize)) |
1460 if (!memcompare((TUint8 *)&inst, instSize, (TUint8 *)&instruction, instSize)) |
1439 { |
1461 { |
1440 TInt err = DoSuspendThread(aCurrentThread); |
1462 TInt err = DoSuspendThread(aCurrentThread); |
1441 if(! ((KErrNone == err) || (KErrAlreadyExists == err)) ) |
1463 if(! ((KErrNone == err) || (KErrAlreadyExists == err)) ) |
1442 { |
1464 { |
1443 LOG_EVENT_MSG2("DRM_DebugChannel::HandleInvalidOpCodeException() Thread with id 0x%08x could not be suspended.", aCurrentThread->iId); |
1465 LOG_MSG2("DRM_DebugChannel::HandleInvalidOpCodeException() Thread with id 0x%08x could not be suspended.", aCurrentThread->iId); |
1444 return EFalse; |
1466 return EFalse; |
1445 } |
1467 } |
1446 |
1468 |
1447 // the exception was a breakpoint instruction. see if we have a breakpoint at that address |
1469 // the exception was a breakpoint instruction. see if we have a breakpoint at that address |
1448 TBreakEntry* breakEntry = NULL; |
1470 TBreakEntry* breakEntry = NULL; |
1449 do |
1471 do |
1450 { |
1472 { |
1451 breakEntry = iBreakManager->GetNextBreak(breakEntry); |
1473 breakEntry = iBreakManager->GetNextBreak(breakEntry); |
1452 if (breakEntry && ((breakEntry->iThreadSpecific && breakEntry->iId == aEventInfo.iThreadId) || (!breakEntry->iThreadSpecific && breakEntry->iId == aEventInfo.iProcessId)) && breakEntry->iAddress == aEventInfo.iRmdArmExcInfo.iR15) |
1474 if (breakEntry && ((breakEntry->iThreadSpecific && breakEntry->iId == aEventInfo.iThreadId) || (!breakEntry->iThreadSpecific && breakEntry->iId == aEventInfo.iProcessId)) && breakEntry->iAddress == aEventInfo.iRmdArmExcInfo.iR15) |
1453 { |
1475 { |
1454 LOG_EVENT_MSG2("Breakpoint with Id %d has been hit", breakEntry->iBreakId); |
1476 LOG_MSG2("Breakpoint with Id %d has been hit", breakEntry->iBreakId); |
1455 |
1477 |
1456 TBreakEntry tempBreakEntry = *breakEntry; |
1478 TBreakEntry tempBreakEntry = *breakEntry; |
1457 |
1479 |
1458 //change the event type to breakpoint type |
1480 //change the event type to breakpoint type |
1459 aEventInfo.iEventType = breakEntry->iThreadSpecific ? EEventsBreakPoint : EEventsProcessBreakPoint; |
1481 aEventInfo.iEventType = breakEntry->iThreadSpecific ? EEventsBreakPoint : EEventsProcessBreakPoint; |
1463 if (KErrNone != err) |
1485 if (KErrNone != err) |
1464 LOG_MSG2("Error %d enabling disabled breakpoints", err); |
1486 LOG_MSG2("Error %d enabling disabled breakpoints", err); |
1465 |
1487 |
1466 // see if this is a temp breakpoint |
1488 // see if this is a temp breakpoint |
1467 if (iBreakManager->IsTemporaryBreak(*breakEntry)) |
1489 if (iBreakManager->IsTemporaryBreak(*breakEntry)) |
1468 { |
1490 { |
1469 // this was a temp breakpoint, so we need to clear it now |
1491 // this was a temp breakpoint, so we need to clear it now |
1470 err = iBreakManager->DoClearBreak(breakEntry->iBreakId); |
1492 err = iBreakManager->DoClearBreak(breakEntry->iBreakId); |
1471 if (KErrNone != err) |
1493 if (KErrNone != err) |
1472 LOG_MSG2("Error %d clearing temp breakpoint", err); |
1494 LOG_MSG2("Error %d clearing temp breakpoint", err); |
1473 |
1495 |
1474 // Find out how many steps remain to be done |
1496 // Find out how many steps remain to be done |
1475 |
1497 |
1476 // reduce the number of steps to complete by 1 |
1498 // reduce the number of steps to complete by 1 |
1477 tempBreakEntry.iNumSteps--; |
1499 tempBreakEntry.iNumSteps--; |
1478 |
1500 |
1479 LOG_EVENT_MSG2("There are %d steps remaining\n", tempBreakEntry.iNumSteps); |
1501 LOG_MSG2("There are %d steps remaining\n", tempBreakEntry.iNumSteps); |
1480 |
1502 |
1481 // New. If we have not finished do all the steps, continue stepping and don't notify event |
1503 // New. If we have not finished do all the steps, continue stepping and don't notify event |
1482 if (tempBreakEntry.iNumSteps) |
1504 if (tempBreakEntry.iNumSteps) |
1483 { |
1505 { |
1484 LOG_EVENT_MSG("Continuing stepping...not telling the agent yet\n"); |
1506 LOG_MSG("Continuing stepping...not telling the agent yet\n"); |
1485 err = DoStepRange(aCurrentThread, aEventInfo.iRmdArmExcInfo.iR15, aEventInfo.iRmdArmExcInfo.iR15, ETrue, tempBreakEntry.iResumeOnceOutOfRange /*EFalse*/, tempBreakEntry.iNumSteps, ETrue); |
1507 err = DoStepRange(aCurrentThread, aEventInfo.iRmdArmExcInfo.iR15, aEventInfo.iRmdArmExcInfo.iR15, ETrue, tempBreakEntry.iResumeOnceOutOfRange /*EFalse*/, tempBreakEntry.iNumSteps, ETrue); |
1486 if (err != KErrNone) |
1508 if (err != KErrNone) |
1487 { |
1509 { |
1488 LOG_EVENT_MSG("Failed to continue stepping\n"); |
1510 LOG_EVENT_MSG("Failed to continue stepping\n"); |
1489 |
1511 |
1490 // what do we do? might as well stop here and tell the user |
1512 // what do we do? might as well stop here and tell the user |
1491 NotifyEvent(aEventInfo); |
1513 NotifyEvent(aEventInfo); |
1492 |
1514 |
1493 return ETrue; |
1515 return ETrue; |
1516 } |
|
1517 |
|
1518 // continue as though no event occured. No need to suspend/resume anything... |
|
1519 LOG_MSG("Continuing to step\n"); |
|
1520 return ETrue; |
|
1494 } |
1521 } |
1495 |
|
1496 // continue as though no event occured. No need to suspend/resume anything... |
|
1497 LOG_EVENT_MSG("Continuing to step\n"); |
|
1498 return ETrue; |
|
1499 } |
|
1500 |
1522 |
1501 // Is this a case where we just want to continue? |
1523 // Is this a case where we just want to continue? |
1502 if (tempBreakEntry.iResumeOnceOutOfRange) |
1524 if (tempBreakEntry.iResumeOnceOutOfRange) |
1503 { |
1525 { |
1504 LOG_EVENT_MSG("PC is out of range, continuing thread"); |
1526 LOG_MSG("PC is out of range, continuing thread"); |
1505 DoResumeThread(aCurrentThread); |
1527 DoResumeThread(aCurrentThread); |
1506 |
1528 |
1507 return ETrue; |
1529 return ETrue; |
1508 } |
1530 } |
1509 } |
1531 } |
1510 |
1532 |
1511 // if the breakpoint is thread specific, make sure it's the right thread |
1533 // if the breakpoint is thread specific, make sure it's the right thread |
1512 // if not, just continue the thread. take special care if it's the debugger |
1534 // if not, just continue the thread. take special care if it's the debugger |
1513 // thread. if it hits a regular breakpoint, we NEVER want to stop at it. if |
1535 // thread. if it hits a regular breakpoint, we NEVER want to stop at it. if |
1515 // and we do need to handle it. |
1537 // and we do need to handle it. |
1516 TBool needToResume = (tempBreakEntry.iThreadSpecific && tempBreakEntry.iId != aEventInfo.iThreadId) || |
1538 TBool needToResume = (tempBreakEntry.iThreadSpecific && tempBreakEntry.iId != aEventInfo.iThreadId) || |
1517 (!tempBreakEntry.iThreadSpecific && tempBreakEntry.iId != aEventInfo.iProcessId); |
1539 (!tempBreakEntry.iThreadSpecific && tempBreakEntry.iId != aEventInfo.iProcessId); |
1518 |
1540 |
1519 if (needToResume) |
1541 if (needToResume) |
1520 { |
1542 { |
1521 LOG_EVENT_MSG("breakpoint does not match threadId, calling DoResumeThread"); |
1543 LOG_MSG("breakpoint does not match threadId, calling DoResumeThread"); |
1522 err = DoResumeThread(aCurrentThread); |
1544 err = DoResumeThread(aCurrentThread); |
1523 if (KErrNone != err) |
1545 if (KErrNone != err) |
1524 LOG_EVENT_MSG2("Error in DoResumeThread: %d", err); |
1546 LOG_MSG2("Error in DoResumeThread: %d", err); |
1525 |
1547 |
1526 return EFalse; |
1548 return EFalse; |
1527 } |
1549 } |
1528 |
1550 |
1529 //normal user break point, just notify the event |
1551 //normal user break point, just notify the event |
1530 break; |
1552 break; |
1531 } |
1553 } |
1532 } while(breakEntry); |
1554 } while(breakEntry); |
1533 } |
1555 } |
1534 |
1556 |
1535 NotifyEvent(aEventInfo); |
1557 NotifyEvent(aEventInfo); |
1536 |
1558 |
1537 return (aEventInfo.iEventType == EEventsBreakPoint) || (aEventInfo.iEventType == EEventsProcessBreakPoint); |
1559 return (aEventInfo.iEventType == EEventsBreakPoint) || (aEventInfo.iEventType == EEventsProcessBreakPoint); |
1538 } |
1560 } |
1539 |
1561 |
1540 // |
1562 // |
1541 // DRM_DebugChannel::SetBreak |
1563 // DRM_DebugChannel::SetBreak |
1542 // |
1564 // |
1543 TInt DRM_DebugChannel::SetBreak(TSetBreakInfo* aBreakInfo) |
1565 TInt DRM_DebugChannel::SetBreak(TSetBreakInfo* aBreakInfo) |
1544 { |
1566 { |
1545 LOG_MSG("DRM_DebugChannel::SetBreak()"); |
1567 LOG_MSG("DRM_DebugChannel::SetBreak()"); |
1546 |
1568 |
1547 TInt err = KErrNone; |
1569 TInt err = KErrNone; |
1548 |
1570 |
1549 if (!aBreakInfo) |
1571 if (!aBreakInfo) |
1550 { |
1572 { |
1551 LOG_MSG("DRM_DebugChannel::SetBreak() was passed a NULL argument"); |
1573 LOG_MSG("DRM_DebugChannel::SetBreak() was passed a NULL argument"); |
1552 return KErrArgument; |
1574 return KErrArgument; |
1553 } |
1575 } |
1554 |
1576 |
1555 //User side memory is not accessible directly |
1577 //User side memory is not accessible directly |
1556 TSetBreakInfo info; |
1578 TSetBreakInfo info; |
1557 err = Kern::ThreadRawRead(iClientThread, aBreakInfo, (TUint8*)&info, sizeof(TSetBreakInfo)); |
1579 err = Kern::ThreadRawRead(iClientThread, aBreakInfo, (TUint8*)&info, sizeof(TSetBreakInfo)); |
1558 if (err != KErrNone) |
1580 if (err != KErrNone) |
1559 { |
1581 { |
1560 LOG_MSG("DRM_DebugChannel::SetBreak() was passed a bad argument"); |
1582 LOG_MSG("DRM_DebugChannel::SetBreak() was passed a bad argument"); |
1561 return err; |
1583 return err; |
1562 } |
1584 } |
1563 |
1585 |
1564 DProcess* process = NULL; |
1586 DProcess* process = NULL; |
1565 if(info.iThreadSpecific) |
1587 if(info.iThreadSpecific) |
1566 { |
1588 { |
1567 // if the target thread is not suspended then return KErrInUse |
1589 // if the target thread is not suspended then return KErrInUse |
1581 } |
1603 } |
1582 else |
1604 else |
1583 { |
1605 { |
1584 process = DebugUtils::OpenProcessHandle(info.iId); |
1606 process = DebugUtils::OpenProcessHandle(info.iId); |
1585 } |
1607 } |
1608 |
|
1586 if(!process) |
1609 if(!process) |
1587 { |
1610 { |
1588 LOG_MSG2("DRM_DebugChannel::SetBreak() Process with id 0x%08x not found", process->iId); |
1611 LOG_MSG2("DRM_DebugChannel::SetBreak() Process with id 0x%08x not found", process->iId); |
1589 return KErrNotFound; |
1612 return KErrNotFound; |
1590 } |
1613 } |
1614 |
|
1591 TBool found = EFalse; |
1615 TBool found = EFalse; |
1592 for(TInt i=0; i<iDebugProcessList.Count(); i++) |
1616 for(TInt i=0; i<iDebugProcessList.Count(); i++) |
1593 { |
1617 { |
1594 if(process->iId == iDebugProcessList[i].iId) |
1618 if(process->iId == iDebugProcessList[i].iId) |
1595 { |
1619 { |
1596 found = ETrue; |
1620 found = ETrue; |
1597 } |
1621 } |
1598 } |
1622 } |
1623 |
|
1599 if(!found) |
1624 if(!found) |
1600 { |
1625 { |
1601 DCodeSeg* codeSeg = process->iCodeSeg; |
1626 DCodeSeg* codeSeg = process->iCodeSeg; |
1602 if (!codeSeg) |
1627 if (!codeSeg) |
1603 { |
1628 { |
1621 |
1646 |
1622 if (!info.iBreakId) //first check if the iId address is valid |
1647 if (!info.iBreakId) //first check if the iId address is valid |
1623 return KErrArgument; |
1648 return KErrArgument; |
1624 |
1649 |
1625 if (err == KErrNone) |
1650 if (err == KErrNone) |
1626 { |
1651 { |
1627 TInt32 iBreakId; |
1652 TInt32 iBreakId; |
1628 |
1653 |
1629 err = iBreakManager->DoSetBreak(iBreakId, info.iId, info.iThreadSpecific, info.iAddress, info.iMode ); |
1654 err = iBreakManager->DoSetBreak(iBreakId, info.iId, info.iThreadSpecific, info.iAddress, info.iMode ); |
1630 |
1655 |
1631 if (err == KErrNone) |
1656 if (err == KErrNone) |
1632 { |
1657 { |
1633 err = Kern::ThreadRawWrite(iClientThread, (TUint8 *)info.iBreakId, &iBreakId, sizeof(TInt32), iClientThread); |
1658 err = Kern::ThreadRawWrite(iClientThread, (TUint8 *)info.iBreakId, &iBreakId, sizeof(TInt32), iClientThread); |
1634 } |
1659 } |
1635 } |
1660 } |
1661 |
|
1636 return err; |
1662 return err; |
1637 } |
1663 } |
1638 |
1664 |
1639 // |
1665 // |
1640 // DRM_DebugChannel::StepRange |
1666 // DRM_DebugChannel::StepRange |
1641 // |
1667 // |
1642 TInt DRM_DebugChannel::StepRange(DThread* aThread, TRM_DebugStepInfo* aStepInfo) |
1668 TInt DRM_DebugChannel::StepRange(DThread* aThread, TRM_DebugStepInfo* aStepInfo) |
1643 { |
1669 { |
1644 LOG_MSG("DRM_DebugChannel::StepRange()"); |
1670 LOG_MSG("DRM_DebugChannel::StepRange()"); |
1645 |
1671 |
1646 TInt err = KErrNone; |
1672 TInt err = KErrNone; |
1647 |
1673 |
1648 if(!TheDProcessTracker.CheckSuspended(aThread)) |
1674 if(!TheDProcessTracker.CheckSuspended(aThread)) |
1661 return err; |
1687 return err; |
1662 |
1688 |
1663 err = DoStepRange(aThread, info.iStartAddress, info.iStopAddress, info.iStepInto, EFalse, ETrue); |
1689 err = DoStepRange(aThread, info.iStartAddress, info.iStopAddress, info.iStepInto, EFalse, ETrue); |
1664 |
1690 |
1665 return err; |
1691 return err; |
1666 } |
1692 } |
1667 |
1693 |
1668 /** |
1694 /** |
1669 Read memory from a target thread and return the data to the client. If the |
1695 Read memory from a target thread and return the data to the client. If the |
1670 memory block has breakpoints in it then the correct values are placed in the |
1696 memory block has breakpoints in it then the correct values are placed in the |
1671 returned data |
1697 returned data |
1678 KErrNoMemory if a temporary buffer could not be allocated, |
1704 KErrNoMemory if a temporary buffer could not be allocated, |
1679 KErrBadHandle if aThread is invalid, |
1705 KErrBadHandle if aThread is invalid, |
1680 or another of the system wide error codes |
1706 or another of the system wide error codes |
1681 */ |
1707 */ |
1682 TInt DRM_DebugChannel::ReadMemory(DThread* aThread, TRM_DebugMemoryInfo* aMemoryInfo) |
1708 TInt DRM_DebugChannel::ReadMemory(DThread* aThread, TRM_DebugMemoryInfo* aMemoryInfo) |
1683 { |
1709 { |
1684 LOG_MSG("DRM_DebugChannel::ReadMemory()"); |
1710 LOG_MSG("DRM_DebugChannel::ReadMemory()"); |
1685 |
1711 |
1686 TInt err = KErrNone; |
1712 TInt err = KErrNone; |
1687 |
1713 |
1688 if (!aMemoryInfo) |
1714 if (!aMemoryInfo) |
1698 |
1724 |
1699 NKern::ThreadEnterCS(); |
1725 NKern::ThreadEnterCS(); |
1700 TUint8 *data = (TUint8*)Kern::Alloc(info.iLength); |
1726 TUint8 *data = (TUint8*)Kern::Alloc(info.iLength); |
1701 NKern::ThreadLeaveCS(); |
1727 NKern::ThreadLeaveCS(); |
1702 if (!data) |
1728 if (!data) |
1703 { |
1729 { |
1704 return KErrNoMemory; |
1730 return KErrNoMemory; |
1705 } |
1731 } |
1706 |
1732 |
1707 TPtr8 dataDes(data, info.iLength); |
1733 TPtr8 dataDes(data, info.iLength); |
1708 |
1734 |
1709 err = DoReadMemory(aThread, info.iAddress, info.iLength, dataDes); |
1735 err = DoReadMemory(aThread, info.iAddress, info.iLength, dataDes); |
1710 if (err == KErrNone) |
1736 if (err == KErrNone) |
1715 NKern::ThreadEnterCS(); |
1741 NKern::ThreadEnterCS(); |
1716 Kern::Free(data); |
1742 Kern::Free(data); |
1717 NKern::ThreadLeaveCS(); |
1743 NKern::ThreadLeaveCS(); |
1718 |
1744 |
1719 return err; |
1745 return err; |
1720 } |
1746 } |
1721 |
1747 |
1722 /** |
1748 /** |
1723 Attempt to write memory to aThread's address space |
1749 Attempt to write memory to aThread's address space |
1724 |
1750 |
1725 @param aThread thread to whose address space memory is to be written |
1751 @param aThread thread to whose address space memory is to be written |
1732 in descrptor |
1758 in descrptor |
1733 KErrBadHandle if aThread is invalid, |
1759 KErrBadHandle if aThread is invalid, |
1734 or another of the system wide error codes |
1760 or another of the system wide error codes |
1735 */ |
1761 */ |
1736 TInt DRM_DebugChannel::WriteMemory(DThread* aThread, TRM_DebugMemoryInfo* aMemoryInfo) |
1762 TInt DRM_DebugChannel::WriteMemory(DThread* aThread, TRM_DebugMemoryInfo* aMemoryInfo) |
1737 { |
1763 { |
1738 LOG_MSG("DRM_DebugChannel::WriteMemory()"); |
1764 LOG_MSG("DRM_DebugChannel::WriteMemory()"); |
1739 |
1765 |
1740 TInt err = KErrNone; |
1766 TInt err = KErrNone; |
1741 |
1767 |
1742 if (!aMemoryInfo) |
1768 if (!aMemoryInfo) |
1752 |
1778 |
1753 NKern::ThreadEnterCS(); |
1779 NKern::ThreadEnterCS(); |
1754 TUint8 *data = (TUint8*)Kern::Alloc(info.iLength); |
1780 TUint8 *data = (TUint8*)Kern::Alloc(info.iLength); |
1755 NKern::ThreadLeaveCS(); |
1781 NKern::ThreadLeaveCS(); |
1756 if (!data) |
1782 if (!data) |
1757 { |
1783 { |
1758 return KErrNoMemory; |
1784 return KErrNoMemory; |
1759 } |
1785 } |
1760 |
1786 |
1761 TPtr8 dataDes(data, info.iLength); |
1787 TPtr8 dataDes(data, info.iLength); |
1762 |
1788 |
1763 err = Kern::ThreadDesRead(iClientThread, info.iData, dataDes, 0); |
1789 err = Kern::ThreadDesRead(iClientThread, info.iData, dataDes, 0); |
1764 if (err == KErrNone) |
1790 if (err == KErrNone) |
1765 { |
1791 { |
1766 err = DoWriteMemory(aThread, info.iAddress, info.iLength, dataDes); |
1792 err = DoWriteMemory(aThread, info.iAddress, info.iLength, dataDes); |
1767 } |
1793 } |
1768 |
1794 |
1769 NKern::ThreadEnterCS(); |
1795 NKern::ThreadEnterCS(); |
1770 Kern::Free(data); |
1796 Kern::Free(data); |
1771 NKern::ThreadLeaveCS(); |
1797 NKern::ThreadLeaveCS(); |
1772 |
1798 |
1773 return err; |
1799 return err; |
1774 } |
1800 } |
1775 |
1801 |
1776 // |
1802 // |
1777 // DRM_DebugChannel::ReadRegisters |
1803 // DRM_DebugChannel::ReadRegisters |
1778 // |
1804 // |
1779 TInt DRM_DebugChannel::ReadRegistersLegacy(DThread* aThread, TRM_DebugRegisterInfo* aRegisterInfo) |
1805 TInt DRM_DebugChannel::ReadRegistersLegacy(DThread* aThread, TRM_DebugRegisterInfo* aRegisterInfo) |
1780 { |
1806 { |
1781 LOG_MSG("DRM_DebugChannel::ReadRegistersLegacy()"); |
1807 LOG_MSG("DRM_DebugChannel::ReadRegistersLegacy()"); |
1782 |
1808 |
1783 TInt err = KErrNone; |
1809 TInt err = KErrNone; |
1784 |
1810 |
1785 if (!aRegisterInfo) |
1811 if (!aRegisterInfo) |
1797 |
1823 |
1798 NKern::ThreadEnterCS(); |
1824 NKern::ThreadEnterCS(); |
1799 TUint8 *values = (TUint8*)Kern::Alloc(length); |
1825 TUint8 *values = (TUint8*)Kern::Alloc(length); |
1800 NKern::ThreadLeaveCS(); |
1826 NKern::ThreadLeaveCS(); |
1801 if (!values) |
1827 if (!values) |
1802 { |
1828 { |
1803 return KErrNoMemory; |
1829 return KErrNoMemory; |
1804 } |
1830 } |
1805 |
1831 |
1806 TPtr8 valuesDes(values, length); |
1832 TPtr8 valuesDes(values, length); |
1807 |
1833 |
1808 err = DoReadRegisters(aThread, info.iFirstRegister, info.iLastRegister, valuesDes); |
1834 err = DoReadRegisters(aThread, info.iFirstRegister, info.iLastRegister, valuesDes); |
1809 if (err == KErrNone) |
1835 if (err == KErrNone) |
1810 { |
1836 { |
1811 err = Kern::ThreadDesWrite(iClientThread, info.iValues, valuesDes, 0, KChunkShiftBy0, iClientThread); |
1837 err = Kern::ThreadDesWrite(iClientThread, info.iValues, valuesDes, 0, KChunkShiftBy0, iClientThread); |
1812 } |
1838 } |
1813 |
1839 |
1814 NKern::ThreadEnterCS(); |
1840 NKern::ThreadEnterCS(); |
1815 Kern::Free(values); |
1841 Kern::Free(values); |
1816 NKern::ThreadLeaveCS(); |
1842 NKern::ThreadLeaveCS(); |
1817 |
1843 |
1818 return err; |
1844 return err; |
1819 } |
1845 } |
1820 |
1846 |
1821 /** |
1847 /** |
1822 Get listing information. |
1848 Get listing information. |
1823 |
1849 |
1824 @param aListInformation pointer to a TListInformation object containing the |
1850 @param aListInformation pointer to a TListInformation object containing the |
1920 if(err == KErrNone) |
1946 if(err == KErrNone) |
1921 { |
1947 { |
1922 //if no error then write the buffer back |
1948 //if no error then write the buffer back |
1923 err = Kern::ThreadDesWrite(iClientThread, info.iBuffer, buffer, 0, KChunkShiftBy0, iClientThread); |
1949 err = Kern::ThreadDesWrite(iClientThread, info.iBuffer, buffer, 0, KChunkShiftBy0, iClientThread); |
1924 } |
1950 } |
1951 |
|
1925 //write back the size of the data regardless of any error |
1952 //write back the size of the data regardless of any error |
1926 TInt writeErr = Kern::ThreadRawWrite(iClientThread, info.iDataSize, (TUint8*)&dataSize, sizeof(TUint32), iClientThread); |
1953 TInt writeErr = Kern::ThreadRawWrite(iClientThread, info.iDataSize, (TUint8*)&dataSize, sizeof(TUint32), iClientThread); |
1927 if(writeErr != KErrNone) |
1954 if(writeErr != KErrNone) |
1928 { |
1955 { |
1929 //if there was an error writing the size return that error instead |
1956 //if there was an error writing the size return that error instead |
1954 specified or if the passed in register values buffer is too small |
1981 specified or if the passed in register values buffer is too small |
1955 KErrNoMemory if there is insufficient memory, |
1982 KErrNoMemory if there is insufficient memory, |
1956 KErrDied, if the thread with thread ID aThreadId is dead |
1983 KErrDied, if the thread with thread ID aThreadId is dead |
1957 */ |
1984 */ |
1958 TInt DRM_DebugChannel::ReadRegisters(DThread* aThread, TRM_DebugRegisterInformation* aRegisterInfo) const |
1985 TInt DRM_DebugChannel::ReadRegisters(DThread* aThread, TRM_DebugRegisterInformation* aRegisterInfo) const |
1959 { |
1986 { |
1960 LOG_MSG("DRM_DebugChannel::ReadRegisters()"); |
1987 LOG_MSG("DRM_DebugChannel::ReadRegisters()"); |
1961 |
1988 |
1962 TInt err = KErrNone; |
1989 TInt err = KErrNone; |
1963 |
1990 |
1964 if (!aRegisterInfo) |
1991 if (!aRegisterInfo) |
1976 TPtr8 ids(NULL, 0); |
2003 TPtr8 ids(NULL, 0); |
1977 err = AllocAndReadDes(iClientThread, *info.iRegisterIds, ids); |
2004 err = AllocAndReadDes(iClientThread, *info.iRegisterIds, ids); |
1978 if(err != KErrNone) |
2005 if(err != KErrNone) |
1979 { |
2006 { |
1980 if(err == KErrNoMemory) |
2007 if(err == KErrNoMemory) |
1981 { |
2008 { |
1982 NKern::ThreadEnterCS(); |
2009 NKern::ThreadEnterCS(); |
1983 Kern::Free((TAny*)ids.Ptr()); |
2010 Kern::Free((TAny*)ids.Ptr()); |
1984 NKern::ThreadLeaveCS(); |
2011 NKern::ThreadLeaveCS(); |
1985 } |
2012 } |
1986 return err; |
2013 return err; |
1987 } |
2014 } |
1988 |
2015 |
1989 //read values from client thread |
2016 //read values from client thread |
1990 TPtr8 values(NULL, 0); |
2017 TPtr8 values(NULL, 0); |
1991 err = AllocAndReadDes(iClientThread, *info.iRegisterValues, values, EFalse); |
2018 err = AllocAndReadDes(iClientThread, *info.iRegisterValues, values, EFalse); |
1992 if(err != KErrNone) |
2019 if(err != KErrNone) |
1993 { |
2020 { |
1994 if(err == KErrNoMemory) |
2021 if(err == KErrNoMemory) |
1995 { NKern::ThreadEnterCS(); |
2022 { |
2023 NKern::ThreadEnterCS(); |
|
1996 Kern::Free((TAny*)values.Ptr()); |
2024 Kern::Free((TAny*)values.Ptr()); |
1997 NKern::ThreadLeaveCS(); |
2025 NKern::ThreadLeaveCS(); |
1998 } |
2026 } |
2027 |
|
1999 NKern::ThreadEnterCS(); |
2028 NKern::ThreadEnterCS(); |
2000 Kern::Free((TAny*)ids.Ptr()); |
2029 Kern::Free((TAny*)ids.Ptr()); |
2001 NKern::ThreadLeaveCS(); |
2030 NKern::ThreadLeaveCS(); |
2002 return err; |
2031 return err; |
2003 } |
2032 } |
2006 TPtr8 flags(NULL, 0); |
2035 TPtr8 flags(NULL, 0); |
2007 err = AllocAndReadDes(iClientThread, *info.iRegisterFlags, flags, EFalse); |
2036 err = AllocAndReadDes(iClientThread, *info.iRegisterFlags, flags, EFalse); |
2008 if(err != KErrNone) |
2037 if(err != KErrNone) |
2009 { |
2038 { |
2010 if(err == KErrNoMemory) |
2039 if(err == KErrNoMemory) |
2011 { |
2040 { |
2012 NKern::ThreadEnterCS(); |
2041 NKern::ThreadEnterCS(); |
2013 Kern::Free((TAny*)flags.Ptr()); |
2042 Kern::Free((TAny*)flags.Ptr()); |
2014 NKern::ThreadLeaveCS(); |
2043 NKern::ThreadLeaveCS(); |
2015 } |
2044 } |
2016 NKern::ThreadEnterCS(); |
2045 NKern::ThreadEnterCS(); |
2017 Kern::Free((TAny*)ids.Ptr()); |
2046 Kern::Free((TAny*)ids.Ptr()); |
2018 Kern::Free((TAny*)values.Ptr()); |
2047 Kern::Free((TAny*)values.Ptr()); |
2019 NKern::ThreadLeaveCS(); |
2048 NKern::ThreadLeaveCS(); |
2020 return err; |
2049 return err; |
2035 Kern::Free((TAny*)values.Ptr()); |
2064 Kern::Free((TAny*)values.Ptr()); |
2036 Kern::Free((TAny*)flags.Ptr()); |
2065 Kern::Free((TAny*)flags.Ptr()); |
2037 NKern::ThreadLeaveCS(); |
2066 NKern::ThreadLeaveCS(); |
2038 |
2067 |
2039 return err; |
2068 return err; |
2040 } |
2069 } |
2041 |
2070 |
2042 /** |
2071 /** |
2043 @deprecated use DRM_DebugChannel::WriteRegisters(DThread* aThread, TRM_DebugRegisterInformation* aRegisterInfo) instead |
2072 @deprecated use DRM_DebugChannel::WriteRegisters(DThread* aThread, TRM_DebugRegisterInformation* aRegisterInfo) instead |
2044 */ |
2073 */ |
2045 TInt DRM_DebugChannel::WriteRegistersLegacy(DThread* aThread, const TRM_DebugRegisterInfo* aRegisterInfo) |
2074 TInt DRM_DebugChannel::WriteRegistersLegacy(DThread* aThread, const TRM_DebugRegisterInfo* aRegisterInfo) |
2046 { |
2075 { |
2047 LOG_MSG("DRM_DebugChannel::WriteRegistersLegacy()"); |
2076 LOG_MSG("DRM_DebugChannel::WriteRegistersLegacy()"); |
2048 |
2077 |
2049 TInt err = KErrNone; |
2078 TInt err = KErrNone; |
2050 |
2079 |
2051 if (!aRegisterInfo) |
2080 if (!aRegisterInfo) |
2063 |
2092 |
2064 NKern::ThreadEnterCS(); |
2093 NKern::ThreadEnterCS(); |
2065 TUint8 *values = (TUint8*)Kern::Alloc(length); |
2094 TUint8 *values = (TUint8*)Kern::Alloc(length); |
2066 NKern::ThreadLeaveCS(); |
2095 NKern::ThreadLeaveCS(); |
2067 if (!values) |
2096 if (!values) |
2068 { |
2097 { |
2069 return KErrNoMemory; |
2098 return KErrNoMemory; |
2070 } |
2099 } |
2071 |
2100 |
2072 TPtr8 valuesDes(values, length); |
2101 TPtr8 valuesDes(values, length); |
2073 |
2102 |
2074 err = Kern::ThreadDesRead(iClientThread, info.iValues, valuesDes, 0); |
2103 err = Kern::ThreadDesRead(iClientThread, info.iValues, valuesDes, 0); |
2075 if (err == KErrNone) |
2104 if (err == KErrNone) |
2076 { |
2105 { |
2077 err = DoWriteRegisters(aThread, info.iFirstRegister, info.iLastRegister, valuesDes); |
2106 err = DoWriteRegisters(aThread, info.iFirstRegister, info.iLastRegister, valuesDes); |
2078 } |
2107 } |
2079 |
2108 |
2080 NKern::ThreadEnterCS(); |
2109 NKern::ThreadEnterCS(); |
2081 Kern::Free(values); |
2110 Kern::Free(values); |
2082 NKern::ThreadLeaveCS(); |
2111 NKern::ThreadLeaveCS(); |
2083 |
2112 |
2084 return err; |
2113 return err; |
2085 } |
2114 } |
2086 |
2115 |
2087 /** |
2116 /** |
2088 Write registers and store flags data in aRegisterInfo |
2117 Write registers and store flags data in aRegisterInfo |
2089 |
2118 |
2090 @param aThread thread to write registers to |
2119 @param aThread thread to write registers to |
2101 KErrGeneral if there was a problem initialising the register set, |
2130 KErrGeneral if there was a problem initialising the register set, |
2102 KErrNoMemory if there is insufficient memory, |
2131 KErrNoMemory if there is insufficient memory, |
2103 KErrDied, if the thread with thread ID aThreadId is dead |
2132 KErrDied, if the thread with thread ID aThreadId is dead |
2104 */ |
2133 */ |
2105 TInt DRM_DebugChannel::WriteRegisters(DThread* aThread, TRM_DebugRegisterInformation* aRegisterInfo) const |
2134 TInt DRM_DebugChannel::WriteRegisters(DThread* aThread, TRM_DebugRegisterInformation* aRegisterInfo) const |
2106 { |
2135 { |
2107 LOG_MSG("DRM_DebugChannel::WriteRegisters()"); |
2136 LOG_MSG("DRM_DebugChannel::WriteRegisters()"); |
2108 |
2137 |
2109 TInt err = KErrNone; |
2138 TInt err = KErrNone; |
2110 |
2139 |
2111 if (!aRegisterInfo) |
2140 if (!aRegisterInfo) |
2179 Kern::Free((TAny*)values.Ptr()); |
2208 Kern::Free((TAny*)values.Ptr()); |
2180 Kern::Free((TAny*)flags.Ptr()); |
2209 Kern::Free((TAny*)flags.Ptr()); |
2181 NKern::ThreadLeaveCS(); |
2210 NKern::ThreadLeaveCS(); |
2182 |
2211 |
2183 return err; |
2212 return err; |
2184 } |
2213 } |
2185 |
2214 |
2186 /** |
2215 /** |
2187 Suspends execution of the specified thread. |
2216 Suspends execution of the specified thread. |
2188 |
2217 |
2189 @param aThread thread to resume |
2218 @param aThread thread to resume |
2237 { |
2266 { |
2238 return DoStepRange(aThread, currentPC, currentPC+1, ETrue, 1, ETrue); |
2267 return DoStepRange(aThread, currentPC, currentPC+1, ETrue, 1, ETrue); |
2239 } |
2268 } |
2240 } |
2269 } |
2241 } while(breakEntry); |
2270 } while(breakEntry); |
2271 |
|
2242 return TheDProcessTracker.ResumeThread(aThread); |
2272 return TheDProcessTracker.ResumeThread(aThread); |
2243 } |
2273 } |
2244 |
2274 |
2245 // |
2275 // |
2246 // DRM_DebugChannel::DoStepRange |
2276 // DRM_DebugChannel::DoStepRange |
2247 // |
2277 // |
2248 TInt DRM_DebugChannel::DoStepRange(DThread *aThread, const TUint32 aStartAddress, const TUint32 aStopAddress, TBool aStepInto, TBool aResumeOnceOutOfRange, const TUint32 aNumSteps, TBool aUserRequest) |
2278 TInt DRM_DebugChannel::DoStepRange(DThread *aThread, const TUint32 aStartAddress, const TUint32 aStopAddress, TBool aStepInto, TBool aResumeOnceOutOfRange, const TUint32 aNumSteps, TBool aUserRequest) |
2249 { |
2279 { |
2250 LOG_MSG("DRM_DebugChannel::DoStepRange()"); |
2280 LOG_MSG("DRM_DebugChannel::DoStepRange()"); |
2251 |
2281 |
2252 if (!aThread) |
2282 if (!aThread) |
2253 return KErrArgument; |
2283 return KErrArgument; |
2254 |
2284 |
2283 ReturnIfError(iStepper->ModifyBreaksForStep(aThread, startAddress, stopAddress, aResumeOnceOutOfRange, aUserRequest, aNumSteps)); |
2313 ReturnIfError(iStepper->ModifyBreaksForStep(aThread, startAddress, stopAddress, aResumeOnceOutOfRange, aUserRequest, aNumSteps)); |
2284 |
2314 |
2285 LOG_MSG("DRM_DebugChannel::DoStepRange() - resuming thread\n"); |
2315 LOG_MSG("DRM_DebugChannel::DoStepRange() - resuming thread\n"); |
2286 |
2316 |
2287 return TheDProcessTracker.ResumeThread(aThread); |
2317 return TheDProcessTracker.ResumeThread(aThread); |
2288 } |
2318 } |
2289 |
2319 |
2290 /** |
2320 /** |
2291 Read memory from the specified addres into the aData descriptor. If there is a |
2321 Read memory from the specified addres into the aData descriptor. If there is a |
2292 breakpoint set in the region of memory returned then the correct data value is |
2322 breakpoint set in the region of memory returned then the correct data value is |
2293 inserted into the descriptor |
2323 inserted into the descriptor |
2380 return KErrArgument; |
2410 return KErrArgument; |
2381 |
2411 |
2382 TInt err = KErrNone; |
2412 TInt err = KErrNone; |
2383 |
2413 |
2384 // trap exceptions in case the address is invalid |
2414 // trap exceptions in case the address is invalid |
2385 XTRAPD(r, XT_DEFAULT, err = TryToWriteMemory(aThread, (TAny *)aAddress, (TAny *)aData.Ptr(), aLength)); |
2415 XTRAPD(r, XT_DEFAULT, err = TryToWriteMemory(aThread, (TAny *)aAddress, (TAny *)aData.Ptr(), aLength)); |
2386 |
2416 |
2387 err = (KErrNone == r) ? err : r; |
2417 err = (KErrNone == r) ? err : r; |
2388 |
2418 |
2389 // reset any breakpoints we may have just overwritten |
2419 // reset any breakpoints we may have just overwritten |
2390 if (KErrNone == err) |
2420 if (KErrNone == err) |
2434 |
2464 |
2435 // |
2465 // |
2436 // DRM_DebugChannel::DoReadRegisters |
2466 // DRM_DebugChannel::DoReadRegisters |
2437 // |
2467 // |
2438 TInt DRM_DebugChannel::DoReadRegisters(DThread *aThread, const TInt16 aFirstRegister, const TInt16 aLastRegister, TDes8 &aValues) |
2468 TInt DRM_DebugChannel::DoReadRegisters(DThread *aThread, const TInt16 aFirstRegister, const TInt16 aLastRegister, TDes8 &aValues) |
2439 { |
2469 { |
2440 LOG_MSG("DRM_DebugChannel::DoReadRegisters()"); |
2470 LOG_EVENT_MSG("DRM_DebugChannel::DoReadRegisters()"); |
2441 |
2471 |
2442 // make sure the parameters are valid |
2472 // make sure the parameters are valid |
2443 if (!aThread || (aFirstRegister < 0) || (aLastRegister >= (TInt16)(sizeof(TArmRegSet)/sizeof(TArmReg)))) |
2473 if (!aThread || (aFirstRegister < 0) || (aLastRegister >= (TInt16)(sizeof(TArmRegSet)/sizeof(TArmReg)))) |
2444 return KErrArgument; |
2474 return KErrArgument; |
2445 |
2475 |
2446 // make sure the descriptor is big enough to hold the requested data |
2476 // make sure the descriptor is big enough to hold the requested data |
2447 if ((TInt)((aLastRegister - aFirstRegister + 1) * sizeof(TArmReg)) > (aValues.MaxSize())) |
2477 if ((TInt)((aLastRegister - aFirstRegister + 1) * sizeof(TArmReg)) > (aValues.MaxSize())) |
2448 return KErrArgument; |
2478 return KErrArgument; |
2449 |
2479 |
2450 TArmRegSet regSet; |
2480 TArmRegSet regSet; |
2451 TUint32 unused; |
2481 TUint32 unused; |
2452 |
2482 |
2453 NKern::ThreadGetUserContext(&aThread->iNThread, ®Set, unused); |
2483 NKern::ThreadGetUserContext(&aThread->iNThread, ®Set, unused); |
2454 |
2484 |
2455 LOG_MSG2( "DRM_DebugChannel::DoReadRegistersLegacy() : unused = 0x%X\n", unused ); |
2485 LOG_MSG2( "DRM_DebugChannel::DoReadRegistersLegacy() : unused = 0x%X\n", unused ); |
2456 |
2486 |
2457 TArmReg *reg = ®Set.iR0; |
2487 TArmReg *reg = ®Set.iR0; |
2458 |
2488 |
2459 if (!reg) |
2489 if (!reg) |
2460 return KErrGeneral; |
2490 return KErrGeneral; |
2461 |
2491 |
2462 for (TInt16 i = aFirstRegister; i <= aLastRegister; i++) |
2492 for (TInt16 i = aFirstRegister; i <= aLastRegister; i++) |
2463 aValues.Append((TUint8 *)®[i], sizeof(TArmReg)); |
2493 aValues.Append((TUint8 *)®[i], sizeof(TArmReg)); |
2464 |
2494 |
2465 return KErrNone; |
2495 return KErrNone; |
2466 } |
2496 } |
2467 |
2497 |
2468 /** |
2498 /** |
2508 KErrArgument if aThread is NULL, if an unknown register is specified in |
2538 KErrArgument if aThread is NULL, if an unknown register is specified in |
2509 aRegisterValues or if aRegisterValues is too small |
2539 aRegisterValues or if aRegisterValues is too small |
2510 KErrGeneral if there was a problem initialising the register set |
2540 KErrGeneral if there was a problem initialising the register set |
2511 */ |
2541 */ |
2512 TInt DRM_DebugChannel::DoReadRegisters(DThread *aThread, const TDesC8 &aRegisterIds, TDes8 &aRegisterValues, TDes8& aRegisterFlags) const |
2542 TInt DRM_DebugChannel::DoReadRegisters(DThread *aThread, const TDesC8 &aRegisterIds, TDes8 &aRegisterValues, TDes8& aRegisterFlags) const |
2513 { |
2543 { |
2514 LOG_MSG("DRM_DebugChannel::DoReadRegisters()"); |
2544 LOG_MSG("DRM_DebugChannel::DoReadRegisters()"); |
2515 |
2545 |
2516 // make sure the parameters are valid |
2546 // make sure the parameters are valid |
2517 if (!aThread) |
2547 if (!aThread) |
2518 return KErrArgument; |
2548 return KErrArgument; |
2611 aRegisterValues.SetLength(aRegisterValues.Length() + registerTag.iSize); |
2641 aRegisterValues.SetLength(aRegisterValues.Length() + registerTag.iSize); |
2612 } |
2642 } |
2613 } |
2643 } |
2614 } |
2644 } |
2615 return KErrNone; |
2645 return KErrNone; |
2616 } |
2646 } |
2617 |
2647 |
2618 // |
2648 // |
2619 // DRM_DebugChannel::DoWriteRegisters |
2649 // DRM_DebugChannel::DoWriteRegisters |
2620 // |
2650 // |
2621 TInt DRM_DebugChannel::DoWriteRegisters(DThread *aThread, const TInt16 aFirstRegister, const TInt16 aLastRegister, TDesC8 &aValues) |
2651 TInt DRM_DebugChannel::DoWriteRegisters(DThread *aThread, const TInt16 aFirstRegister, const TInt16 aLastRegister, TDesC8 &aValues) |
2622 { |
2652 { |
2623 LOG_MSG("DRM_DebugChannel::DoWriteRegisters()"); |
2653 LOG_MSG("DRM_DebugChannel::DoWriteRegisters()"); |
2624 |
2654 |
2625 // make sure the parameters are valid |
2655 // make sure the parameters are valid |
2626 if (!aThread || (aFirstRegister < 0) || (aLastRegister >= (TInt16)(sizeof(TArmRegSet)/sizeof(TArmReg)))) |
2656 if (!aThread || (aFirstRegister < 0) || (aLastRegister >= (TInt16)(sizeof(TArmRegSet)/sizeof(TArmReg)))) |
2627 return KErrArgument; |
2657 return KErrArgument; |
2641 reg[i] = *(TUint32 *)&aValues[(i-aFirstRegister)*sizeof(TArmReg)]; |
2671 reg[i] = *(TUint32 *)&aValues[(i-aFirstRegister)*sizeof(TArmReg)]; |
2642 |
2672 |
2643 NKern::ThreadSetUserContext(&aThread->iNThread, ®Set); |
2673 NKern::ThreadSetUserContext(&aThread->iNThread, ®Set); |
2644 |
2674 |
2645 return KErrNone; |
2675 return KErrNone; |
2646 } |
2676 } |
2647 |
2677 |
2648 /** |
2678 /** |
2649 Write registers and store flags indicating which registers could be read in |
2679 Write registers and store flags indicating which registers could be read in |
2650 aRegisterFlags |
2680 aRegisterFlags |
2651 |
2681 |
2660 KErrArgument if aThread is NULL, if the buffer passed in as |
2690 KErrArgument if aThread is NULL, if the buffer passed in as |
2661 aRegisterValue is too small, or if an unknown register is requested, |
2691 aRegisterValue is too small, or if an unknown register is requested, |
2662 KErrGeneral if there was a problem initialising the register set |
2692 KErrGeneral if there was a problem initialising the register set |
2663 */ |
2693 */ |
2664 TInt DRM_DebugChannel::DoWriteRegisters(DThread *aThread, const TDesC8 &aRegisterIds, TDesC8 &aRegisterValues, TDes8 &aRegisterFlags) const |
2694 TInt DRM_DebugChannel::DoWriteRegisters(DThread *aThread, const TDesC8 &aRegisterIds, TDesC8 &aRegisterValues, TDes8 &aRegisterFlags) const |
2665 { |
2695 { |
2666 LOG_MSG("DRM_DebugChannel::DoWriteRegisters()"); |
2696 LOG_MSG("DRM_DebugChannel::DoWriteRegisters()"); |
2667 |
2697 |
2668 // make sure the parameters are valid |
2698 // make sure the parameters are valid |
2669 if (!aThread) |
2699 if (!aThread) |
2670 return KErrArgument; |
2700 return KErrArgument; |
2763 |
2793 |
2764 // |
2794 // |
2765 // DRM_DebugChannel::DoSecurityCheck |
2795 // DRM_DebugChannel::DoSecurityCheck |
2766 // |
2796 // |
2767 TBool DRM_DebugChannel::DoSecurityCheck() |
2797 TBool DRM_DebugChannel::DoSecurityCheck() |
2768 { |
2798 { |
2769 LOG_MSG("DRM_DebugChannel::DoSecurityCheck"); |
2799 LOG_MSG("DRM_DebugChannel::DoSecurityCheck"); |
2770 DProcess* clientProcess = iClientThread->iOwningProcess; |
2800 DProcess* clientProcess = iClientThread->iOwningProcess; |
2771 if (clientProcess) |
2801 if (clientProcess) |
2772 { |
2802 { |
2773 SSecurityInfo secureInfo = clientProcess->iS; |
2803 SSecurityInfo secureInfo = clientProcess->iS; |
2774 |
2804 |
2775 LOG_MSG2("DoSecurityCheck - client secure id is 0x%08x",secureInfo.iSecureId); |
2805 LOG_MSG2("DoSecurityCheck - client secure id is 0x%08x",secureInfo.iSecureId); |
2776 |
2806 |
2777 // Ensure we really are communicating with the Debug Security Server |
2807 // Ensure we really are communicating with the Debug Security Server |
2778 if (secureInfo.iSecureId == KUidDebugSecurityServer.iUid ) |
2808 if (secureInfo.iSecureId == KUidDebugSecurityServer.iUid ) |
2779 { |
2809 { |
2780 return ETrue; |
2810 return ETrue; |
2781 } |
2811 } |
2782 } |
2812 } |
2783 return EFalse; |
2813 return EFalse; |
2784 } |
2814 } |
2785 |
2815 |
2786 /** |
2816 /** |
2787 Attempt to read memory from aThread's address space |
2817 Attempt to read memory from aThread's address space |
2788 |
2818 |
2789 @param aThread thread from whose address space memory is to be read |
2819 @param aThread thread from whose address space memory is to be read |
2793 |
2823 |
2794 @return KErrNone if memory read successfully, |
2824 @return KErrNone if memory read successfully, |
2795 or another of the system wide error codes |
2825 or another of the system wide error codes |
2796 */ |
2826 */ |
2797 TInt DRM_DebugChannel::TryToReadMemory(const DThread *aThread, const TAny *aSrc, TAny *aDest, const TUint32 aLength) const |
2827 TInt DRM_DebugChannel::TryToReadMemory(const DThread *aThread, const TAny *aSrc, TAny *aDest, const TUint32 aLength) const |
2798 { |
2828 { |
2799 LOG_MSG("DRM_DebugChannel::TryToReadMemory()"); |
2829 LOG_MSG("DRM_DebugChannel::TryToReadMemory()"); |
2800 |
2830 |
2801 // make sure the parameters are valid |
2831 // make sure the parameters are valid |
2802 if (!aThread) |
2832 if (!aThread) |
2803 return KErrArgument; |
2833 return KErrArgument; |
2812 } |
2842 } |
2813 #endif |
2843 #endif |
2814 |
2844 |
2815 LOG_MSG2("Using Kern::ThreadRawRead to read memory at address %x", aSrc); |
2845 LOG_MSG2("Using Kern::ThreadRawRead to read memory at address %x", aSrc); |
2816 return Kern::ThreadRawRead((DThread *)aThread, aSrc, aDest, aLength); |
2846 return Kern::ThreadRawRead((DThread *)aThread, aSrc, aDest, aLength); |
2817 } |
2847 } |
2818 |
2848 |
2819 /** |
2849 /** |
2820 Attempt to write memory to aThread's address space |
2850 Attempt to write memory to aThread's address space |
2821 |
2851 |
2822 @param aThread thread to whose address space memory is to be written |
2852 @param aThread thread to whose address space memory is to be written |
2826 |
2856 |
2827 @return KErrNone if memory written successfully, or another of the system wide |
2857 @return KErrNone if memory written successfully, or another of the system wide |
2828 error codes |
2858 error codes |
2829 */ |
2859 */ |
2830 TInt DRM_DebugChannel::TryToWriteMemory(const DThread *aThread, TAny *aDest, const TAny *aSrc, const TUint32 aLength) |
2860 TInt DRM_DebugChannel::TryToWriteMemory(const DThread *aThread, TAny *aDest, const TAny *aSrc, const TUint32 aLength) |
2831 { |
2861 { |
2832 LOG_MSG("DRM_DebugChannel::TryToWriteMemory()"); |
2862 LOG_MSG("DRM_DebugChannel::TryToWriteMemory()"); |
2833 |
2863 |
2834 //check that the thread is suspended before writing the memory |
2864 //check that the thread is suspended before writing the memory |
2835 if(!TheDProcessTracker.CheckSuspended((DThread*)aThread)) |
2865 if(!TheDProcessTracker.CheckSuspended((DThread*)aThread)) |
2836 { |
2866 { |
2838 return KErrInUse; |
2868 return KErrInUse; |
2839 } |
2869 } |
2840 |
2870 |
2841 LOG_MSG2("Using Kern::ThreadRawWrite to write memory at address %x", (TUint32)aDest); |
2871 LOG_MSG2("Using Kern::ThreadRawWrite to write memory at address %x", (TUint32)aDest); |
2842 return Kern::ThreadRawWrite((DThread *)aThread, aDest, aSrc, aLength, iClientThread); |
2872 return Kern::ThreadRawWrite((DThread *)aThread, aDest, aSrc, aLength, iClientThread); |
2843 } |
2873 } |
2844 |
2874 |
2845 /** |
2875 /** |
2846 @deprecated use DRM_DebugChannel::ReadKernelRegisterValue(DThread *aThread, const TArmReg aKernelRegisterId, T4ByteRegisterValue &aValue) instead |
2876 @deprecated use DRM_DebugChannel::ReadKernelRegisterValue(DThread *aThread, const TArmReg aKernelRegisterId, T4ByteRegisterValue &aValue) instead |
2847 */ |
2877 */ |
2848 TInt32 DRM_DebugChannel::ReadRegister(DThread *aThread, TInt aNum) |
2878 TInt32 DRM_DebugChannel::ReadRegister(DThread *aThread, TInt aNum) |
2849 { |
2879 { |
2850 LOG_MSG("DRM_DebugChannel::ReadRegister()"); |
2880 LOG_MSG("DRM_DebugChannel::ReadRegister()"); |
2851 |
2881 |
2852 if (!aThread || (aNum < 0) || (aNum >= (TInt16)(sizeof(TArmRegSet)/sizeof(TArmReg)))) |
2882 if (!aThread || (aNum < 0) || (aNum >= (TInt16)(sizeof(TArmRegSet)/sizeof(TArmReg)))) |
2853 { |
2883 { |
2854 LOG_MSG2("Invalid register number (%d) passed to ReadRegister", aNum); |
2884 LOG_MSG2("Invalid register number (%d) passed to ReadRegister", aNum); |
2855 return 0; |
2885 return 0; |
2856 } |
2886 } |
2857 |
2887 |
2858 TArmRegSet regSet; |
2888 TArmRegSet regSet; |
2859 TUint32 unused; |
2889 TUint32 unused; |
2860 |
2890 |
2861 NKern::ThreadGetUserContext(&aThread->iNThread, ®Set, unused); |
2891 NKern::ThreadGetUserContext(&aThread->iNThread, ®Set, unused); |
2862 |
2892 |
2863 TArmReg *reg = ®Set.iR0; |
2893 TArmReg *reg = ®Set.iR0; |
2864 |
2894 |
2865 return ((TUint32 *)reg)[aNum]; |
2895 return ((TUint32 *)reg)[aNum]; |
2866 } |
2896 } |
2867 |
2897 |
2868 /** |
2898 /** |
2869 Given a TArmReg register ID, read the value of the register. The register value |
2899 Given a TArmReg register ID, read the value of the register. The register value |
2870 will be stored in aValue if the register could be read. |
2900 will be stored in aValue if the register could be read. |
2871 |
2901 |
2877 KErrNotSupported if aKernelRegister is not supported by the debug |
2907 KErrNotSupported if aKernelRegister is not supported by the debug |
2878 security server, |
2908 security server, |
2879 or a return value from DRM_DebugChannel::ReadDebugRegisterValue() |
2909 or a return value from DRM_DebugChannel::ReadDebugRegisterValue() |
2880 */ |
2910 */ |
2881 TInt32 DRM_DebugChannel::ReadKernelRegisterValue(DThread *aThread, const TArmReg aKernelRegisterId, T4ByteRegisterValue &aValue) const |
2911 TInt32 DRM_DebugChannel::ReadKernelRegisterValue(DThread *aThread, const TArmReg aKernelRegisterId, T4ByteRegisterValue &aValue) const |
2882 { |
2912 { |
2883 //get register ID as a TRegisterInfo ID |
2913 //get register ID as a TRegisterInfo ID |
2884 TRegisterInfo regId; |
2914 TRegisterInfo regId; |
2885 TInt err = GetDebugRegisterId(aKernelRegisterId, regId); |
2915 TInt err = GetDebugRegisterId(aKernelRegisterId, regId); |
2886 if(err != KErrNone) |
2916 if(err != KErrNone) |
2887 return err; |
2917 return err; |
2904 TRegisterFlag::ENotSupported if the register is not supported, |
2934 TRegisterFlag::ENotSupported if the register is not supported, |
2905 KErrNoMemory if temporary memory could not be allocated, |
2935 KErrNoMemory if temporary memory could not be allocated, |
2906 or a return value from DRM_DebugChannel::DoReadRegisters |
2936 or a return value from DRM_DebugChannel::DoReadRegisters |
2907 */ |
2937 */ |
2908 TInt32 DRM_DebugChannel::ReadDebugRegisterValue(DThread *aThread, const TRegisterInfo aDebugRegisterId, T4ByteRegisterValue &aValue) const |
2938 TInt32 DRM_DebugChannel::ReadDebugRegisterValue(DThread *aThread, const TRegisterInfo aDebugRegisterId, T4ByteRegisterValue &aValue) const |
2909 { |
2939 { |
2910 //allocate temporary buffers to store data |
2940 //allocate temporary buffers to store data |
2911 NKern::ThreadEnterCS(); |
2941 NKern::ThreadEnterCS(); |
2912 TUint8* id = (TUint8*)Kern::Alloc(sizeof(TRegisterInfo)); |
2942 TUint8* id = (TUint8*)Kern::Alloc(sizeof(TRegisterInfo)); |
2913 NKern::ThreadLeaveCS(); |
2943 NKern::ThreadLeaveCS(); |
2914 if(id == NULL) |
2944 if(id == NULL) |
2915 { |
2945 { |
2916 return KErrNoMemory; |
2946 return KErrNoMemory; |
2917 } |
2947 } |
2948 |
|
2918 TPtr8 idPtr(id, sizeof(TRegisterInfo)); |
2949 TPtr8 idPtr(id, sizeof(TRegisterInfo)); |
2919 |
2950 |
2920 NKern::ThreadEnterCS(); |
2951 NKern::ThreadEnterCS(); |
2921 TUint8* value = (TUint8*)Kern::Alloc(sizeof(T4ByteRegisterValue)); |
2952 TUint8* value = (TUint8*)Kern::Alloc(sizeof(T4ByteRegisterValue)); |
2922 NKern::ThreadLeaveCS(); |
2953 NKern::ThreadLeaveCS(); |
2923 if(value == NULL) |
2954 if(value == NULL) |
2924 { |
2955 { |
2925 return KErrNoMemory; |
2956 return KErrNoMemory; |
2926 } |
2957 } |
2927 TPtr8 valuePtr(value, sizeof(T4ByteRegisterValue)); |
2958 TPtr8 valuePtr(value, sizeof(T4ByteRegisterValue)); |
2928 |
2959 |
2929 NKern::ThreadEnterCS(); |
2960 NKern::ThreadEnterCS(); |
2930 TUint8* flag = (TUint8*)Kern::Alloc(sizeof(TUint8)); |
2961 TUint8* flag = (TUint8*)Kern::Alloc(sizeof(TUint8)); |
2931 NKern::ThreadLeaveCS(); |
2962 NKern::ThreadLeaveCS(); |
2932 if(flag == NULL) |
2963 if(flag == NULL) |
2933 { |
2964 { |
2934 return KErrNoMemory; |
2965 return KErrNoMemory; |
2935 } |
2966 } |
2936 TPtr8 flagPtr(flag, sizeof(TUint8)); |
2967 TPtr8 flagPtr(flag, sizeof(TUint8)); |
2937 |
2968 |
2938 //store register id in buffer |
2969 //store register id in buffer |
2939 idPtr.Append((TUint8*)&aDebugRegisterId, sizeof(TRegisterInfo)); |
2970 idPtr.Append((TUint8*)&aDebugRegisterId, sizeof(TRegisterInfo)); |
2940 |
2971 |
2941 //read registers |
2972 //read registers |
2942 TInt err = DoReadRegisters(aThread, idPtr, valuePtr, flagPtr); |
2973 TInt err = DoReadRegisters(aThread, idPtr, valuePtr, flagPtr); |
2943 if(err == KErrNone) |
2974 if(err == KErrNone) |
2944 { |
2975 { |
2945 if(*flag == EValid) |
2976 if(*flag == EValid) |
2946 { |
2977 { |
2947 //register could be read so store value |
2978 //register could be read so store value |
2948 aValue = *(T4ByteRegisterValue*)value; |
2979 aValue = *(T4ByteRegisterValue*)value; |
2949 } |
2980 } |
2950 else |
2981 else |
2951 { |
2982 { |
2952 //register couldn't be read for some reason |
2983 //register couldn't be read for some reason |
2953 err = *flag; |
2984 err = *flag; |
2954 } |
2985 } |
2955 } |
2986 } |
2956 |
2987 |
2957 //free memory |
2988 //free memory |
2958 NKern::ThreadEnterCS(); |
2989 NKern::ThreadEnterCS(); |
2959 Kern::Free(id); |
2990 Kern::Free(id); |
2960 Kern::Free(value); |
2991 Kern::Free(value); |
2961 Kern::Free(flag); |
2992 Kern::Free(flag); |
2962 NKern::ThreadLeaveCS(); |
2993 NKern::ThreadLeaveCS(); |
2963 |
2994 |
2964 return err; |
2995 return err; |
2965 } |
2996 } |
2966 |
2997 |
2967 // |
2998 // |
2968 // DRM_DebugChannel::NotifyEvent |
2999 // DRM_DebugChannel::NotifyEvent |
2969 // |
3000 // |
2970 void DRM_DebugChannel::NotifyEvent(const TDriverEventInfo& aEventInfo) |
3001 void DRM_DebugChannel::NotifyEvent(const TDriverEventInfo& aEventInfo) |
2971 { |
3002 { |
2972 LOG_EVENT_MSG("DRM_DebugChannel::NotifyEvent()"); |
3003 LOG_EVENT_MSG("DRM_DebugChannel::NotifyEvent()"); |
2973 |
3004 |
2974 // Look for the relevant DTargetProcess |
3005 // Look for the relevant DTargetProcess |
2975 // We can find out the relevant process id from aEventInfo |
3006 // We can find out the relevant process id from aEventInfo |
2976 TUint32 pid = aEventInfo.iProcessId; |
3007 TUint32 pid = aEventInfo.iProcessId; |
3014 LOG_EVENT_MSG("DRM_DebugChannel::NotifyEvent - we are not debugging this process!"); |
3045 LOG_EVENT_MSG("DRM_DebugChannel::NotifyEvent - we are not debugging this process!"); |
3015 return; |
3046 return; |
3016 } |
3047 } |
3017 |
3048 |
3018 foundProcess->NotifyEvent(aEventInfo); |
3049 foundProcess->NotifyEvent(aEventInfo); |
3019 } |
3050 } |
3020 |
3051 |
3021 #ifndef __LAUNCH_AS_EXTENSION__ |
3052 #ifndef __LAUNCH_AS_EXTENSION__ |
3022 DECLARE_STANDARD_LDD() |
3053 DECLARE_STANDARD_LDD() |
3023 { |
3054 { |
3024 return new DRM_DebugDriverFactory; |
3055 return new DRM_DebugDriverFactory; |
3110 * stop mode api, kdebug, is not in place. It will initialise all values to NULL except |
3141 * stop mode api, kdebug, is not in place. It will initialise all values to NULL except |
3111 * the pointer to the new stop mode api extension. This allows the new stop mode solution |
3142 * the pointer to the new stop mode api extension. This allows the new stop mode solution |
3112 * to both co-exist and exist independantly of the existing one * |
3143 * to both co-exist and exist independantly of the existing one * |
3113 */ |
3144 */ |
3114 DDebuggerInfo::DDebuggerInfo(): |
3145 DDebuggerInfo::DDebuggerInfo(): |
3115 iObjectOffsetTable(NULL), |
3146 iObjectOffsetTable(NULL), |
3116 iObjectOffsetTableCount(NULL), |
3147 iObjectOffsetTableCount(NULL), |
3117 iThreadContextTable(NULL), |
3148 iThreadContextTable(NULL), |
3118 iStopModeExtension(new DStopModeExtension()), |
3149 iStopModeExtension(new DStopModeExtension()), |
3119 iContainers(NULL), |
3150 iContainers(NULL), |
3120 iCodeSegLock(NULL), |
3151 iCodeSegLock(NULL), |
3121 iCodeSegGlobalList(NULL), |
3152 iCodeSegGlobalList(NULL), |
3122 iScheduler(NULL), |
3153 iScheduler(NULL), |
3123 iShadowPages(NULL), |
3154 iShadowPages(NULL), |
3124 iShadowPageCount(0), |
3155 iShadowPageCount(0), |
3125 iCurrentThread(NULL), |
3156 iCurrentThread(NULL), |
3126 iEventMask(), |
3157 iEventMask(), |
3127 iEventHandlerBreakpoint(0), |
3158 iEventHandlerBreakpoint(0), |
3128 iMemModelObjectOffsetTable(NULL), |
3159 iMemModelObjectOffsetTable(NULL), |
3129 iMemModelObjectOffsetTableCount(0) |
3160 iMemModelObjectOffsetTableCount(0) |
3130 { |
3161 { |
3131 } |
3162 } |
3132 |
3163 |
3133 /** |
3164 /** |
3134 * Installs the stop-mode debugger extension |
3165 * Installs the stop-mode debugger extension |
3135 * Make the stop-mode API visible to a JTAG debugger, by publishing its |
3166 * Make the stop-mode API visible to a JTAG debugger, by publishing its |
3136 * existence in the superpage |
3167 * existence in the superpage |
3137 */ |
3168 */ |
3138 void DStopModeExtension::Install(DStopModeExtension* aExt) |
3169 void DStopModeExtension::Install(DStopModeExtension* aExt) |
3139 { |
3170 { |
3140 Kern::SuperPage().iDebuggerInfo->iStopModeExtension = aExt; |
3171 Kern::SuperPage().iDebuggerInfo->iStopModeExtension = aExt; |
3141 } |
3172 } |
3142 |
3173 |
3143 #endif |
3174 #endif |
3144 |
3175 |
3145 /** |
3176 /** |
3146 Helper function |
3177 Helper function |
3340 |
3371 |
3341 @return ETrue if bit is set, EFalse if not |
3372 @return ETrue if bit is set, EFalse if not |
3342 */ |
3373 */ |
3343 TBool DRM_DebugChannel::GetFlagAtOffset(const TUint32 aFlags, const TArmReg aIndex) const |
3374 TBool DRM_DebugChannel::GetFlagAtOffset(const TUint32 aFlags, const TArmReg aIndex) const |
3344 { |
3375 { |
3345 return ( aFlags & (1<<aIndex) ) ? ETrue : EFalse; |
3376 return aFlags & (1<<aIndex); |
3346 } |
3377 } |
3347 |
3378 |
3348 /* Register the attachment of a debug agent to a process to be debugged |
3379 /* Register the attachment of a debug agent to a process to be debugged |
3349 * |
3380 * |
3350 * @param a1 - TDes8 target process name |
3381 * @param a1 - TDes8 target process name |
3473 // Allocate space to store the target process name in a kernel-side TPtr8 |
3504 // Allocate space to store the target process name in a kernel-side TPtr8 |
3474 NKern::ThreadEnterCS(); |
3505 NKern::ThreadEnterCS(); |
3475 TUint8* buffer = (TUint8*)Kern::AllocZ(length); |
3506 TUint8* buffer = (TUint8*)Kern::AllocZ(length); |
3476 NKern::ThreadLeaveCS(); |
3507 NKern::ThreadLeaveCS(); |
3477 if (buffer==NULL) |
3508 if (buffer==NULL) |
3478 { |
3509 { |
3479 // Out of memory |
3510 // Out of memory |
3480 return KErrNoMemory; |
3511 return KErrNoMemory; |
3481 } |
3512 } |
3482 |
3513 |
3483 TPtr8 targetProcessName(buffer,length,length); |
3514 TPtr8 targetProcessName(buffer,length,length); |
3484 |
3515 |
3485 // Read the user-side data into targetProcessName |
3516 // Read the user-side data into targetProcessName |
3486 err = Kern::ThreadDesRead(iClientThread,a1,targetProcessName,0,KChunkShiftBy0); |
3517 err = Kern::ThreadDesRead(iClientThread,a1,targetProcessName,0,KChunkShiftBy0); |
3487 if (err != KErrNone) |
3518 if (err != KErrNone) |
3488 { |
3519 { |
3489 // Something bad happened so free the memory and return |
3520 // Something bad happened so free the memory and return |
3490 NKern::ThreadEnterCS(); |
3521 NKern::ThreadEnterCS(); |
3491 Kern::Free(buffer); |
3522 Kern::Free(buffer); |
3492 NKern::ThreadLeaveCS(); |
3523 NKern::ThreadLeaveCS(); |
3493 |
3524 |
3494 return err; |
3525 return err; |
3495 } |
3526 } |
3496 |
3527 |
3497 // Obtain the AgentId |
3528 // Obtain the AgentId |
3498 TUint64 debugAgentId = 0; |
3529 TUint64 debugAgentId = 0; |
3499 |
3530 |
3500 err = Kern::ThreadRawRead(iClientThread,a2,&debugAgentId,sizeof(debugAgentId)); |
3531 err = Kern::ThreadRawRead(iClientThread,a2,&debugAgentId,sizeof(debugAgentId)); |
3501 if (err != KErrNone) |
3532 if (err != KErrNone) |
3502 { |
3533 { |
3503 // Something bad happened so free the memory and return |
3534 // Something bad happened so free the memory and return |
3504 NKern::ThreadEnterCS(); |
3535 NKern::ThreadEnterCS(); |
3505 Kern::Free(buffer); |
3536 Kern::Free(buffer); |
3506 NKern::ThreadLeaveCS(); |
3537 NKern::ThreadLeaveCS(); |
3507 |
3538 |
3508 return err; |
3539 return err; |
3509 } |
3540 } |
3510 |
3541 |
3511 // Remove the process from our list of tracked processes |
3542 // Remove the process from our list of tracked processes |
3512 err = TheDProcessTracker.DetachProcess(targetProcessName, debugAgentId); |
3543 err = TheDProcessTracker.DetachProcess(targetProcessName, debugAgentId); |
3513 |
3544 |
3514 // Free the kernel-side memory containing targetProcessName data |
3545 // Free the kernel-side memory containing targetProcessName data |
3529 // Obtain the AgentId |
3560 // Obtain the AgentId |
3530 TUint64 debugAgentId = 0; |
3561 TUint64 debugAgentId = 0; |
3531 |
3562 |
3532 TInt err = Kern::ThreadRawRead(iClientThread,a1,&debugAgentId,sizeof(debugAgentId)); |
3563 TInt err = Kern::ThreadRawRead(iClientThread,a1,&debugAgentId,sizeof(debugAgentId)); |
3533 if (err != KErrNone) |
3564 if (err != KErrNone) |
3534 { |
3565 { |
3535 return err; |
3566 return err; |
3536 } |
3567 } |
3537 |
3568 |
3538 // Remove the process from our list of tracked processes |
3569 // Remove the process from our list of tracked processes |
3539 return TheDProcessTracker.DetachAgent(debugAgentId); |
3570 return TheDProcessTracker.DetachAgent(debugAgentId); |
3540 } |
3571 } |
3541 |
3572 |
3576 // Allocate space to store the target process name in a kernelspace TPtr8 |
3607 // Allocate space to store the target process name in a kernelspace TPtr8 |
3577 NKern::ThreadEnterCS(); |
3608 NKern::ThreadEnterCS(); |
3578 TUint8* buffer = (TUint8*)Kern::AllocZ(length); |
3609 TUint8* buffer = (TUint8*)Kern::AllocZ(length); |
3579 NKern::ThreadLeaveCS(); |
3610 NKern::ThreadLeaveCS(); |
3580 if (buffer==NULL) |
3611 if (buffer==NULL) |
3581 { |
3612 { |
3582 // Out of memory |
3613 // Out of memory |
3583 return KErrNoMemory; |
3614 return KErrNoMemory; |
3584 } |
3615 } |
3585 TPtr8 targetProcessName(buffer,length,length); |
3616 TPtr8 targetProcessName(buffer,length,length); |
3586 |
3617 |
3587 // Read the user-side data into targetProcessName |
3618 // Read the user-side data into targetProcessName |
3588 err = Kern::ThreadDesRead(iClientThread,a1,targetProcessName,0,KChunkShiftBy0); |
3619 err = Kern::ThreadDesRead(iClientThread,a1,targetProcessName,0,KChunkShiftBy0); |
3589 if (err != KErrNone) |
3620 if (err != KErrNone) |
3590 { |
3621 { |
3591 // Something bad happened so free the memory and return |
3622 // Something bad happened so free the memory and return |
3592 NKern::ThreadEnterCS(); |
3623 NKern::ThreadEnterCS(); |
3593 Kern::Free(buffer); |
3624 Kern::Free(buffer); |
3594 NKern::ThreadLeaveCS(); |
3625 NKern::ThreadLeaveCS(); |
3595 |
3626 |
3596 return err; |
3627 return err; |
3597 } |
3628 } |
3598 |
3629 |
3599 // Read the Event and Action from the user-side |
3630 // Read the Event and Action from the user-side |
3600 TRM_DebugEventActionInfo info(0,0,0); |
3631 TRM_DebugEventActionInfo info(0,0,0); |
3601 |
3632 |
3602 err = Kern::ThreadRawRead(iClientThread, a2, &info, sizeof(info)); |
3633 err = Kern::ThreadRawRead(iClientThread, a2, &info, sizeof(info)); |
3603 if (err != KErrNone) |
3634 if (err != KErrNone) |
3604 { |
3635 { |
3605 // Could not read event action data from the user-side |
3636 // Could not read event action data from the user-side |
3606 |
3637 |
3607 // Free memory used for targetProcessName |
3638 // Free memory used for targetProcessName |
3608 NKern::ThreadEnterCS(); |
3639 NKern::ThreadEnterCS(); |
3609 Kern::Free(buffer); |
3640 Kern::Free(buffer); |
3610 NKern::ThreadLeaveCS(); |
3641 NKern::ThreadLeaveCS(); |
3611 |
3642 |
3612 return err; |
3643 return err; |
3613 } |
3644 } |
3614 |
3645 |
3615 // Find the target process |
3646 // Find the target process |
3616 DTargetProcess* pProcess = TheDProcessTracker.FindProcess(targetProcessName); |
3647 DTargetProcess* pProcess = TheDProcessTracker.FindProcess(targetProcessName); |
3617 if (pProcess == NULL) |
3648 if (pProcess == NULL) |
3618 { |
3649 { |
3619 // Could not find this process |
3650 // Could not find this process |
3620 |
3651 |
3621 // Free memory used for targetProcessName |
3652 // Free memory used for targetProcessName |
3622 NKern::ThreadEnterCS(); |
3653 NKern::ThreadEnterCS(); |
3623 Kern::Free(buffer); |
3654 Kern::Free(buffer); |
3624 NKern::ThreadLeaveCS(); |
3655 NKern::ThreadLeaveCS(); |
3625 |
3656 |
3626 return KErrArgument; |
3657 return KErrArgument; |
3627 } |
3658 } |
3628 |
3659 |
3629 TUint64 debugAgentId = info.iAgentId; |
3660 TUint64 debugAgentId = info.iAgentId; |
3630 |
3661 |
3631 // Find the agent |
3662 // Find the agent |
3632 DDebugAgent* debugAgent = pProcess->Agent(debugAgentId); |
3663 DDebugAgent* debugAgent = pProcess->Agent(debugAgentId); |
3633 if (debugAgent == NULL) |
3664 if (debugAgent == NULL) |
3634 { |
3665 { |
3635 // Bad agent means there is no tracking agent |
3666 // Bad agent means there is no tracking agent |
3636 LOG_MSG2("Cannot locate debug agent with pid 0x%0x16lx",info.iAgentId); |
3667 LOG_MSG2("Cannot locate debug agent with pid 0x%0x16lx",info.iAgentId); |
3637 |
3668 |
3638 // Free memory used for targetProcessName |
3669 // Free memory used for targetProcessName |
3639 NKern::ThreadEnterCS(); |
3670 NKern::ThreadEnterCS(); |
3640 Kern::Free(buffer); |
3671 Kern::Free(buffer); |
3641 NKern::ThreadLeaveCS(); |
3672 NKern::ThreadLeaveCS(); |
3642 |
3673 |
3643 return KErrGeneral; |
3674 return KErrGeneral; |
3644 } |
3675 } |
3645 |
3676 |
3646 // Set the event action |
3677 // Set the event action |
3647 debugAgent->SetEventAction((TEventType)info.iEvent,(TKernelEventAction)info.iAction); |
3678 debugAgent->SetEventAction((TEventType)info.iEvent,(TKernelEventAction)info.iAction); |
3648 |
3679 |
3649 // Free memory used for targetProcessName |
3680 // Free memory used for targetProcessName |
3750 } |
3781 } |
3751 process->Close(NULL); |
3782 process->Close(NULL); |
3752 } |
3783 } |
3753 |
3784 |
3754 if (err == KErrNone) |
3785 if (err == KErrNone) |
3755 { |
3786 { |
3756 LOG_MSG2("DRM_DebugChannel::IsDebuggable(aProcessId 0x%08x) - Yes it is debuggable\n",aProcessId); |
3787 LOG_MSG2("DRM_DebugChannel::IsDebuggable(aProcessId 0x%08x) - Yes it is debuggable\n",aProcessId); |
3757 } |
3788 } |
3758 |
3789 |
3759 return err; |
3790 return err; |
3760 } |
3791 } |