|
1 // Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies). |
|
2 // All rights reserved. |
|
3 // This component and the accompanying materials are made available |
|
4 // under the terms of "Eclipse Public License v1.0" |
|
5 // which accompanies this distribution, and is available |
|
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
7 // |
|
8 // Initial Contributors: |
|
9 // Nokia Corporation - initial contribution. |
|
10 // |
|
11 // Contributors: |
|
12 // |
|
13 // Description: |
|
14 // core_dump_session_calls.cpp |
|
15 // |
|
16 |
|
17 |
|
18 |
|
19 /** |
|
20 @file |
|
21 @internalTechnology |
|
22 @released |
|
23 */ |
|
24 |
|
25 #include <crashlogwalker.h> |
|
26 #include <scmconfigitem.h> |
|
27 #include "coredumpsession.h" |
|
28 |
|
29 using namespace Debug; |
|
30 |
|
31 // Creates and returns a heap descriptor which holds contents of list |
|
32 HBufC8* CCoreDumpSession::MarshalListL( TListRequest & req, TAny * list ) |
|
33 { |
|
34 |
|
35 LOG_MSG("->CCoreDumpSession::MarshalListL()\n" ); |
|
36 |
|
37 // Create a dynamic flat buffer to hold this object's member data |
|
38 // Can only use CBufFlat due to Store supporting CBufFlat and CBufSeg |
|
39 // See Symbian OS guide » System libraries » Using Store » Streaming » Templated stream operators |
|
40 |
|
41 const TInt KExpandSize = 128; // "Granularity" of dynamic buffer |
|
42 |
|
43 CBufFlat* buf = CBufFlat::NewL( KExpandSize ); |
|
44 CleanupStack::PushL( buf ); |
|
45 |
|
46 RBufWriteStream stream( *buf ); // Stream over the buffer |
|
47 CleanupClosePushL( stream ); |
|
48 |
|
49 for( TInt i = 0; i < req.iRemaining; i ++ ) |
|
50 { |
|
51 switch( req.iListType ) |
|
52 { |
|
53 case TListRequest::EThreadList: |
|
54 { |
|
55 //LOG_MSG2( " -> ((*threadPointerList)[%d])->ExternalizeL( )\n", i ); |
|
56 iThreadPointerList[i]->ExternalizeL( stream, buf ); |
|
57 //LOG_MSG2( " buf->Size()=%d\n", buf->Size() ); |
|
58 break; |
|
59 } |
|
60 case TListRequest::EProcessList: |
|
61 { |
|
62 //LOG_MSG2( " -> ((*processPointerList)[%d])->ExternalizeL( )\n", i ); |
|
63 iProcessPointerList[i]->ExternalizeL( stream, buf ); |
|
64 //LOG_MSG2( " buf->Size()=%d\n", buf->Size() ); |
|
65 break; |
|
66 } |
|
67 |
|
68 case TListRequest::EExecutableList: |
|
69 { |
|
70 //LOG_MSG2( " -> ((*processPointerList)[%d])->ExternalizeL( )\n", i ); |
|
71 iExecutablePointerList[i]->ExternalizeL( stream, buf ); |
|
72 //LOG_MSG2( " buf->Size()=%d\n", buf->Size() ); |
|
73 break; |
|
74 } |
|
75 case TListRequest::EFormatterList: |
|
76 { |
|
77 LOG_MSG2( " -> ((*formatterInfos)[%d])->ExternalizeL( )\n", i ); |
|
78 iFormatterInfos[i]->ExternalizeL( stream, buf ); |
|
79 //LOG_MSG2( " buf->Size()=%d\n", buf->Size() ); |
|
80 break; |
|
81 } |
|
82 case TListRequest::EWriterList: |
|
83 { |
|
84 LOG_MSG2( " -> ((*writerInfos)[%d])->ExternalizeL( )\n", i ); |
|
85 iWriterInfos[i]->ExternalizeL( stream, buf ); |
|
86 //LOG_MSG2( " buf->Size()=%d\n", buf->Size() ); |
|
87 break; |
|
88 } |
|
89 case TListRequest::ECrashList: |
|
90 { |
|
91 LOG_MSG2( " -> ((*iCrashList)[%d])->ExternalizeL( )\n", i ); |
|
92 iCrashList[i]->ExternalizeL(stream, buf); |
|
93 //LOG_MSG2( " buf->Size()=%d\n", buf->Size() ); |
|
94 break; |
|
95 } |
|
96 default: |
|
97 { |
|
98 LOG_MSG("CCoreDumpSession::MarshalListL : Received unknown list type"); |
|
99 User::Leave( KErrNotSupported ); |
|
100 } |
|
101 } |
|
102 } |
|
103 |
|
104 stream.CommitL(); |
|
105 |
|
106 TInt bufSize = buf->Size(); |
|
107 |
|
108 // Create a heap descriptor from the buffer |
|
109 HBufC8* des = HBufC8::NewL( buf->Size() ); |
|
110 TPtr8 ptr( des->Des() ); |
|
111 |
|
112 buf->Read( 0, ptr, buf->Size() ); |
|
113 |
|
114 CleanupStack::PopAndDestroy( &stream ); |
|
115 CleanupStack::PopAndDestroy( buf ); |
|
116 |
|
117 return des; |
|
118 } |
|
119 |
|
120 |
|
121 void CCoreDumpSession::GetListL( const RMessage2& aMessage ) |
|
122 { |
|
123 LOG_MSG( "CCoreDumpSession::GetListL()\n" ); |
|
124 |
|
125 TListRequest listRequest; |
|
126 HBufC8 *listDes = NULL; |
|
127 |
|
128 TPtr8 listReqPtr( (TUint8 *)&listRequest, sizeof(TListRequest) ); |
|
129 |
|
130 aMessage.ReadL( 0, listReqPtr ); |
|
131 |
|
132 switch( listRequest.iListType ) |
|
133 { |
|
134 case TListRequest::EThreadList : |
|
135 { |
|
136 if( listRequest.iRequiredDescriptorSize != iTotalThreadListDescSize ) |
|
137 { |
|
138 LOG_MSG( " ERROR !* listReq.iRequiredDescriptorSize != iTotalThreadListDescSize\n" ); |
|
139 User::Leave( KErrBadDescriptor ); |
|
140 } |
|
141 listDes = iMarshalledThreadList; |
|
142 break; |
|
143 } |
|
144 case TListRequest::EProcessList : |
|
145 { |
|
146 if( listRequest.iRequiredDescriptorSize != iTotalProcessListDescSize ) |
|
147 { |
|
148 LOG_MSG( " ERROR !* listReq.iRequiredDescriptorSize != iTotalProcessListDescSize\n" ); |
|
149 User::Leave( KErrBadDescriptor ); |
|
150 } |
|
151 listDes = iMarshalledProcessList; |
|
152 break; |
|
153 } |
|
154 case TListRequest::EExecutableList : |
|
155 { |
|
156 if( listRequest.iRequiredDescriptorSize != iTotalExecutableListDescSize ) |
|
157 { |
|
158 LOG_MSG( " ERROR !* listReq.iRequiredDescriptorSize != iTotalExecutableListDescSize\n" ); |
|
159 User::Leave( KErrBadDescriptor ); |
|
160 } |
|
161 listDes = iMarshalledExecutableList; |
|
162 break; |
|
163 } |
|
164 case TListRequest::EFormatterList : |
|
165 { |
|
166 if( listRequest.iRequiredDescriptorSize != iTotalFormatterListDescSize ) |
|
167 { |
|
168 LOG_MSG( " ERROR !* listReq.iRequiredDescriptorSize != iTotalFormatterListDescSize\n" ); |
|
169 User::Leave( KErrBadDescriptor ); |
|
170 } |
|
171 listDes = iMarshalledFormatterList; |
|
172 break; |
|
173 } |
|
174 case TListRequest::EWriterList : |
|
175 { |
|
176 if( listRequest.iRequiredDescriptorSize != iTotalWriterListDescSize ) |
|
177 { |
|
178 LOG_MSG( " ERROR !* listReq.iRequiredDescriptorSize != iTotalWriterListDescSize\n" ); |
|
179 User::Leave( KErrBadDescriptor ); |
|
180 } |
|
181 listDes = iMarshalledWriterList; |
|
182 break; |
|
183 } |
|
184 case TListRequest::ECrashList : |
|
185 { |
|
186 if( listRequest.iRequiredDescriptorSize != iTotalCrashInfoDescSize ) |
|
187 { |
|
188 LOG_MSG( " ERROR !* listReq.iRequiredDescriptorSize != iTotalWriterListDescSize\n" ); |
|
189 User::Leave( KErrBadDescriptor ); |
|
190 } |
|
191 listDes = iMarshalledCrashList; |
|
192 break; |
|
193 } |
|
194 default : |
|
195 { |
|
196 LOG_MSG2( " ERROR !* : CCoreDumpSession::ListInfoL() : invalid TListRequestType %d\n", listRequest.iListType ); |
|
197 User::Leave( KErrArgument ); |
|
198 } |
|
199 } |
|
200 |
|
201 if ( listDes == NULL ) |
|
202 { |
|
203 |
|
204 LOG_MSG( " ERROR !* MarshalData returned null buf\n" ); |
|
205 User::Leave( KErrBadDescriptor ); |
|
206 |
|
207 } |
|
208 else |
|
209 { |
|
210 |
|
211 //LOG_MSG( " -> TPtr8 lsitPtr( listDes->Des() )\n" ); |
|
212 TPtr8 listPtr( listDes->Des() ); |
|
213 //LOG_MSG2( " listPtr->Size()=%d\n", listPtr.Size() ); |
|
214 |
|
215 if( listPtr.Size() == 0 ) |
|
216 { |
|
217 LOG_MSG( " ERROR !* : if( lsitPtr.Size() == 0 )\n" ); |
|
218 User::Leave( KErrBadDescriptor ); |
|
219 } |
|
220 |
|
221 //LOG_MSG( " -> WriteL( 1, listPtr )\n" ); |
|
222 aMessage.WriteL( 1, listPtr ); |
|
223 |
|
224 } |
|
225 |
|
226 } |
|
227 |
|
228 |
|
229 void CCoreDumpSession::ListInfoL( const RMessage2& aMessage ) |
|
230 { |
|
231 LOG_MSG( "CCoreDumpSession::ListInfoL()\n" ); |
|
232 |
|
233 TListRequest listRequest; |
|
234 TUint64 procId; |
|
235 |
|
236 TPtr8 listReqPtr( (TUint8 *)&listRequest, sizeof(TListRequest) ); |
|
237 |
|
238 aMessage.ReadL( 0, listReqPtr ); |
|
239 |
|
240 switch( listRequest.iListType ) |
|
241 { |
|
242 case TListRequest::EThreadList : |
|
243 { |
|
244 procId = MAKE_TUINT64( listRequest.iSubId2, listRequest.iSubId1 ); |
|
245 iDataSource->GetThreadListL( procId, iThreadPointerList, iTotalThreadListDescSize ); |
|
246 |
|
247 listRequest.iRemaining = iThreadPointerList.Count(); |
|
248 |
|
249 //mark those that we observe |
|
250 for(TInt i = 0; i < iObservationList.Count(); i++) |
|
251 { |
|
252 for(TInt j = 0; j < iThreadPointerList.Count(); j++) |
|
253 { |
|
254 if(iObservationList[i]->HasThread(iThreadPointerList[j]->Name())) |
|
255 { |
|
256 iThreadPointerList[j]->Observed(ETrue); |
|
257 } |
|
258 } |
|
259 } |
|
260 |
|
261 if( NULL != iMarshalledThreadList ) |
|
262 { |
|
263 delete iMarshalledThreadList; |
|
264 } |
|
265 |
|
266 //LOG_MSG( " EThreadList -> MarshalDataL()\n" ); |
|
267 iMarshalledThreadList = MarshalListL( listRequest, (TAny*) &iThreadPointerList ); |
|
268 listRequest.iRequiredDescriptorSize = iMarshalledThreadList->Des().Size(); |
|
269 iTotalThreadListDescSize = listRequest.iRequiredDescriptorSize; |
|
270 |
|
271 break; |
|
272 } |
|
273 case TListRequest::EProcessList : |
|
274 { |
|
275 iDataSource->GetProcessListL( iProcessPointerList, iTotalProcessListDescSize ); |
|
276 |
|
277 listRequest.iRemaining = iProcessPointerList.Count(); |
|
278 |
|
279 //mark those that we observe |
|
280 for(TInt i = 0; i < iObservationList.Count(); i++) |
|
281 { |
|
282 for(TInt j = 0; j < iProcessPointerList.Count(); j++) |
|
283 { |
|
284 if( (iObservationList[i]->TargetName() == iProcessPointerList[j]->Name()) && //attached to it |
|
285 (iObservationList[i]->ThreadCount() == 0) ) //and no threads on the list |
|
286 { |
|
287 iProcessPointerList[j]->Observed(ETrue); |
|
288 } |
|
289 } |
|
290 } |
|
291 |
|
292 if( NULL != iMarshalledProcessList ) |
|
293 { |
|
294 delete iMarshalledProcessList; |
|
295 } |
|
296 |
|
297 //LOG_MSG( " EProcessList -> MarshalDataL()\n" ); |
|
298 iMarshalledProcessList = MarshalListL( listRequest, (TAny*) &iProcessPointerList ); |
|
299 listRequest.iRequiredDescriptorSize = iMarshalledProcessList->Des().Size(); |
|
300 iTotalProcessListDescSize = listRequest.iRequiredDescriptorSize; |
|
301 |
|
302 break; |
|
303 } |
|
304 case TListRequest::EExecutableList : |
|
305 { |
|
306 iDataSource->GetExecutableListL( iExecutablePointerList, iTotalExecutableListDescSize ); |
|
307 |
|
308 listRequest.iRemaining = iExecutablePointerList.Count(); |
|
309 //LOG_MSG2( " listRequest.iRemaining=%d\n", listRequest.iRemaining ); |
|
310 |
|
311 //mark those that we observe |
|
312 for(TInt i = 0; i < iObservationList.Count(); i++) |
|
313 { |
|
314 for(TInt j = 0; j < iExecutablePointerList.Count(); j++) |
|
315 { |
|
316 if( iObservationList[i]->TargetName() == iExecutablePointerList[j]->Name() )//attached to it |
|
317 { |
|
318 iExecutablePointerList[j]->Observed(ETrue); |
|
319 } |
|
320 } |
|
321 } |
|
322 |
|
323 if( NULL != iMarshalledExecutableList ) |
|
324 { |
|
325 delete iMarshalledExecutableList; |
|
326 } |
|
327 |
|
328 //LOG_MSG( " EExecutableList -> MarshalDataL()\n" ); |
|
329 iMarshalledExecutableList = MarshalListL( listRequest, (TAny*) &iExecutablePointerList ); |
|
330 listRequest.iRequiredDescriptorSize = iMarshalledExecutableList->Des().Size(); |
|
331 iTotalExecutableListDescSize = listRequest.iRequiredDescriptorSize; |
|
332 |
|
333 break; |
|
334 } |
|
335 case TListRequest::EFormatterList : |
|
336 { |
|
337 listRequest.iRemaining = iFormatterInfos.Count(); |
|
338 |
|
339 if(iMarshalledFormatterList) |
|
340 { |
|
341 delete iMarshalledFormatterList; |
|
342 } |
|
343 |
|
344 iMarshalledFormatterList = MarshalListL( listRequest, (TAny*) &iFormatterInfos ); |
|
345 listRequest.iRequiredDescriptorSize = iMarshalledFormatterList->Des().Size(); |
|
346 iTotalFormatterListDescSize = listRequest.iRequiredDescriptorSize; |
|
347 |
|
348 break; |
|
349 } |
|
350 case TListRequest::EWriterList : |
|
351 { |
|
352 listRequest.iRemaining = iWriterInfos.Count(); |
|
353 |
|
354 if(iMarshalledWriterList) |
|
355 { |
|
356 delete iMarshalledWriterList; |
|
357 } |
|
358 |
|
359 iMarshalledWriterList = MarshalListL( listRequest, (TAny*) &iWriterInfos ); |
|
360 listRequest.iRequiredDescriptorSize = iMarshalledWriterList->Des().Size(); |
|
361 iTotalWriterListDescSize = listRequest.iRequiredDescriptorSize; |
|
362 |
|
363 break; |
|
364 } |
|
365 case TListRequest::ECrashList : |
|
366 { |
|
367 //Dealing with listing crashes from flash. Refresh the list and then |
|
368 //serialise the list onto iMarshalledCrashList |
|
369 |
|
370 RefreshCrashListFromFlashL(); |
|
371 listRequest.iRemaining = iCrashList.Count(); |
|
372 |
|
373 if(iMarshalledCrashList) |
|
374 { |
|
375 delete iMarshalledCrashList; |
|
376 iMarshalledCrashList = NULL; |
|
377 } |
|
378 |
|
379 iMarshalledCrashList = MarshalListL(listRequest, (TAny*)&iCrashList); |
|
380 listRequest.iRequiredDescriptorSize = iMarshalledCrashList->Des().Size(); |
|
381 iTotalCrashInfoDescSize = listRequest.iRequiredDescriptorSize; |
|
382 |
|
383 break; |
|
384 } |
|
385 default : |
|
386 { |
|
387 LOG_MSG2( " ERROR !* : CCoreDumpSession::ListInfoL() : invalid TListRequestType %d\n", listRequest.iListType ); |
|
388 User::Leave( KErrArgument ); |
|
389 } |
|
390 } |
|
391 |
|
392 aMessage.WriteL( 0, listReqPtr ); |
|
393 |
|
394 } |
|
395 |
|
396 /** |
|
397 * This method looks at the crash logs in the flash partition |
|
398 * and caches them |
|
399 */ |
|
400 void CCoreDumpSession::RefreshCrashListFromFlashL() |
|
401 { |
|
402 LOG_MSG("CCoreDumpSession::RefreshCrashListFromFlashL()"); |
|
403 |
|
404 TBuf8<Debug::KMaxCoreHeaderSize> buf; |
|
405 iCrashList.ResetAndDestroy(); |
|
406 |
|
407 //Start looking where the config ends if it exists |
|
408 TInt crashLogPos = 0; |
|
409 SCMConfiguration* config = FlashDataSource()->GetSCMConfigFromFlashL(); |
|
410 if(config) |
|
411 { |
|
412 crashLogPos = config->GetSize(); |
|
413 } |
|
414 |
|
415 delete config; |
|
416 |
|
417 do |
|
418 { |
|
419 LOG_MSG3("Looking for crash at [%d] [0x%X]", crashLogPos, crashLogPos); |
|
420 |
|
421 //Read in the 2 headers and the context, while we are in the crash log |
|
422 TInt err = iSecSess.ReadCrashLog(crashLogPos, buf, Debug::KMaxCoreHeaderSize); |
|
423 if(err != KErrNone) |
|
424 { |
|
425 if(err == KErrPermissionDenied) |
|
426 { |
|
427 User::Leave(err); |
|
428 } |
|
429 |
|
430 //We have reached the end of the crash partition |
|
431 return; |
|
432 } |
|
433 |
|
434 TCrashLogWalker wlk(buf); |
|
435 |
|
436 if(KErrNone == wlk.ReadLogHeader(0)) |
|
437 { |
|
438 LOG_MSG("Found a valid crash"); |
|
439 const TCrashInfoHeader hdr = wlk.GetCrashHeader(); |
|
440 TCrashInfo* inf = TCrashInfo::NewL(hdr); |
|
441 inf->iCrashSource = TCrashInfo::ESystemCrash; |
|
442 inf->iContext = wlk.GetCrashContext(); |
|
443 |
|
444 iCrashList.Append(inf); |
|
445 |
|
446 //Increment this so it goes up by the log size AND then enough to align it to a flash block |
|
447 TUint32 flashPadding = 0x20000 - (crashLogPos + hdr.iLogSize)%0x20000; |
|
448 crashLogPos += (hdr.iLogSize + flashPadding); |
|
449 } |
|
450 else |
|
451 { |
|
452 //otherwise we dont have any more crashes |
|
453 return; |
|
454 } |
|
455 |
|
456 } |
|
457 while(true); |
|
458 |
|
459 } |
|
460 |
|
461 |
|
462 /** |
|
463 * Processes the crash log in the flash partition corrosponding to the crash ID of the parameter |
|
464 * passed through. If this doesnt match a crash in the partition, or the flash cannot be read |
|
465 * this will leave with KErrCorrupted |
|
466 * @param aMessage |
|
467 * @leave one of the OS wide codes |
|
468 */ |
|
469 void CCoreDumpSession::ProcessCrashLogL(const RMessage2& aMessage) |
|
470 { |
|
471 TInt crashId = aMessage.Int0(); |
|
472 LOG_MSG2("->CCoreDumpSession::ProcessCrashLogL(ID = [%d])\n", crashId); |
|
473 |
|
474 RefreshCrashListFromFlashL(); |
|
475 |
|
476 for(TInt cnt = 0; cnt < iCrashList.Count(); cnt++) |
|
477 { |
|
478 if(iCrashList[cnt]->iCrashId == crashId) |
|
479 { |
|
480 RDebug::Printf("Going to the crash handler"); |
|
481 iCrashHandler->HandleCrashFromFlashL(*(iCrashList[cnt])); |
|
482 } |
|
483 } |
|
484 } |
|
485 |
|
486 /** |
|
487 * Processes the crash log in the flash partition Asynchronously corrosponding to the crash ID of the parameter |
|
488 * passed through. It refreshes the crash list and then calls the crash handler. Leaves with standard leave codes |
|
489 * when the underlying methods leave. |
|
490 * @param aMessage |
|
491 * @leave one of the OS wide codes |
|
492 */ |
|
493 void CCoreDumpSession::ProcessCrashLogAsyncL(const RMessage2& aMessage) |
|
494 { |
|
495 TInt crashId = aMessage.Int0(); |
|
496 LOG_MSG2("->CCoreDumpSession::ProcessCrashLogAsyncL(ID = [%d])\n", crashId); |
|
497 |
|
498 RefreshCrashListFromFlashL(); |
|
499 |
|
500 for(TInt cnt = 0; cnt < iCrashList.Count(); cnt++) |
|
501 { |
|
502 if(iCrashList[cnt]->iCrashId == crashId) |
|
503 { |
|
504 LOG_MSG("Going to the crash handler using the async mechanism"); |
|
505 iCrashHandler->HandleCrashFromFlashL(*(iCrashList[cnt]), aMessage); |
|
506 } |
|
507 } |
|
508 } |
|
509 |
|
510 /** |
|
511 * Cancels asynchronous processing of the crash log in the flash partition |
|
512 * @param aMessage |
|
513 */ |
|
514 void CCoreDumpSession::CancelProcessCrashLogAsync(const RMessage2& aMessage) |
|
515 { |
|
516 TInt crashId = aMessage.Int0(); |
|
517 LOG_MSG2("->CCoreDumpSession::CancelProcessCrashLogAsyncL(ID = [%d])\n", crashId); |
|
518 |
|
519 for(TInt cnt = 0; cnt < iCrashList.Count(); cnt++) |
|
520 { |
|
521 if(iCrashList[cnt]->iCrashId == crashId) |
|
522 { |
|
523 LOG_MSG("Going to the cancel async crash handler processing"); |
|
524 iCrashHandler->CancelHandleCrashFromFlash(*(iCrashList[cnt])); |
|
525 } |
|
526 } |
|
527 } |
|
528 |
|
529 /** |
|
530 * From a crash ID gets a TCrashInfo |
|
531 * @param aCrashId crash ID to search for |
|
532 * @param aCrashInfo the crash info for supplied crash ID |
|
533 * @leave one of the OS wide codes |
|
534 */ |
|
535 void CCoreDumpSession::GetCrashInfoL(TInt aCrashId, TCrashInfo& aCrashInfo) |
|
536 { |
|
537 for(TInt i = 0; i<iCrashList.Count(); i++) |
|
538 { |
|
539 if(iCrashList[i]->iCrashId == aCrashId) |
|
540 { |
|
541 aCrashInfo = *(iCrashList[i]); |
|
542 return; |
|
543 } |
|
544 } |
|
545 |
|
546 User::Leave(KErrNotFound); |
|
547 } |
|
548 |
|
549 /** |
|
550 Retrives the 'cancel crash' property value and checks if required to abort the crash dump. Updates 'crash progress' property. |
|
551 |
|
552 @param aProgress descriptor with the crash progress value. |
|
553 @leave KErrAbort if crash cancel property has been set |
|
554 */ |
|
555 void CCoreDumpSession::UpdateProgressL(const TDesC &aProgress) const |
|
556 { |
|
557 LOG_MSG("->CCoreDumpSession::UpdateProgressL()\n"); |
|
558 TInt cancelCrash = EFalse; |
|
559 TInt err = RProperty::Get(KCoreDumpServUid, ECrashProgress, cancelCrash); |
|
560 if(err != KErrNone) |
|
561 { |
|
562 LOG_MSG2("CCoreDumpSession::UpdateProgressL - unable to retrive 'ECrashProgress' value! err:%d\n", err); |
|
563 } |
|
564 |
|
565 if(cancelCrash) |
|
566 { |
|
567 LOG_MSG("CCoreDumpSession::UpdateProgressL - aborting dump in progress\n"); |
|
568 User::Leave(KErrNotReady); |
|
569 } |
|
570 |
|
571 err = RProperty::Set(KCoreDumpServUid, ECrashProgress, aProgress); |
|
572 if(err != KErrNone) |
|
573 { |
|
574 LOG_MSG2("CCoreDumpSession::UpdateProgressL - unable to retrive 'crash progress' value! err:%d\n", err); |
|
575 } |
|
576 #ifdef DEBUG |
|
577 User::After(1000000); |
|
578 #endif |
|
579 } |
|
580 |
|
581 /** |
|
582 * This method removes a crash log from the flash partition |
|
583 * @param aMessage |
|
584 * @leave one of the OS wide codes |
|
585 */ |
|
586 void CCoreDumpSession::DeleteCrashLogL(const RMessage2& aMessage) |
|
587 { |
|
588 User::Leave(KErrNotSupported); |
|
589 } |
|
590 |
|
591 void CCoreDumpSession::DeleteCrashPartitionL() |
|
592 { |
|
593 LOG_MSG("CCoreDumpSession::DeleteCrashPartitionL()"); |
|
594 |
|
595 UpdateProgressL(_L("Erasing Entire Log")); |
|
596 |
|
597 //Read in config first |
|
598 SCMConfiguration* config = FlashDataSource()->GetSCMConfigFromFlashL(); |
|
599 TCleanupItem scmCleanup(CCoreDumpSession::CleanupSCMConfiguration, (TAny*)config); |
|
600 if(config) |
|
601 CleanupStack::PushL(scmCleanup); |
|
602 |
|
603 TInt err = iSecSess.EraseCrashFlashPartition(); |
|
604 User::LeaveIfError(err); |
|
605 |
|
606 if(config) |
|
607 { |
|
608 //Now we rewrite the config |
|
609 RBuf8 data; |
|
610 data.CreateL(config->GetSize()); |
|
611 data.SetLength(config->GetSize()); |
|
612 data.CleanupClosePushL(); |
|
613 |
|
614 TByteStreamWriter writer(const_cast<TUint8*>(data.Ptr()), EFalse); |
|
615 config->Serialize(writer); |
|
616 |
|
617 TUint32 written = 0; |
|
618 User::LeaveIfError(iSecSess.WriteCrashConfig(0, data, written)); |
|
619 |
|
620 CleanupStack::PopAndDestroy(2);//data and scmCleanup |
|
621 } |
|
622 |
|
623 RefreshCrashListFromFlashL(); |
|
624 |
|
625 UpdateProgressL(_L("Idle")); |
|
626 } |
|
627 |
|
628 void CCoreDumpSession::CreateWriterL( const TUid loadRequestUid ) |
|
629 { |
|
630 LOG_MSG("->CCoreDumpSession::CreateWriterL()\n" ); |
|
631 |
|
632 ValidatePluginL( loadRequestUid ); |
|
633 |
|
634 if(iPluginList.Count() == 0) |
|
635 { |
|
636 RefreshPluginListL(); |
|
637 } |
|
638 |
|
639 CPluginInfo *info = NULL; |
|
640 for(TInt i = 0; i < iPluginList.Count(); i++) |
|
641 { |
|
642 if(iPluginList[i].iUid == loadRequestUid) |
|
643 { |
|
644 info = CPluginInfo::NewL(iPluginList[i].iName, |
|
645 loadRequestUid.iUid, |
|
646 iPluginList[i].iVersion, |
|
647 TPluginRequest::EWriter); |
|
648 CleanupStack::PushL(info); |
|
649 break; |
|
650 } |
|
651 } |
|
652 |
|
653 if(!info) |
|
654 { |
|
655 LOG_MSG2("CCoreDumpSession::CreateWriterL - unable to find writer uid:%d on plugin type list!\n", loadRequestUid); |
|
656 User::Leave(KErrArgument); |
|
657 } |
|
658 |
|
659 iWriterInfos.AppendL(info); |
|
660 CleanupStack::Pop(info); |
|
661 |
|
662 CCrashDataSave *writer = CCrashDataSave::NewL( (TUid)( loadRequestUid ) ); |
|
663 |
|
664 CleanupStack::PushL(writer); |
|
665 iWriterPlugins.AppendL(writer); |
|
666 CleanupStack::Pop(writer); |
|
667 |
|
668 LOG_MSG3("CCoreDumpSession::CreateFormatter fmt:%d, wrt:%d\n", iFormatterPlugins.Count(), iWriterPlugins.Count()); |
|
669 //for compatibility, first pair is bound by default |
|
670 if( (iFormatterPlugins.Count() == 1) && (iWriterPlugins.Count() == 1) ) |
|
671 { |
|
672 LOG_MSG("CCoreDumpSession::CreateFormatter binding default plugin pair\n" ); |
|
673 iFormatterInfos[0]->Pair(0); |
|
674 iFormatterPlugins[0]->ConfigureDataSaveL(iWriterPlugins[0]); |
|
675 } |
|
676 } |
|
677 |
|
678 void CCoreDumpSession::CreateFormatterL( const TUid loadRequestUid ) |
|
679 { |
|
680 LOG_MSG( "->CCoreDumpSession::CreateFormatter()\n" ); |
|
681 |
|
682 ValidatePluginL( loadRequestUid ); |
|
683 |
|
684 if(iPluginList.Count() == 0) |
|
685 { |
|
686 RefreshPluginListL(); |
|
687 } |
|
688 |
|
689 CPluginInfo *info = NULL; |
|
690 for(TInt i = 0; i < iPluginList.Count(); i++) |
|
691 { |
|
692 if(iPluginList[i].iUid == loadRequestUid) |
|
693 { |
|
694 info = CPluginInfo::NewL(iPluginList[i].iName, |
|
695 loadRequestUid.iUid, |
|
696 iPluginList[i].iVersion, |
|
697 TPluginRequest::EFormatter); |
|
698 CleanupStack::PushL(info); |
|
699 break; |
|
700 } |
|
701 } |
|
702 |
|
703 if(!info) |
|
704 { |
|
705 LOG_MSG2("CCoreDumpSession::CreateFormatterL - unable to find formatter uid:%X on plugin type list!\n", loadRequestUid); |
|
706 User::Leave(KErrArgument); |
|
707 } |
|
708 |
|
709 iFormatterInfos.AppendL(info); |
|
710 CleanupStack::Pop(info); |
|
711 |
|
712 CCoreDumpFormatter *formatter = CCoreDumpFormatter::NewL( (TUid)( loadRequestUid ) ); |
|
713 |
|
714 CleanupStack::PushL(formatter); |
|
715 iFormatterPlugins.AppendL(formatter); |
|
716 CleanupStack::Pop(formatter); |
|
717 |
|
718 LOG_MSG3("CCoreDumpSession::CreateFormatter fmt:%d, wrt:%d\n", iFormatterPlugins.Count(), iWriterPlugins.Count()); |
|
719 //for compatibility, first pair is bound by default |
|
720 if( (iFormatterPlugins.Count() == 1) && (iWriterPlugins.Count() == 1) ) |
|
721 { |
|
722 LOG_MSG("CCoreDumpSession::CreateFormatter binding default plugin pair\n" ); |
|
723 iFormatterInfos[0]->Pair(0); |
|
724 iFormatterPlugins[0]->ConfigureDataSaveL(iWriterPlugins[0]); |
|
725 } |
|
726 } |
|
727 |
|
728 void CCoreDumpSession::DeleteFormatterL( const TUid aFreeRequestUid, const TUint aIndex ) |
|
729 { |
|
730 LOG_MSG("->CCoreDumpSession::DeleteFormatterL()\n"); |
|
731 if( (iFormatterInfos.Count() > aIndex) && (iFormatterInfos[aIndex]->Uid() == aFreeRequestUid.iUid) ) |
|
732 { |
|
733 delete iFormatterPlugins[aIndex]; |
|
734 iFormatterPlugins.Remove(aIndex); |
|
735 |
|
736 delete iFormatterInfos[aIndex]; |
|
737 iFormatterInfos.Remove(aIndex); |
|
738 } |
|
739 else |
|
740 { |
|
741 User::Leave(KErrArgument); |
|
742 } |
|
743 } |
|
744 |
|
745 void CCoreDumpSession::DeleteWriterL( const TUid aFreeRequestUid, const TUint aIndex ) |
|
746 { |
|
747 LOG_MSG("->CCoreDumpSession::DeleteWriterL()\n"); |
|
748 if( (iWriterInfos.Count() > aIndex) && (iWriterInfos[aIndex]->Uid() == aFreeRequestUid.iUid) ) |
|
749 { |
|
750 for(TInt i = 0; i < iFormatterInfos.Count(); i++) |
|
751 { |
|
752 if(iFormatterInfos[i]->Pair() == aIndex) |
|
753 { |
|
754 iFormatterInfos[i]->Pair(KMaxTUint32); |
|
755 } |
|
756 } |
|
757 |
|
758 delete iWriterPlugins[aIndex]; |
|
759 iWriterPlugins.Remove(aIndex); |
|
760 |
|
761 delete iWriterInfos[aIndex]; |
|
762 iWriterInfos.Remove(aIndex); |
|
763 } |
|
764 else |
|
765 { |
|
766 User::Leave(KErrArgument); |
|
767 } |
|
768 } |
|
769 |
|
770 void CCoreDumpSession::PluginRequestL(const RMessage2& aMessage) |
|
771 { |
|
772 LOG_MSG("->CCoreDumpSession::PluginRequestL()\n"); |
|
773 |
|
774 TPluginRequest request; |
|
775 TPtr8 pluginReqPtr((TUint8 *)&request, sizeof(TPluginRequest)); |
|
776 aMessage.ReadL(0, pluginReqPtr); |
|
777 |
|
778 if(request.iUid.iUid != 0) //(un)load a plugin |
|
779 { |
|
780 if(request.iPluginType == TPluginRequest::EFormatter) |
|
781 { |
|
782 if(request.iLoad) |
|
783 { |
|
784 CreateFormatterL(request.iUid); |
|
785 } |
|
786 else |
|
787 { |
|
788 //index mapping compatibility - one plugin at a time case |
|
789 TUint index = (request.iIndex == request.iPair) ? request.iIndex : 0; |
|
790 DeleteFormatterL(request.iUid, index); |
|
791 } |
|
792 } |
|
793 else if(request.iPluginType == TPluginRequest::EWriter) |
|
794 { |
|
795 if(request.iLoad) |
|
796 { |
|
797 CreateWriterL(request.iUid); |
|
798 } |
|
799 else |
|
800 { |
|
801 //index mapping compatibility - one plugin at a time case |
|
802 TUint index = (request.iIndex == request.iPair) ? request.iIndex : 0; |
|
803 DeleteWriterL(request.iUid, index); |
|
804 } |
|
805 } |
|
806 else |
|
807 { |
|
808 LOG_MSG2("CCoreDumpSession::PluginRequestL() - invalid plugin type:%d!\n", request.iPluginType); |
|
809 User::Leave(KErrNotSupported); |
|
810 } |
|
811 UpdateConfigParametersL(); |
|
812 } |
|
813 else //bind a plugin pair |
|
814 { |
|
815 BindPluginsL(request.iIndex, request.iPair); |
|
816 } |
|
817 } |
|
818 |
|
819 void CCoreDumpSession::BindPluginsL(const TUint aFormatterIndex, const TUint aWriterIndex) |
|
820 { |
|
821 LOG_MSG3("->CCoreDumpSession::BindPluginsL(fmt=%d, wrt=%d)\n", aFormatterIndex, aWriterIndex); |
|
822 if( (aFormatterIndex < iFormatterInfos.Count()) && (aWriterIndex < iWriterInfos.Count()) ) |
|
823 { |
|
824 iFormatterInfos[aFormatterIndex]->Pair(aWriterIndex); |
|
825 iFormatterPlugins[aFormatterIndex]->ConfigureDataSaveL(iWriterPlugins[aWriterIndex]); |
|
826 } |
|
827 else |
|
828 { |
|
829 LOG_MSG5("CCoreDumpSession::BindPluginsL -> fmtIndex:%d/%d wrtIndex:%d/%d\n", aFormatterIndex, iFormatterInfos.Count(), |
|
830 aWriterIndex, iWriterInfos.Count()); |
|
831 User::Leave(KErrNotFound); |
|
832 } |
|
833 } |
|
834 |
|
835 CCoreDumpFormatter* CCoreDumpSession::GetValidFormatter(const TUint aCount) |
|
836 { |
|
837 LOG_MSG2("->CCoreDumpSession::ValidFormatter(aCount=%d)", aCount); |
|
838 TUint counter = 0; |
|
839 |
|
840 for(TInt i = 0; i < iFormatterInfos.Count(); i++) |
|
841 { |
|
842 LOG_MSG3("CCoreDumpSession::ValidFormatter() - fmt[%d]->pair=%d", i, iFormatterInfos[i]->Pair()); |
|
843 if( (iFormatterInfos[i]->Pair() < iWriterInfos.Count()) && ( counter++ == aCount)) |
|
844 { |
|
845 LOG_MSG2("CCoreDumpSession::ValidFormatter() - found valid formatter=%d", iFormatterPlugins[i]); |
|
846 return iFormatterPlugins[i]; |
|
847 } |
|
848 } |
|
849 return NULL; |
|
850 } |
|
851 |
|
852 static void CleanupEComArray(TAny* aArray) |
|
853 { |
|
854 (static_cast<RImplInfoPtrArray*> (aArray))->ResetAndDestroy(); |
|
855 (static_cast<RImplInfoPtrArray*> (aArray))->Close(); |
|
856 } |
|
857 |
|
858 void CCoreDumpSession::RefreshPluginListL() |
|
859 { |
|
860 LOG_MSG("->CCoreDumpSession::RefreshPluginList()\n"); |
|
861 |
|
862 iPluginList.Close(); |
|
863 TPluginInfo ref; |
|
864 |
|
865 RImplInfoPtrArray infoArray; |
|
866 TCleanupItem cleanup(CleanupEComArray, &infoArray); |
|
867 CleanupStack::PushL(cleanup); |
|
868 |
|
869 CCoreDumpFormatter::ListAllImplementationsL( infoArray ); |
|
870 |
|
871 for ( TInt i = 0; i < infoArray.Count(); i++ ) |
|
872 { |
|
873 ref.iVersion = infoArray[i]->Version(); |
|
874 ref.iName = infoArray[i]->DisplayName(); |
|
875 ref.iUid = infoArray[i]->ImplementationUid(); |
|
876 ref.iType = TPluginRequest::EFormatter; |
|
877 |
|
878 ref.iLoaded = EFalse; //iLoaded on this list means we have an instance of that plugin |
|
879 for(TInt j = 0; j < iFormatterInfos.Count(); j++) |
|
880 { |
|
881 if(iFormatterInfos[j]->Uid() == ref.iUid.iUid) |
|
882 { |
|
883 ref.iLoaded = ETrue; |
|
884 break; |
|
885 } |
|
886 } |
|
887 |
|
888 iPluginList.AppendL(ref); |
|
889 } |
|
890 |
|
891 infoArray.ResetAndDestroy(); |
|
892 |
|
893 CCrashDataSave::ListAllImplementationsL( infoArray ); |
|
894 |
|
895 for ( TInt i = 0; i < infoArray.Count(); i++ ) |
|
896 { |
|
897 ref.iVersion = infoArray[i]->Version(); |
|
898 ref.iName = infoArray[i]->DisplayName(); |
|
899 ref.iUid = infoArray[i]->ImplementationUid(); |
|
900 ref.iType = TPluginRequest::EWriter; |
|
901 |
|
902 ref.iLoaded = EFalse; //iLoaded on this list means we have an instance of that plugin |
|
903 for(TInt j = 0; j < iWriterInfos.Count(); j++) |
|
904 { |
|
905 if(iWriterInfos[j]->Uid() == ref.iUid.iUid) |
|
906 { |
|
907 ref.iLoaded = ETrue; |
|
908 break; |
|
909 } |
|
910 } |
|
911 |
|
912 iPluginList.AppendL(ref); |
|
913 } |
|
914 |
|
915 CleanupStack::PopAndDestroy(); |
|
916 } |
|
917 |
|
918 void CCoreDumpSession::GetPluginListL(const RMessage2& aMessage) |
|
919 { |
|
920 //LOG_MSG("->CCoreDumpSession::GetPluginList()\n"); |
|
921 |
|
922 TListRequest listRequest; |
|
923 |
|
924 TPtr8 pluginReqPtr((TUint8 *)&listRequest, sizeof(TListRequest)); |
|
925 |
|
926 //read target debug app address and size from debug agent |
|
927 aMessage.ReadL(0, pluginReqPtr); |
|
928 |
|
929 TPluginInfoBlock * plugins = new (ELeave) TPluginInfoBlock; |
|
930 CleanupStack::PushL(plugins); |
|
931 |
|
932 if( 0 == listRequest.iIndex ) |
|
933 { |
|
934 iPluginList.Reset(); |
|
935 RefreshPluginListL(); |
|
936 } |
|
937 |
|
938 TUint toSupply = iPluginList.Count() - listRequest.iIndex; |
|
939 if ( toSupply > KNumPluginDetails ) |
|
940 { |
|
941 toSupply = KNumPluginDetails; |
|
942 } |
|
943 |
|
944 for( TUint index = 0; index < toSupply; index ++ ) |
|
945 { |
|
946 plugins->plugins[index].iVersion = iPluginList[index+listRequest.iIndex].iVersion; |
|
947 plugins->plugins[index].iName = iPluginList[index+listRequest.iIndex].iName; |
|
948 plugins->plugins[index].iDescription = iPluginList[index+listRequest.iIndex].iDescription; |
|
949 plugins->plugins[index].iUid = iPluginList[index+listRequest.iIndex].iUid; |
|
950 plugins->plugins[index].iType = iPluginList[index+listRequest.iIndex].iType; |
|
951 plugins->plugins[index].iLoaded = iPluginList[index+listRequest.iIndex].iLoaded; |
|
952 //RDebug::Print( _L(" loaded[%d]=%d\n"), index, plugins->plugins[index].iLoaded ); |
|
953 } |
|
954 |
|
955 listRequest.iSupplied = toSupply; |
|
956 listRequest.iRemaining = iPluginList.Count() - (listRequest.iIndex + listRequest.iSupplied); |
|
957 |
|
958 //RDebug::Print( _L(" supplying=%d, remaining=%d\n"), toSupply, listRequest.iRemaining ); |
|
959 |
|
960 aMessage.WriteL(0, pluginReqPtr); |
|
961 TPtr8 pluginArrPtr( (TUint8 *)plugins, sizeof(TPluginInfoBlock) ); |
|
962 pluginArrPtr.Set( (TUint8 *)plugins, sizeof(TPluginInfoBlock), sizeof(TPluginInfoBlock) ); |
|
963 |
|
964 aMessage.WriteL(1, pluginArrPtr); |
|
965 CleanupStack::PopAndDestroy(plugins); |
|
966 } |
|
967 |
|
968 void CCoreDumpSession::ObservationRequestL( const RMessage2& aMessage ) |
|
969 { |
|
970 //RDebug::Print(_L("->CCoreDumpSession::ObservationRequestL()\n")); |
|
971 TInt deslen; |
|
972 deslen = aMessage.GetDesLengthL(0); |
|
973 if (deslen == 0) |
|
974 { |
|
975 // Zero-length target name supplied |
|
976 User::Leave(KErrArgument); |
|
977 } |
|
978 |
|
979 RBuf targetName; |
|
980 targetName.CleanupClosePushL(); |
|
981 targetName.CreateL(deslen); |
|
982 // Read the target name into targetName |
|
983 aMessage.ReadL(0, targetName); |
|
984 |
|
985 deslen = aMessage.GetDesLengthL(1); |
|
986 if (deslen == 0) |
|
987 { |
|
988 // Zero-length target owner name supplied |
|
989 User::Leave(KErrArgument); |
|
990 } |
|
991 |
|
992 RBuf targetOwnerName; |
|
993 targetOwnerName.CleanupClosePushL(); |
|
994 targetOwnerName.CreateL(deslen); |
|
995 // Read the target owner name into targetOwnerName |
|
996 aMessage.ReadL(1, targetOwnerName); |
|
997 |
|
998 TBool observe = static_cast<TBool>(aMessage.Int2()); |
|
999 if(observe) |
|
1000 { |
|
1001 LOG_MSG("CCoreDumpSession::ObservationRequestL - KAttach\n" ); |
|
1002 AttachTargetL(targetName, targetOwnerName); |
|
1003 } |
|
1004 else |
|
1005 { |
|
1006 LOG_MSG("CCoreDumpSession::ObservationRequestL - KDetach\n"); |
|
1007 DetachTargetL(targetName, targetOwnerName); |
|
1008 } |
|
1009 |
|
1010 CleanupStack::PopAndDestroy(&targetOwnerName); |
|
1011 CleanupStack::PopAndDestroy(&targetName); |
|
1012 } |
|
1013 |
|
1014 void CCoreDumpSession::AttachTargetL( const TDesC &aTargetName, const TDesC &aTargetOwnerName ) |
|
1015 { |
|
1016 //LOG_MSG("->CoreDumpSession::AttachTargetL()\n"); |
|
1017 TBool found = EFalse; |
|
1018 |
|
1019 for(TInt i = 0; i < iObservationList.Count(); ++i) |
|
1020 { |
|
1021 if(iObservationList[i]->TargetName() == aTargetOwnerName) |
|
1022 { |
|
1023 if(aTargetName != aTargetOwnerName) //attach thread |
|
1024 { |
|
1025 iObservationList[i]->AddThreadL(aTargetName); |
|
1026 //LOG_MSG("CoreDumpSession::AttachTargetL - thread added\n"); |
|
1027 } |
|
1028 else |
|
1029 { |
|
1030 LOG_MSG("CoreDumpSession::AttachTargetL - process added\n"); |
|
1031 iObservationList[i]->ClearThreads(); |
|
1032 } |
|
1033 found = ETrue; |
|
1034 break; |
|
1035 } |
|
1036 } |
|
1037 |
|
1038 if(!found) |
|
1039 { |
|
1040 //RDebug::Printf( "CoreDumpSession::AttachTargetL - creating new observer", &aTargetOwnerName ); |
|
1041 CTargetObserver *observer = CTargetObserver::NewLC( iSecSess, *iCrashHandler, aTargetOwnerName ); |
|
1042 User::LeaveIfError( iObservationList.Insert(observer, 0) ); |
|
1043 |
|
1044 if(aTargetName != aTargetOwnerName) //attach thread |
|
1045 { |
|
1046 observer->AddThreadL(aTargetName); |
|
1047 //LOG_MSG("CoreDumpSession::AttachTargetL - thread added\n"); |
|
1048 } |
|
1049 |
|
1050 if( (iPreCrashEventAction & ESuspendThread) || |
|
1051 (iPreCrashEventAction & ESuspendProcess) ) |
|
1052 { |
|
1053 LOG_MSG("CCoreDumpSession::AttachTargetL() ->SetCrashEventsL(EActionSuspend)\n" ); |
|
1054 SetCrashEventsL(*observer, EActionSuspend); |
|
1055 } |
|
1056 else |
|
1057 { |
|
1058 LOG_MSG("CCoreDumpSession::AttachTargetL() ->SetCrashEventsL(EActionContinue)\n" ); |
|
1059 SetCrashEventsL(*observer, EActionContinue); |
|
1060 } |
|
1061 |
|
1062 observer->Observe(); |
|
1063 |
|
1064 //LOG_MSG("CoreDumpSession::AttachTargetL - observer started\n"); |
|
1065 CleanupStack::Pop(); //observer is now in the iObservationList |
|
1066 } |
|
1067 } |
|
1068 |
|
1069 void CCoreDumpSession::SetCrashEventsL(CTargetObserver &aObserver, TKernelEventAction aAction) |
|
1070 { |
|
1071 LOG_MSG2("CCoreDumpSession::SetCrashEventsL(aAction=%d)\n", aAction); |
|
1072 |
|
1073 if(iCrashEventTypes & ECrashHwExc) |
|
1074 { |
|
1075 LOG_MSG2(" aObserver.SetCrashEventL(EEventsHwExc, aAction=%d)\n", aAction); |
|
1076 aObserver.SetCrashEventL(EEventsHwExc, aAction); |
|
1077 } |
|
1078 else |
|
1079 { |
|
1080 LOG_MSG(" aObserver.SetCrashEventL(EEventsHwExc, EActionIgnore)\n"); |
|
1081 aObserver.SetCrashEventL(EEventsHwExc, EActionIgnore); |
|
1082 } |
|
1083 |
|
1084 if(iCrashEventTypes & ECrashKillThread) |
|
1085 { |
|
1086 LOG_MSG2(" aObserver.SetCrashEventL(EEventsKillThread, aAction=%d)\n", aAction); |
|
1087 aObserver.SetCrashEventL(EEventsKillThread, aAction); |
|
1088 } |
|
1089 else |
|
1090 { |
|
1091 LOG_MSG(" aObserver.SetCrashEventL(EEventsKillThread, EActionIgnore)\n"); |
|
1092 aObserver.SetCrashEventL(EEventsKillThread, EActionIgnore); |
|
1093 } |
|
1094 } |
|
1095 |
|
1096 void CCoreDumpSession::DetachTargetL( const TDesC &aTargetName, const TDesC &aTargetOwnerName ) |
|
1097 { |
|
1098 //LOG_MSG("->CoreDumpSession::DetachTargetL()\n"); |
|
1099 TBool found = EFalse; |
|
1100 |
|
1101 RBuf ton; |
|
1102 ton.CreateL(aTargetName); |
|
1103 char *tonp = (char*) ton.Collapse().PtrZ(); |
|
1104 LOG_MSG2("CCoreDumpSession::DetachTargetL(%s)\n", tonp); |
|
1105 ton.Close(); |
|
1106 |
|
1107 RBuf otn; |
|
1108 TInt count = iObservationList.Count(); |
|
1109 for(TInt i = 0; i < count; ++i) |
|
1110 { |
|
1111 otn.CreateL(iObservationList[i]->TargetName()); |
|
1112 char* otnp = (char*) otn.Collapse().PtrZ(); |
|
1113 LOG_MSG3("CCoreDumpSession::DetachTargetL - iObservationList[%d]->TargetName=%s\n", i, otnp); |
|
1114 otn.Close(); |
|
1115 if (iObservationList[i]->TargetName() == aTargetOwnerName) |
|
1116 { |
|
1117 if(aTargetName != aTargetOwnerName) //detach thread |
|
1118 { |
|
1119 iObservationList[i]->DelThreadL(aTargetName); |
|
1120 LOG_MSG("CoreDumpSession::DetachTargetL - thread removed\n"); |
|
1121 } |
|
1122 if(iObservationList[i]->ThreadCount() == 0) //no more threads to observe or detach process |
|
1123 { |
|
1124 LOG_MSG("CoreDumpSession::DetachTargetL - destroying observer\n"); |
|
1125 delete iObservationList[i]; |
|
1126 iObservationList.Remove(i); |
|
1127 } |
|
1128 found = ETrue; |
|
1129 break; |
|
1130 } |
|
1131 } |
|
1132 |
|
1133 if(!found) |
|
1134 { |
|
1135 LOG_MSG("CoreDumpSession::DetachTargetL - target not found\n"); |
|
1136 User::Leave(KErrNotFound); |
|
1137 } |
|
1138 } |
|
1139 |
|
1140 void CCoreDumpSession::UpdateConfigParametersL() |
|
1141 { |
|
1142 LOG_MSG( "->CCoreDumpSession::UpdateConfigParametersL()\n" ); |
|
1143 |
|
1144 COptionConfig *config = NULL; |
|
1145 iTotalConfigList.Reset(); |
|
1146 TUint configParamSize; |
|
1147 |
|
1148 TInt paramNum = iConfigList.Count(); |
|
1149 for(TInt i = 0; i < paramNum; i++ ) |
|
1150 { |
|
1151 config = iConfigList[i]; |
|
1152 |
|
1153 if(!config) |
|
1154 { |
|
1155 User::Leave(KErrBadHandle); |
|
1156 } |
|
1157 |
|
1158 configParamSize = config->Size(); |
|
1159 if(configParamSize > iMaxConfigParamSize) |
|
1160 { |
|
1161 iMaxConfigParamSize = configParamSize ; |
|
1162 } |
|
1163 iTotalConfigList.AppendL(config); |
|
1164 } |
|
1165 |
|
1166 |
|
1167 for(TInt i = 0; i < iFormatterPlugins.Count(); i++) |
|
1168 { |
|
1169 paramNum = iFormatterPlugins[i]->GetNumberConfigParametersL(); |
|
1170 for(TInt index = 0; index < paramNum; index++) |
|
1171 { |
|
1172 config = iFormatterPlugins[i]->GetConfigParameterL(index); |
|
1173 if(!config) |
|
1174 { |
|
1175 User::Leave(KErrBadHandle); |
|
1176 } |
|
1177 |
|
1178 configParamSize = config->Size(); |
|
1179 if(configParamSize > iMaxConfigParamSize) |
|
1180 { |
|
1181 iMaxConfigParamSize = configParamSize ; |
|
1182 } |
|
1183 |
|
1184 config->Instance(i); |
|
1185 iTotalConfigList.AppendL(config); |
|
1186 } |
|
1187 } |
|
1188 |
|
1189 for(TInt i = 0; i < iWriterPlugins.Count(); i++) |
|
1190 { |
|
1191 paramNum = iWriterPlugins[i]->GetNumberConfigParametersL(); |
|
1192 for(TInt index = 0; index < paramNum; index++) |
|
1193 { |
|
1194 config = iWriterPlugins[i]->GetConfigParameterL(index); |
|
1195 if(!config) |
|
1196 { |
|
1197 User::Leave(KErrBadHandle); |
|
1198 } |
|
1199 |
|
1200 configParamSize = config->Size(); |
|
1201 if(configParamSize > iMaxConfigParamSize) |
|
1202 { |
|
1203 iMaxConfigParamSize = configParamSize ; |
|
1204 } |
|
1205 |
|
1206 config->Instance(i); |
|
1207 iTotalConfigList.AppendL(config); |
|
1208 } |
|
1209 } |
|
1210 |
|
1211 |
|
1212 TRAPD(err, iFlashDataSource->ReadSCMConfigL(iScmConfigList)); |
|
1213 if(err != KErrNone) |
|
1214 { |
|
1215 LOG_MSG("Unable to retrieve config params for the SCM: [%d]"); |
|
1216 return; |
|
1217 } |
|
1218 |
|
1219 for(TInt i=0;i<iScmConfigList.Count();i++) |
|
1220 { |
|
1221 iTotalConfigList.AppendL(iScmConfigList[i]); |
|
1222 } |
|
1223 } |
|
1224 |
|
1225 /** |
|
1226 * This logs the current SCM Config to serial |
|
1227 */ |
|
1228 void CCoreDumpSession::PrintScmConfigL() |
|
1229 { |
|
1230 for(TInt i=0;i<iScmConfigList.Count();i++) |
|
1231 { |
|
1232 COptionConfig* optCon = iScmConfigList[i]; |
|
1233 LOG_DES(optCon->Prompt()); |
|
1234 LOG_MSG2("\t\tHas a value of %d", optCon->Value()); |
|
1235 } |
|
1236 } |
|
1237 |
|
1238 // Gather all conifg params from CDS, formatter and iWriter, |
|
1239 // collent into an array and set num to the number of configs avaliable |
|
1240 void CCoreDumpSession::GetNumberConfigParametersL( const RMessage2& aMessage ) |
|
1241 { |
|
1242 //LOG_MSG( "->CCoreDumpSession::GetNumberConfigParametersL()\n" ); |
|
1243 UpdateConfigParametersL( ); |
|
1244 |
|
1245 TInt numConfigParams = iTotalConfigList.Count(); |
|
1246 //LOG_MSG2( " numConfigParams=%d", numConfigParams ); |
|
1247 |
|
1248 TPtr8 numParamPtr( (TUint8 *) & numConfigParams, sizeof(TInt) ); |
|
1249 // Else it does not get passed back |
|
1250 numParamPtr.Set( (TUint8 *)& numConfigParams, sizeof(TInt), sizeof(TInt) ); |
|
1251 |
|
1252 TPtr8 maxParamSizePtr( (TUint8 *) & iMaxConfigParamSize, sizeof(TInt) ); |
|
1253 // Else it does not get passed back |
|
1254 maxParamSizePtr.Set( (TUint8 *)& iMaxConfigParamSize, sizeof(TInt), sizeof(TInt) ); |
|
1255 |
|
1256 /* |
|
1257 RDebug::Printf( " CCoreDumpSession::GetNumberConfigParameters(): iConfigList.Count()=%d, passing back nParams=%d, iMaxConfigParamSize=%d \n", |
|
1258 iConfigList.Count(), numConfigParams, iMaxConfigParamSize ); |
|
1259 */ |
|
1260 |
|
1261 aMessage.WriteL( 0, numParamPtr ); |
|
1262 |
|
1263 aMessage.WriteL( 1, maxParamSizePtr ); |
|
1264 } |
|
1265 |
|
1266 void CCoreDumpSession::GetConfigParameterL( const RMessage2& aMessage ) |
|
1267 { |
|
1268 // LOG_MSG( "->CCoreDumpSession::GetConfigParameterL()\n" ); |
|
1269 |
|
1270 |
|
1271 if( iTotalConfigList.Count() == 0 ) |
|
1272 { |
|
1273 // The user has never called GetNumberConfigParametersL(), |
|
1274 // so update the parameters first. |
|
1275 UpdateConfigParametersL( ); |
|
1276 } |
|
1277 |
|
1278 if( iTotalConfigList.Count() == 0 ) |
|
1279 { |
|
1280 RDebug::Printf( " ERROR !* : Have not gathered the configuration parameters\n" ); |
|
1281 User::Leave( KErrBadHandle ); |
|
1282 } |
|
1283 |
|
1284 TInt configIndex = aMessage.Int0(); |
|
1285 //RDebug::Printf( " configIndex=%d\n", configIndex ); |
|
1286 |
|
1287 if ( ( configIndex < 0 ) || ( configIndex >= iTotalConfigList.Count() ) ) |
|
1288 { |
|
1289 RDebug::Printf( " ERROR !* : config Index out of bounds\n" ); |
|
1290 User::Leave( KErrBadHandle ); |
|
1291 } |
|
1292 |
|
1293 COptionConfig * config = iTotalConfigList[configIndex]; |
|
1294 |
|
1295 HBufC8 * configDes = config->MarshalDataL(); |
|
1296 CleanupStack::PushL( configDes ); |
|
1297 |
|
1298 if ( configDes == NULL ) |
|
1299 { |
|
1300 RDebug::Printf( " ERROR !* MarshalData returned null buf\n" ); |
|
1301 User::Leave( KErrBadDescriptor ); |
|
1302 } |
|
1303 else |
|
1304 { |
|
1305 TPtr8 configPtr( configDes->Des() ); |
|
1306 if( configPtr.Size() == 0 ) |
|
1307 { |
|
1308 RDebug::Printf( " ERROR !* : if( configPtr.Size() == 0 )\n" ); |
|
1309 User::Leave( KErrBadDescriptor ); |
|
1310 } |
|
1311 |
|
1312 aMessage.WriteL( 1, configPtr ); |
|
1313 } |
|
1314 |
|
1315 CleanupStack::PopAndDestroy( configDes ); |
|
1316 } |
|
1317 |
|
1318 void CCoreDumpSession::SetConfigParameterL( const RMessage2& aMessage ) |
|
1319 { |
|
1320 LOG_MSG( "->CCoreDumpSession::SetConfigParameterL()\n" ); |
|
1321 |
|
1322 TConfigRequest configRequest; |
|
1323 |
|
1324 TPtr8 configReqPtr( (TUint8 *)&configRequest, sizeof(TConfigRequest) ); |
|
1325 aMessage.ReadL( 0, configReqPtr ); |
|
1326 |
|
1327 TInt32 value = aMessage.Int1(); |
|
1328 |
|
1329 HBufC *valueDesc = NULL; |
|
1330 TInt valueDesLen = aMessage.GetDesLength( 2 ); |
|
1331 if( valueDesLen > 0 ) |
|
1332 { |
|
1333 valueDesc = HBufC::NewL( valueDesLen ); |
|
1334 CleanupStack::PushL( valueDesc ); |
|
1335 TPtr ptr( valueDesc->Des() ); |
|
1336 aMessage.ReadL( 2, ptr ); |
|
1337 } |
|
1338 else |
|
1339 { |
|
1340 valueDesc = KNullDesC().AllocL(); |
|
1341 CleanupStack::PushL( valueDesc ); |
|
1342 } |
|
1343 |
|
1344 switch(configRequest.iSource) |
|
1345 { |
|
1346 case COptionConfig::ECoreDumpServer: |
|
1347 |
|
1348 SetConfigParameterL( configRequest.iIndex, value, *valueDesc ); |
|
1349 break; |
|
1350 |
|
1351 case COptionConfig::EFormatterPlugin: |
|
1352 { |
|
1353 if(configRequest.iInstance < iFormatterPlugins.Count()) |
|
1354 { |
|
1355 iFormatterPlugins[configRequest.iInstance]->SetConfigParameterL(configRequest.iIndex, value, *valueDesc); |
|
1356 break; |
|
1357 } |
|
1358 break; |
|
1359 } |
|
1360 case COptionConfig::EWriterPlugin: |
|
1361 { |
|
1362 if(configRequest.iInstance < iWriterPlugins.Count()) |
|
1363 { |
|
1364 iWriterPlugins[configRequest.iInstance]->SetConfigParameterL(configRequest.iIndex, value, *valueDesc); |
|
1365 break; |
|
1366 } |
|
1367 break; |
|
1368 } |
|
1369 case COptionConfig::ESCMConfig: |
|
1370 { |
|
1371 |
|
1372 LOG_MSG4("(CCoreDumpSession::SetConfigParameterL) Updating config param instance %d value %d index =%d" |
|
1373 , configRequest.iInstance , value, configRequest.iIndex); |
|
1374 iFlashDataSource->ModifySCMConfigItemL(configRequest.iInstance, value); |
|
1375 break; |
|
1376 } |
|
1377 |
|
1378 default: |
|
1379 User::Leave(KErrArgument); |
|
1380 } |
|
1381 |
|
1382 CleanupStack::PopAndDestroy( valueDesc ); |
|
1383 } |
|
1384 |
|
1385 |
|
1386 TInt32 CCoreDumpSession::PreProcessingAction() const |
|
1387 { |
|
1388 return iConfigList[EPreCrashEventAction]->Value(); |
|
1389 } |
|
1390 |
|
1391 TInt32 CCoreDumpSession::PostProcessingAction() const |
|
1392 { |
|
1393 return iConfigList[EPostCrashEventAction]->Value(); |
|
1394 } |
|
1395 |
|
1396 void CCoreDumpSession::SetConfigParameterL( const TInt aIndex, |
|
1397 const TInt32 & aValue, |
|
1398 const TDesC & aDescValue ) |
|
1399 { |
|
1400 LOG_MSG3( "->CCoreDumpSession::SetConfigParameterL( aIndex=%d, aValue=0x%X )\n", aIndex, aValue ); |
|
1401 |
|
1402 if ( ( aIndex < 0 ) || ( aIndex >= iConfigList.Count() ) ) |
|
1403 { |
|
1404 LOG_MSG2( " ERROR !* : config Index out of bounds, max=%d\n", iConfigList.Count() - 1 ); |
|
1405 User::Leave( KErrBadHandle ); |
|
1406 } |
|
1407 |
|
1408 //Match the parameter passed in to one of our own parameters via the index |
|
1409 COptionConfig &config = *iConfigList[aIndex]; |
|
1410 |
|
1411 if( config.Index() != aIndex ) |
|
1412 { |
|
1413 RDebug::Printf( " ERROR !* : config Index %d does not match internal index %d\n", aIndex, config.Index() ); |
|
1414 User::Leave( KErrBadHandle ); |
|
1415 } |
|
1416 |
|
1417 if( aIndex == (TInt)EPreCrashEventAction ) |
|
1418 { |
|
1419 switch( aValue ) |
|
1420 { |
|
1421 case ENoPreAction: |
|
1422 case ESuspendThread: |
|
1423 case ESuspendProcess: |
|
1424 |
|
1425 LOG_MSG2(" Changing EPreCrashEventAction to =%d\n", aValue ); |
|
1426 |
|
1427 iPreCrashEventAction = aValue; |
|
1428 |
|
1429 for(TInt i = 0; i < iObservationList.Count(); i++) |
|
1430 { |
|
1431 if( (iPreCrashEventAction & ESuspendThread) || |
|
1432 (iPreCrashEventAction & ESuspendProcess) ) |
|
1433 { |
|
1434 LOG_MSG2(" SetCrashEventsL(*iObservationList[%d], EActionSuspend)\n", i ); |
|
1435 SetCrashEventsL(*iObservationList[i], EActionSuspend); |
|
1436 } |
|
1437 else |
|
1438 { |
|
1439 LOG_MSG2(" SetCrashEventsL(*iObservationList[%d], EActionContinue);\n", i ); |
|
1440 SetCrashEventsL(*iObservationList[i], EActionContinue); |
|
1441 } |
|
1442 } |
|
1443 |
|
1444 break; |
|
1445 default: |
|
1446 RDebug::Printf(" ERROR !* EPreCrashEventAction cannot be %d\n", aValue ); |
|
1447 User::Leave(KErrArgument); |
|
1448 } |
|
1449 } |
|
1450 else if( aIndex == (TInt)EPostCrashEventAction ) |
|
1451 { |
|
1452 switch( aValue ) |
|
1453 { |
|
1454 case ENoPostAction: |
|
1455 case EResumeThread: |
|
1456 case EResumeProcess: |
|
1457 case EKillProcess: |
|
1458 iPostCrashEventAction = aValue; |
|
1459 break; |
|
1460 default: |
|
1461 RDebug::Printf(" ERROR !* EPostCrashEventAction cannot be %d\n", aValue ); |
|
1462 User::Leave(KErrArgument); |
|
1463 } |
|
1464 } |
|
1465 else if( aIndex == (TInt)ECrashEventTypes ) |
|
1466 { |
|
1467 switch( aValue ) |
|
1468 { |
|
1469 case ECrashHwExc: |
|
1470 case ECrashKillThread: |
|
1471 case ECrashHwExcAndKillThread: |
|
1472 |
|
1473 LOG_MSG2(" Changing trigger ECrashEventTypes to =%d\n", aValue ); |
|
1474 iCrashEventTypes = aValue; |
|
1475 |
|
1476 for(TInt i = 0; i < iObservationList.Count(); i++) |
|
1477 { |
|
1478 if( (iPreCrashEventAction & ESuspendThread) || |
|
1479 (iPreCrashEventAction & ESuspendProcess) ) |
|
1480 SetCrashEventsL(*iObservationList[i], EActionSuspend); |
|
1481 else |
|
1482 SetCrashEventsL(*iObservationList[i], EActionContinue); |
|
1483 } |
|
1484 |
|
1485 break; |
|
1486 default: |
|
1487 RDebug::Printf( " ERROR !* ECrashEventTypes cannot be %d\n", aValue ); |
|
1488 User::Leave(KErrArgument); |
|
1489 } |
|
1490 } |
|
1491 else |
|
1492 { |
|
1493 RDebug::Printf( |
|
1494 "CCoreDumpSession::SetConfigParameterL() : parameter with index %d does is not valid\n", |
|
1495 aIndex ); |
|
1496 User::Leave(KErrArgument); |
|
1497 } |
|
1498 |
|
1499 // Change our internal values |
|
1500 config.Value( aValue ); |
|
1501 //LOG_MSG( " config->ValueL( aDescValue )\n" ); |
|
1502 config.ValueL( aDescValue ); |
|
1503 |
|
1504 } |
|
1505 |
|
1506 |
|
1507 |
|
1508 /** |
|
1509 Save one parameter for a specific section. |
|
1510 @param aParam COptionConfig pointer to save |
|
1511 @param aSectName Section name in the file to save this parameter to |
|
1512 @param aSaveIndex This parameter is only used to create key strings that are unique. |
|
1513 @param aPersistConfigData Object used to save the configuration to. |
|
1514 */ |
|
1515 void CCoreDumpSession::SaveConfigParamL( const COptionConfig * aParam, |
|
1516 const TPtrC & aSectName, |
|
1517 const TInt aSaveIndex, |
|
1518 CIniDocument16 * aPersistConfigData ) |
|
1519 { |
|
1520 |
|
1521 LOG_MSG2( "CCoreDumpSession::SaveConfigParamL( aSaveIndex=%d )\n", aSaveIndex ); |
|
1522 |
|
1523 HBufC * iniStringKey; |
|
1524 TInt err; |
|
1525 |
|
1526 // Save the Configuration Parameter Value |
|
1527 { |
|
1528 iniStringKey = GenerateKeyStringLC( aSaveIndex, EIniKeyValue ); |
|
1529 TInt keyIntValue = aParam->Value(); |
|
1530 |
|
1531 // Size of character buffer required to represent a 32bit |
|
1532 // interger as decimal should be 10. |
|
1533 TBuf<16> intValueBuf; |
|
1534 |
|
1535 switch( aParam->Type() ) |
|
1536 { |
|
1537 case COptionConfig::ETInt: |
|
1538 case COptionConfig::ETUInt: |
|
1539 case COptionConfig::ETBool: |
|
1540 |
|
1541 LOG_MSG2( " -> SetKey( int value=%d)\n", keyIntValue ); |
|
1542 intValueBuf.AppendNum( keyIntValue ); |
|
1543 err = aPersistConfigData->SetKey( aSectName, iniStringKey->Des(), intValueBuf ); |
|
1544 |
|
1545 /* |
|
1546 const TDesC & paramV = intValueBuf; |
|
1547 RBuf valueV; |
|
1548 valueV.Create( paramV ); |
|
1549 char* cl = (char*) valueV.Collapse().PtrZ(); |
|
1550 RDebug::Printf(" saving integer value=%s\n", cl ); |
|
1551 */ |
|
1552 |
|
1553 break; |
|
1554 |
|
1555 case COptionConfig::ETString: |
|
1556 case COptionConfig::ETFileName: |
|
1557 case COptionConfig::ETMultiEntryEnum: |
|
1558 case COptionConfig::ETSingleEntryEnum: |
|
1559 { |
|
1560 const TDesC & paramValue = aParam->ValueAsDesc(); |
|
1561 |
|
1562 if( paramValue == KNullDesC ) |
|
1563 { |
|
1564 LOG_MSG( " Cannot save parameter value that is NULL\n" ); |
|
1565 CleanupStack::PopAndDestroy( iniStringKey ); |
|
1566 return; |
|
1567 } |
|
1568 /* |
|
1569 RBuf value; |
|
1570 value.Create( paramValue ); |
|
1571 char* cl = (char*) value.Collapse().PtrZ(); |
|
1572 RDebug::Printf(" saving string value=%s\n", cl ); |
|
1573 */ |
|
1574 |
|
1575 LOG_MSG( " -> SetKey( string value )\n" ); |
|
1576 err = aPersistConfigData->SetKey( aSectName, iniStringKey->Des(), paramValue ); |
|
1577 } |
|
1578 break; |
|
1579 default: |
|
1580 { |
|
1581 // unknown type, Leave since the file could be corrupt or malformed |
|
1582 LOG_MSG2( " Invalid COptionConfig parameter type %d\n", aParam->Type() ); |
|
1583 CleanupStack::PopAndDestroy( iniStringKey ); |
|
1584 User::Leave( KErrCorrupt ); |
|
1585 } |
|
1586 }// switch (COptionConfig::TOptionType) |
|
1587 |
|
1588 LOG_MSG( " CleanupStack::PopAndDestroy( iniStringKey )" ); |
|
1589 CleanupStack::PopAndDestroy( iniStringKey ); |
|
1590 } |
|
1591 |
|
1592 |
|
1593 |
|
1594 // Save the Configuration Parameter Index |
|
1595 { |
|
1596 iniStringKey = GenerateKeyStringLC( aSaveIndex, EIniKeyIndex ); |
|
1597 |
|
1598 TInt keyIndex = aParam->Index(); |
|
1599 TBuf<4> intIndexBuf; |
|
1600 LOG_MSG3( " -> keyIndex%d = parameter index %d\n", aSaveIndex, keyIndex ); |
|
1601 intIndexBuf.AppendNum( keyIndex ); |
|
1602 |
|
1603 err = aPersistConfigData->SetKey( aSectName, iniStringKey->Des(), intIndexBuf ); |
|
1604 |
|
1605 CleanupStack::PopAndDestroy( iniStringKey ); |
|
1606 |
|
1607 if( KErrNone != err ) |
|
1608 { |
|
1609 LOG_MSG2( " ERROR !* aPersistConfigData->AddValue() returned %d\n", err ); |
|
1610 } |
|
1611 User::LeaveIfError( err ); |
|
1612 } |
|
1613 |
|
1614 |
|
1615 // Save the Configuration Parameter Type |
|
1616 { |
|
1617 iniStringKey = GenerateKeyStringLC( aSaveIndex, EIniKeyType ); |
|
1618 |
|
1619 TInt keyType = aParam->Type(); |
|
1620 TBuf<8> intTypeBuf; |
|
1621 LOG_MSG3( " -> KeyType%d = parameter type %d\n", aSaveIndex, keyType ); |
|
1622 intTypeBuf.AppendNum( keyType ); |
|
1623 |
|
1624 err = aPersistConfigData->SetKey( aSectName, iniStringKey->Des(), intTypeBuf ); |
|
1625 |
|
1626 CleanupStack::PopAndDestroy( iniStringKey ); |
|
1627 if( KErrNone != err ) |
|
1628 { |
|
1629 LOG_MSG2( " ERROR !* aPersistConfigData->AddValue() returned %d\n", err ); |
|
1630 } |
|
1631 User::LeaveIfError( err ); |
|
1632 } |
|
1633 } |
|
1634 |
|
1635 |
|
1636 |
|
1637 _LIT( KPluginExtension, ".plugin" ); |
|
1638 #define KPluginUIDCharsPerLine 8 |
|
1639 |
|
1640 |
|
1641 _LIT( KCDSConfig, "CoreDumpServerConfiguration" ); |
|
1642 _LIT( KWriterConfig, "WriterConfiguration" ); |
|
1643 _LIT( KFormatterConfig, "FormatterConfiguration" ); |
|
1644 _LIT( KObservedConfig, "ObservedConfiguration" ); |
|
1645 |
|
1646 _LIT( KDefaultIniFile, "coredumpserver.ini" ); |
|
1647 _LIT( KUID, "UID" ); |
|
1648 _LIT( KPluginPair, "Pair" ); |
|
1649 |
|
1650 |
|
1651 |
|
1652 |
|
1653 |
|
1654 /** |
|
1655 Method to parse the set of files that contain the UIDs of the allowed plugins. |
|
1656 The files are read our private directory in all drives. Thus installed .plugin |
|
1657 files are also checked. |
|
1658 |
|
1659 The plugin files must have the extension ".plugin". The content must be in |
|
1660 ASCII-8. The format must be one UID per line, with no empty lines. |
|
1661 The EOL can be CR+LF or just CR. |
|
1662 */ |
|
1663 void CCoreDumpSession::ReadPluginUidFilesL( ) |
|
1664 { |
|
1665 |
|
1666 RFs fsSession; |
|
1667 CleanupClosePushL( fsSession ); |
|
1668 User::LeaveIfError( fsSession.Connect() ); |
|
1669 |
|
1670 //RProcess thisProc; |
|
1671 |
|
1672 TDriveList driveList; |
|
1673 TVolumeInfo volInfo; |
|
1674 |
|
1675 User::LeaveIfError( fsSession.DriveList( driveList ) ); |
|
1676 |
|
1677 HBufC* sessionPath = HBufC::NewLC( KMaxFileName ); |
|
1678 TPtr privPath( sessionPath->Des() ); |
|
1679 |
|
1680 RBuf8 allowedPluginUidStr; |
|
1681 allowedPluginUidStr.CleanupClosePushL(); |
|
1682 allowedPluginUidStr.CreateL( KPluginUIDCharsPerLine ); |
|
1683 |
|
1684 RFile pluginFile; |
|
1685 CleanupClosePushL( pluginFile ); |
|
1686 |
|
1687 for( TInt driveNumber = EDriveA; driveNumber <= EDriveZ; driveNumber++ ) |
|
1688 { |
|
1689 if( ( !driveList[driveNumber] ) || |
|
1690 ( KErrNone != fsSession.Volume( volInfo, driveNumber) ) || |
|
1691 ( volInfo.iDrive.iType==EMediaNotPresent ) ) |
|
1692 { |
|
1693 continue; |
|
1694 } |
|
1695 |
|
1696 // Get a list of the files in the private directory of drive <driveNumber> |
|
1697 |
|
1698 fsSession.SetSessionToPrivate( driveNumber ); |
|
1699 User::LeaveIfError( fsSession.SessionPath( privPath ) ); |
|
1700 CDir * fileList = NULL; |
|
1701 |
|
1702 // KEntryAttNormal gets only files (not dirs, hidden or system files) |
|
1703 TInt ret = fsSession.GetDir( privPath, KEntryAttNormal, ESortByName, fileList ); |
|
1704 if( ( KErrNone != ret ) || ( !fileList ) ) |
|
1705 { |
|
1706 if( fileList ) |
|
1707 delete fileList; |
|
1708 continue; |
|
1709 } |
|
1710 |
|
1711 CleanupStack::PushL( fileList ); |
|
1712 |
|
1713 for( TInt i = 0; i < fileList->Count(); i++ ) |
|
1714 { |
|
1715 TEntry fileEntry = (*fileList)[i]; |
|
1716 TParse fileNameParser; |
|
1717 fileNameParser.Set( fileEntry.iName, NULL, NULL ); |
|
1718 if( fileNameParser.Ext() != KPluginExtension ) |
|
1719 { |
|
1720 continue; |
|
1721 } |
|
1722 |
|
1723 /* |
|
1724 RBuf8 pluginFilePrint; |
|
1725 pluginFilePrint.CreateL( fileEntry.iName.Length() + 1 ); |
|
1726 pluginFilePrint.Copy( fileEntry.iName ); |
|
1727 char* cl = (char*) pluginFilePrint.PtrZ(); |
|
1728 LOG_MSG2(" Reading .plugin file %s\n", cl ); |
|
1729 */ |
|
1730 |
|
1731 // File extension is .plugin, so add the list of UIDs contained inside |
|
1732 // the file to our list of allowed plugins |
|
1733 // |
|
1734 ret = pluginFile.Open( fsSession, fileEntry.iName, EFileRead ); |
|
1735 if( KErrNone != ret ) |
|
1736 { |
|
1737 LOG_MSG(" Error openning file. Ignoring this file\n" ); |
|
1738 continue; |
|
1739 } |
|
1740 |
|
1741 while( KErrNone == ret ) |
|
1742 { |
|
1743 // Read the UID characters on a line. Exactly 8 * 1 byte non-UNICODE chars per line |
|
1744 ret = pluginFile.Read( allowedPluginUidStr, KPluginUIDCharsPerLine ); |
|
1745 if( ( KErrNone != ret ) || (allowedPluginUidStr.Length() != KPluginUIDCharsPerLine ) ) |
|
1746 { |
|
1747 // Reached the end of file, so go to the next file |
|
1748 break; |
|
1749 } |
|
1750 |
|
1751 TLex8 uidLex( allowedPluginUidStr ); |
|
1752 TUint pluginUidValue = 0; |
|
1753 uidLex.Val( pluginUidValue, EHex ); |
|
1754 TUid allowedUid = TUid::Uid( pluginUidValue ); |
|
1755 iAllowedPlugins.AppendL( allowedUid ); |
|
1756 |
|
1757 // Now skip the end of line character/s CR 0x0D and possibly LF 0x0A |
|
1758 ret = pluginFile.Read( allowedPluginUidStr, 1 ); |
|
1759 if( ( KErrNone == ret ) && (allowedPluginUidStr.Length() == 1) ) |
|
1760 { |
|
1761 //Could have read the CR or LF |
|
1762 if( 0x0D == *(allowedPluginUidStr.Ptr()) ) |
|
1763 { |
|
1764 // CR should be followed by LF, so read that too |
|
1765 ret = pluginFile.Read( allowedPluginUidStr, 1 ); |
|
1766 } |
|
1767 } |
|
1768 |
|
1769 if( allowedPluginUidStr.Length() == 0 ) |
|
1770 { |
|
1771 ret = KErrEof; |
|
1772 } |
|
1773 |
|
1774 } // while have read 8 bytes |
|
1775 |
|
1776 pluginFile.Close(); |
|
1777 } // for each file in file list |
|
1778 |
|
1779 CleanupStack::PopAndDestroy( fileList ); |
|
1780 } |
|
1781 |
|
1782 CleanupStack::PopAndDestroy( &pluginFile ); |
|
1783 CleanupStack::PopAndDestroy( &allowedPluginUidStr ); |
|
1784 CleanupStack::PopAndDestroy( sessionPath ); |
|
1785 CleanupStack::PopAndDestroy( &fsSession ); |
|
1786 |
|
1787 if( 0 == iAllowedPlugins.Count() ) |
|
1788 { |
|
1789 LOG_MSG( " Warning : No plugins will be allowed\n" ); |
|
1790 } |
|
1791 else |
|
1792 { |
|
1793 for( TInt i=0; i < iAllowedPlugins.Count(); i++ ) |
|
1794 { |
|
1795 LOG_MSG2( " Plugin 0x%X allowed\n", iAllowedPlugins[i] ); |
|
1796 } |
|
1797 } |
|
1798 |
|
1799 } |
|
1800 |
|
1801 void CCoreDumpSession::ValidatePluginL( const TUid aPluginUid ) const |
|
1802 { |
|
1803 |
|
1804 LOG_MSG2( "->CCoreDumpSession::ValidatePlugin(aPluginId=0x%X)\n", aPluginUid.iUid ); |
|
1805 |
|
1806 for( TInt i = 0; i < iAllowedPlugins.Count(); i++ ) |
|
1807 { |
|
1808 if( iAllowedPlugins[i] == aPluginUid ) |
|
1809 { |
|
1810 LOG_MSG( " Plugin Allowed\n" ); |
|
1811 return; |
|
1812 } |
|
1813 } |
|
1814 LOG_MSG( " Plugin Not Allowed\n" ); |
|
1815 User::Leave(KErrPermissionDenied); |
|
1816 } |
|
1817 |
|
1818 /** |
|
1819 @pre aFsSession FileSystem session must have been connected to and still be active |
|
1820 @post aFileName and aPersistConfigData pushed onto the stack |
|
1821 */ |
|
1822 void CCoreDumpSession::OpenIniFileLC( const RMessage2 * aMessage, |
|
1823 const TBool aSaving, |
|
1824 RFs & aFsSession, |
|
1825 HBufC *& aFileName, |
|
1826 CIniDocument16 *& aPersistConfigData ) |
|
1827 { |
|
1828 |
|
1829 |
|
1830 LOG_MSG( "CCoreDumpSession::OpenIniFileLC(RMessage2)\n" ); |
|
1831 |
|
1832 TInt ret; |
|
1833 |
|
1834 TInt iniFileDesLen = 0; |
|
1835 |
|
1836 if( aMessage ) |
|
1837 { |
|
1838 LOG_MSG( " RMessage2 != NULL\n" ); |
|
1839 iniFileDesLen = aMessage->GetDesLength( 0 ); |
|
1840 if( iniFileDesLen > 0 ) |
|
1841 { |
|
1842 //LOG_MSG( " User supplied ini file name\n" ); |
|
1843 aFileName = HBufC::NewL( iniFileDesLen ); |
|
1844 |
|
1845 //LOG_MSG( " CleanupStack::PushL( aFileName )\n" ); |
|
1846 CleanupStack::PushL( aFileName ); |
|
1847 |
|
1848 TPtr ptr( aFileName->Des() ); |
|
1849 aMessage->ReadL( 0, ptr ); |
|
1850 if( !aSaving && !aFsSession.IsValidName( ptr ) ) |
|
1851 { |
|
1852 // If we are loading and the file and path are incorrect |
|
1853 //LOG_MSG( " IsValidName() == EFalse\n" ); |
|
1854 User::Leave( KErrPathNotFound ); |
|
1855 } |
|
1856 } |
|
1857 } |
|
1858 |
|
1859 if( 0 == iniFileDesLen ) |
|
1860 { |
|
1861 aFsSession.SetSessionToPrivate( EDriveE ); |
|
1862 |
|
1863 RBuf privPath; |
|
1864 privPath.CleanupClosePushL(); |
|
1865 privPath.CreateL( KMaxFileName ); |
|
1866 |
|
1867 aFsSession.SessionPath( privPath ); |
|
1868 |
|
1869 privPath.Append( KDefaultIniFile ); |
|
1870 aFileName = HBufC::NewL( privPath.Length() ); |
|
1871 *aFileName = privPath;// Copy name |
|
1872 |
|
1873 CleanupStack::PopAndDestroy( &privPath ); |
|
1874 |
|
1875 CleanupStack::PushL( aFileName ); |
|
1876 |
|
1877 if( aSaving ) |
|
1878 { |
|
1879 //LOG_MSG( " aFsSession.CreatePrivatePath( EDriveE )\n" ); |
|
1880 ret = aFsSession.CreatePrivatePath( EDriveE ); |
|
1881 if( ( KErrNone != ret ) && ( KErrAlreadyExists != ret ) ) |
|
1882 { |
|
1883 LOG_MSG2( " aFsSession.CreatePrivatePath( EDriveE ) returned ERROR %d\n", ret ); |
|
1884 User::Leave( ret ); |
|
1885 } |
|
1886 } |
|
1887 } |
|
1888 |
|
1889 if( aSaving ) |
|
1890 { |
|
1891 // delete existing file since CIniDocument16::NewL expects a correctly formed |
|
1892 // file or no file at all. An empty file makes the NewL Leave |
|
1893 // |
|
1894 //LOG_MSG( " -> aFsSession.Delete( aFileName->Des() )\n"); |
|
1895 aFsSession.Delete( aFileName->Des() ); |
|
1896 } |
|
1897 else |
|
1898 { |
|
1899 TEntry entry; |
|
1900 User::LeaveIfError(aFsSession.Entry(aFileName->Des(), entry)); |
|
1901 } |
|
1902 //LOG_MSG( " ->CIniDocument16::NewL( aFsSession, aFileName->Des() )\n"); |
|
1903 TRAPD(err, aPersistConfigData = CIniDocument16::NewL( aFsSession, aFileName->Des() )); |
|
1904 |
|
1905 if( KErrNone != err ) |
|
1906 { |
|
1907 LOG_MSG2( " <- CIniDocument16::NewL( ) left with %d\n", err ); |
|
1908 } |
|
1909 |
|
1910 CleanupStack::PushL( aPersistConfigData ); |
|
1911 } |
|
1912 |
|
1913 |
|
1914 |
|
1915 _LIT( KIniFileCommentTitle, "CoreDumpServerSettingsFile" ); |
|
1916 _LIT( KIniFileCommentSymbian, "Symbian_Software_Ltd" ); |
|
1917 _LIT( KIniFileCommentSymbianYear, "2007" ); |
|
1918 _LIT( KIniFileCommentVersionString, "Version" ); |
|
1919 _LIT( KIniFileCommentVersionNumber, "1.0.0" ); |
|
1920 |
|
1921 |
|
1922 /* |
|
1923 * Client request to load system configuration file |
|
1924 */ |
|
1925 void CCoreDumpSession::SaveConfigFileL( const RMessage2* aMessage ) |
|
1926 { |
|
1927 |
|
1928 LOG_MSG( "CCoreDumpSession::SaveConfigFileL(RMessage2)\n"); |
|
1929 |
|
1930 RFs fsSession; |
|
1931 CleanupClosePushL( fsSession ); |
|
1932 User::LeaveIfError( fsSession.Connect() ); |
|
1933 |
|
1934 |
|
1935 HBufC * fileName = NULL; |
|
1936 CIniDocument16 * persistConfigData = NULL; |
|
1937 |
|
1938 OpenIniFileLC( aMessage, ETrue, fsSession, fileName, persistConfigData ); |
|
1939 |
|
1940 // persistConfigData is on top of the stack, and under it is fileName |
|
1941 |
|
1942 TInt ret; |
|
1943 TPtrC uidString; |
|
1944 uidString.Set( KUID ); |
|
1945 TPtrC sectName; |
|
1946 |
|
1947 sectName.Set( KIniFileCommentTitle ); |
|
1948 ret = persistConfigData->AddSection( sectName ); |
|
1949 User::LeaveIfError( ret ); |
|
1950 |
|
1951 ret = persistConfigData->SetKey( sectName, KIniFileCommentSymbian, KIniFileCommentSymbianYear ); |
|
1952 User::LeaveIfError( ret ); |
|
1953 |
|
1954 ret = persistConfigData->SetKey( sectName, KIniFileCommentVersionString, KIniFileCommentVersionNumber ); |
|
1955 User::LeaveIfError( ret ); |
|
1956 |
|
1957 |
|
1958 sectName.Set( KCDSConfig ); |
|
1959 //LOG_MSG( " persistConfigData->AddSection( KCDSConfig )\n" ); |
|
1960 ret = persistConfigData->AddSection( sectName ); |
|
1961 //LOG_MSG2( " AddSection( KCDSConfig ) returned %d", ret ); |
|
1962 User::LeaveIfError( ret ); |
|
1963 |
|
1964 RBuf cdsUidNumberString; |
|
1965 cdsUidNumberString.CleanupClosePushL(); |
|
1966 cdsUidNumberString.CreateL( 8 ); |
|
1967 cdsUidNumberString.AppendNumFixedWidth( (TUint)iOurSecureID.iUid, EHex, 8 ); // Width = 8 chars |
|
1968 |
|
1969 //LOG_MSG( " persistConfigData->SetKey( KCDSConfig, uidString, cdsUidNumberString )\n" ); |
|
1970 ret = persistConfigData->SetKey( sectName, uidString, cdsUidNumberString ); |
|
1971 User::LeaveIfError( ret ); |
|
1972 |
|
1973 for( TInt i = 0; i < iConfigList.Count(); i++ ) |
|
1974 { |
|
1975 SaveConfigParamL( iConfigList[i], sectName, i, persistConfigData ); |
|
1976 } |
|
1977 CleanupStack::PopAndDestroy(&cdsUidNumberString); |
|
1978 |
|
1979 if( iObservationList.Count() > 0 ) |
|
1980 { |
|
1981 |
|
1982 //LOG_MSG( " Saving Observed section\n"); |
|
1983 |
|
1984 // There is no point in saving the id of a thread since the id is not predictable |
|
1985 // and could be used in another boot session. Thus only save the names |
|
1986 // EIniKeyValue holds Target Name EIniKeyType holds TargetOwnerName |
|
1987 // Thus a process will have both the same, so we can differentiate them |
|
1988 HBufC * iniStringTargetValue; |
|
1989 HBufC * iniStringOwnerType; |
|
1990 |
|
1991 TPtrC observationSection; |
|
1992 observationSection.Set( KObservedConfig ); |
|
1993 //LOG_MSG( " persistConfigData->AddSection( KObservedConfig )\n" ); |
|
1994 ret = persistConfigData->AddSection( observationSection ); |
|
1995 User::LeaveIfError( ret ); |
|
1996 |
|
1997 TInt observeKey = 0; |
|
1998 |
|
1999 for( TInt i = 0; i < iObservationList.Count(); i ++ ) |
|
2000 { |
|
2001 CTargetObserver *observer = iObservationList[i]; |
|
2002 TInt count = observer->ThreadCount(); |
|
2003 TInt j = 0; |
|
2004 do |
|
2005 { |
|
2006 // Key string for target name |
|
2007 iniStringTargetValue = GenerateKeyStringLC( observeKey, EIniKeyValue ); |
|
2008 TPtrC targetName; |
|
2009 if(count == 0) //whole process, no threads on list => targetName == targetOwnerName |
|
2010 { |
|
2011 targetName.Set(observer->TargetName()); |
|
2012 } |
|
2013 else |
|
2014 { |
|
2015 targetName.Set(observer->Thread(j)); |
|
2016 } |
|
2017 |
|
2018 //LOG_MSG2( " iPersistConfigData->SetKey( KObservedConfig, target.Length()=%d )\n", targetName.Length() ); |
|
2019 ret = persistConfigData->SetKey( observationSection, |
|
2020 iniStringTargetValue->Des(), |
|
2021 targetName ); |
|
2022 |
|
2023 CleanupStack::PopAndDestroy( iniStringTargetValue ); |
|
2024 if( KErrNone != ret ) |
|
2025 { |
|
2026 LOG_MSG2( " ERROR !* iPersistConfigData->AddValue() for observed target returned %d\n", ret ); |
|
2027 User::Leave( ret ); |
|
2028 } |
|
2029 |
|
2030 // Key string for target owner name |
|
2031 iniStringOwnerType = GenerateKeyStringLC( observeKey, EIniKeyType ); |
|
2032 TPtrC targetOwnerName( observer->TargetName() ); |
|
2033 |
|
2034 LOG_MSG2( " iPersistConfigData->SetKey( KObservedConfig, targetOwner.Length()=%d )\n", targetOwnerName.Length() ); |
|
2035 ret = persistConfigData->SetKey( observationSection, |
|
2036 iniStringOwnerType->Des(), |
|
2037 targetOwnerName ); |
|
2038 |
|
2039 CleanupStack::PopAndDestroy( iniStringOwnerType ); |
|
2040 if( KErrNone != ret ) |
|
2041 { |
|
2042 LOG_MSG2( " ERROR !* iPersistConfigData->AddValue() for observed target owner returned %d\n", ret ); |
|
2043 User::Leave( ret ); |
|
2044 } |
|
2045 |
|
2046 j++; |
|
2047 observeKey ++; |
|
2048 |
|
2049 } while(j < count); |
|
2050 |
|
2051 } //for(i) |
|
2052 } |
|
2053 |
|
2054 TBuf<63> sectionName; |
|
2055 |
|
2056 |
|
2057 for(TInt i = 0; i < iFormatterPlugins.Count(); i++) |
|
2058 { |
|
2059 sectionName = KFormatterConfig; |
|
2060 sectionName.AppendFormat(_L("%d"), i); |
|
2061 |
|
2062 ret = persistConfigData->AddSection( sectionName ); |
|
2063 User::LeaveIfError(ret); |
|
2064 |
|
2065 |
|
2066 // Add a key "UID" with a value equal to the UID of the writer, so we can load it again |
|
2067 RBuf uidNumberString; |
|
2068 uidNumberString.CleanupClosePushL(); |
|
2069 uidNumberString.CreateL( 8 ); |
|
2070 uidNumberString.AppendNumFixedWidth( (TUint)iFormatterInfos[i]->Uid(), EHex, 8 ); // Width = 8 chars |
|
2071 ret = persistConfigData->SetKey( sectionName, uidString, uidNumberString ); |
|
2072 User::LeaveIfError( ret ); |
|
2073 CleanupStack::PopAndDestroy(&uidNumberString); |
|
2074 |
|
2075 TPtrC pairString; |
|
2076 pairString.Set( KPluginPair ); |
|
2077 |
|
2078 //Add pair key with value equal to the paired writer plugin |
|
2079 RBuf pairNumberString; |
|
2080 pairNumberString.CleanupClosePushL(); |
|
2081 pairNumberString.CreateL( 8 ); |
|
2082 pairNumberString.AppendNumFixedWidth( (TUint)iFormatterInfos[i]->Pair(), EHex, 8 ); // Width = 8 chars |
|
2083 ret = persistConfigData->SetKey( sectionName, pairString, pairNumberString ); |
|
2084 User::LeaveIfError( ret ); |
|
2085 CleanupStack::PopAndDestroy(&pairNumberString); |
|
2086 |
|
2087 for( TInt j = 0; j < iTotalConfigList.Count(); j++ ) |
|
2088 { |
|
2089 if( iTotalConfigList[j] && (COptionConfig::EFormatterPlugin == iTotalConfigList[j]->Source()) && (i == iTotalConfigList[j]->Instance())) |
|
2090 { |
|
2091 SaveConfigParamL( iTotalConfigList[j], sectionName, iTotalConfigList[j]->Index(), persistConfigData ); |
|
2092 } |
|
2093 } |
|
2094 } |
|
2095 |
|
2096 for(TInt i = 0; i < iWriterPlugins.Count(); i++) |
|
2097 { |
|
2098 sectionName = KWriterConfig; |
|
2099 sectionName.AppendFormat(_L("%d"), i); |
|
2100 |
|
2101 ret = persistConfigData->AddSection( sectionName ); |
|
2102 User::LeaveIfError(ret); |
|
2103 |
|
2104 // Add a key "UID" with a value equal to the UID of the writer, so we can load it again |
|
2105 RBuf uidNumberString; |
|
2106 uidNumberString.CleanupClosePushL(); |
|
2107 uidNumberString.CreateL( 8 ); |
|
2108 uidNumberString.AppendNumFixedWidth( (TUint)iWriterInfos[i]->Uid(), EHex, 8 ); // Width = 8 chars |
|
2109 ret = persistConfigData->SetKey( sectionName, uidString, uidNumberString ); |
|
2110 User::LeaveIfError( ret ); |
|
2111 CleanupStack::PopAndDestroy(&uidNumberString); |
|
2112 |
|
2113 for( TInt j = 0; j < iTotalConfigList.Count(); j++ ) |
|
2114 { |
|
2115 if( iTotalConfigList[j] && (COptionConfig::EWriterPlugin == iTotalConfigList[j]->Source()) && (i == iTotalConfigList[j]->Instance())) |
|
2116 { |
|
2117 SaveConfigParamL( iTotalConfigList[j], sectionName, iTotalConfigList[j]->Index(), persistConfigData ); |
|
2118 } |
|
2119 } |
|
2120 } |
|
2121 |
|
2122 if( NULL == persistConfigData ) |
|
2123 { |
|
2124 LOG_MSG( " persistConfigData == NULL\n" ); |
|
2125 } |
|
2126 |
|
2127 // Now save the config to file |
|
2128 ret = persistConfigData->Externalise( fileName->Des() ); |
|
2129 //LOG_MSG2( " <- iPersistConfigData->Externalise() returned %d\n", ret ); |
|
2130 |
|
2131 //LOG_MSG( " CleanupStack::PopAndDestroy( iPersistConfigData )" ); |
|
2132 CleanupStack::PopAndDestroy( persistConfigData ); |
|
2133 |
|
2134 //LOG_MSG( " CleanupStack::PopAndDestroy( fileName )" ); |
|
2135 CleanupStack::PopAndDestroy( fileName ); |
|
2136 |
|
2137 //LOG_MSG( " ->CleanupStack::PopAndDestroy( fsSession )" ); |
|
2138 CleanupStack::PopAndDestroy( & fsSession ); |
|
2139 //LOG_MSG( " <-CleanupStack::PopAndDestroy( fsSession )" ); |
|
2140 |
|
2141 } |
|
2142 |
|
2143 /* |
|
2144 * Client request to load system configuration file |
|
2145 */ |
|
2146 void CCoreDumpSession::LoadConfigFileL( const RMessage2* aMessage ) |
|
2147 { |
|
2148 |
|
2149 |
|
2150 LOG_MSG( "CCoreDumpSession::LoadConfigFileL(RMessage2)" ); |
|
2151 |
|
2152 RFs fsSession; |
|
2153 //LOG_MSG( " User::LeaveIfError( fsSession.Connect() )\n" ); |
|
2154 User::LeaveIfError( fsSession.Connect() ); |
|
2155 CleanupClosePushL( fsSession ); |
|
2156 |
|
2157 TPtrC16 value; |
|
2158 |
|
2159 HBufC * fileName = NULL; |
|
2160 CIniDocument16 * persistConfigData = NULL; |
|
2161 |
|
2162 //LOG_MSG( " -> CIniDocument16 * iPersistConfigData = OpenIniFileLC()" ); |
|
2163 OpenIniFileLC( aMessage, EFalse, fsSession, fileName, persistConfigData ); |
|
2164 |
|
2165 //LOG_MSG( " -> RecreateConfigurationL( iPersistConfigData )\n" ); |
|
2166 RecreateConfigurationL( persistConfigData ); |
|
2167 |
|
2168 //LOG_MSG( " -> CleanupStack::PopAndDestroy( iPersistConfigData )" ); |
|
2169 CleanupStack::PopAndDestroy( persistConfigData ); |
|
2170 //LOG_MSG( " -> CleanupStack::PopAndDestroy( fileName )" ); |
|
2171 CleanupStack::PopAndDestroy( fileName ); |
|
2172 //LOG_MSG( " -> CleanupStack::PopAndDestroy( & fsSession )" ); |
|
2173 CleanupStack::PopAndDestroy( & fsSession ); |
|
2174 //LOG_MSG( " returning from CCoreDumpSession::LoadConfigFileL(RMessage2)" ); |
|
2175 } |
|
2176 |
|
2177 |
|
2178 /** |
|
2179 Method used to load and unload the formatter and writer plugins as a pair. |
|
2180 Also configures the data source and data save for the formatter. |
|
2181 If unloading the UIDs are still checked. |
|
2182 */ |
|
2183 void CCoreDumpSession::SetPluginsL( const TUid aFormatterUID, |
|
2184 const TUid aWriterUID, |
|
2185 const TBool aLoad ) |
|
2186 { |
|
2187 ValidatePluginL( aFormatterUID ); |
|
2188 |
|
2189 ValidatePluginL( aWriterUID ); |
|
2190 |
|
2191 /* |
|
2192 if( iFormatter ) |
|
2193 { |
|
2194 delete iFormatter; |
|
2195 iFormatterUid = TUid::Uid(0); |
|
2196 } |
|
2197 |
|
2198 if( iWriter ) |
|
2199 { |
|
2200 delete iWriter; |
|
2201 iWriterUid = TUid::Uid(0); |
|
2202 } |
|
2203 |
|
2204 if( !aLoad ) |
|
2205 { |
|
2206 return; |
|
2207 } |
|
2208 |
|
2209 // We push the plugins onto the cleanup stack since if we leave here we |
|
2210 // want them destroyed so that there is always a valid pair or none are loaded |
|
2211 iWriter = CCrashDataSave::NewL( aWriterUID ); |
|
2212 CleanupStack::PushL( iWriter ); |
|
2213 |
|
2214 iFormatter = CCoreDumpFormatter::NewL( aFormatterUID ); |
|
2215 CleanupStack::PushL( iFormatter ); |
|
2216 |
|
2217 iFormatter->ConfigureDataSourceL( iDataSource ); |
|
2218 iFormatter->ConfigureDataSaveL( iWriter ); |
|
2219 |
|
2220 iFormatterUid = aFormatterUID; |
|
2221 iWriterUid = aWriterUID; |
|
2222 |
|
2223 // We can pop the plugins |
|
2224 CleanupStack::Pop( 2, iWriter ); |
|
2225 |
|
2226 */ |
|
2227 } |
|
2228 |
|
2229 |
|
2230 |
|
2231 /** |
|
2232 Look through the iPersistConfigData object (initialised from the ini file) |
|
2233 and attempt to recreate the state described by the object. |
|
2234 This means |
|
2235 - unloading current plugins, |
|
2236 - loading new plugins, |
|
2237 - updating the configuration list by calling UpdateConfigParametersL() |
|
2238 - recreating the configuration for section (CDS, formatter, writer ) |
|
2239 |
|
2240 We have to be lax about the errors since we do not want to stop the |
|
2241 loading of a configuration if there is a non-fatal error. This applies to |
|
2242 loading of the plugins. |
|
2243 */ |
|
2244 void CCoreDumpSession::RecreateConfigurationL( CIniDocument16 * iPersistConfigData ) |
|
2245 { |
|
2246 |
|
2247 // for each section in ini file, |
|
2248 // read section's SID |
|
2249 // load plugins |
|
2250 // for each (type, index, value) triplet, |
|
2251 // create a COptionConfig |
|
2252 // append to aIniFileConfigList |
|
2253 // |
|
2254 |
|
2255 |
|
2256 TInt ret; |
|
2257 TBool foundCdsSection = EFalse; |
|
2258 TBool foundFormatterSection = EFalse; |
|
2259 TBool foundWriterSection = EFalse; |
|
2260 |
|
2261 TPtrC uidString; |
|
2262 uidString.Set( KUID ); |
|
2263 |
|
2264 // Recreate CDS section |
|
2265 { |
|
2266 TPtrC cdsUidString; |
|
2267 //LOG_MSG(" iPersistConfigData->GetKeyValue( KCDSConfig, uidString, cdsUidString )\n" ); |
|
2268 ret = iPersistConfigData->GetKeyValue( KCDSConfig, uidString, cdsUidString ); |
|
2269 //LOG_MSG2(" iPersistConfigData->GetKeyValue( ) returned %d\n", ret ); |
|
2270 |
|
2271 if( KErrNone == ret ) |
|
2272 { |
|
2273 foundCdsSection = ETrue; |
|
2274 } |
|
2275 else |
|
2276 { |
|
2277 // It an error for there to be no saved CDS configuration |
|
2278 User::Leave( ret ); |
|
2279 } |
|
2280 |
|
2281 if( foundCdsSection ) |
|
2282 { |
|
2283 TLex cdsUidLex( cdsUidString ); |
|
2284 TUint cdsUidValue; |
|
2285 cdsUidLex.Val( cdsUidValue, EHex ); |
|
2286 TUid savedCdsUid = TUid::Uid( cdsUidValue ); |
|
2287 //LOG_MSG2(" Found CDS Config Section with UID 0x%X\n", cdsUidValue ); |
|
2288 //LOG_MSG2(" Current UID is 0x%X\n", iOurSecureID.iUid ); |
|
2289 if( savedCdsUid != iOurSecureID ) |
|
2290 { |
|
2291 // The UID for the CDS does not match our current CDS SID. |
|
2292 // This could arise if the config file was created by a previous version |
|
2293 // of the CDS, but more likely we are reading a corrupt file. |
|
2294 // Thus the safe option is to leave |
|
2295 LOG_MSG2( " ERROR !* Read CDS UID from ini file as 0x%X, which is not same as our current value\n", |
|
2296 cdsUidValue ); |
|
2297 User::Leave( KErrCorrupt ); |
|
2298 } |
|
2299 }//foundCdsSection |
|
2300 } |
|
2301 |
|
2302 TBuf<63> sectionName; |
|
2303 |
|
2304 |
|
2305 foundWriterSection = -1; |
|
2306 for(TInt i = 0;;i++) |
|
2307 { |
|
2308 sectionName = KWriterConfig; |
|
2309 sectionName.AppendFormat(_L("%d"), i); |
|
2310 |
|
2311 TPtrC writerUidString; |
|
2312 ret = iPersistConfigData->GetKeyValue( sectionName, uidString, writerUidString ); |
|
2313 |
|
2314 TUint writerUidValue; |
|
2315 if( KErrNone == ret ) |
|
2316 { |
|
2317 foundWriterSection++; |
|
2318 TLex writerUidLex( writerUidString ); |
|
2319 writerUidLex.Val( writerUidValue, EHex ); |
|
2320 CreateWriterL( TUid::Uid( writerUidValue ) ); |
|
2321 } |
|
2322 else |
|
2323 { |
|
2324 break; |
|
2325 } |
|
2326 |
|
2327 } |
|
2328 |
|
2329 |
|
2330 foundFormatterSection = -1; |
|
2331 for(TInt i = 0;;i++) |
|
2332 { |
|
2333 sectionName = KFormatterConfig; |
|
2334 sectionName.AppendFormat(_L("%d"), i); |
|
2335 |
|
2336 TPtrC formatterUidString; |
|
2337 ret = iPersistConfigData->GetKeyValue( sectionName, uidString, formatterUidString ); |
|
2338 |
|
2339 TUint formatterUidValue; |
|
2340 if( KErrNone == ret ) |
|
2341 { |
|
2342 foundFormatterSection++; |
|
2343 TLex fromatterUidLex( formatterUidString ); |
|
2344 fromatterUidLex.Val( formatterUidValue, EHex ); |
|
2345 CreateFormatterL( TUid::Uid( formatterUidValue ) ); |
|
2346 |
|
2347 TPtrC pairString; |
|
2348 pairString.Set( KPluginPair ); |
|
2349 TPtrC formatterPairString; |
|
2350 ret = iPersistConfigData->GetKeyValue(sectionName, pairString, formatterPairString); |
|
2351 if(ret == KErrNone) |
|
2352 { |
|
2353 TLex fromatterPairLex( formatterPairString ); |
|
2354 TUint formatterPairValue; |
|
2355 fromatterPairLex.Val( formatterPairValue, EHex ); |
|
2356 BindPluginsL(i, formatterPairValue); |
|
2357 } |
|
2358 } |
|
2359 else |
|
2360 { |
|
2361 break; |
|
2362 } |
|
2363 |
|
2364 } |
|
2365 |
|
2366 |
|
2367 // Now that the old plugins are unloaded (if a new one was specified in the ini file), |
|
2368 // and the new ones loaded, reconstruct the list of configuration parameters. |
|
2369 // We will then change them with the ini file values that we are about to read. |
|
2370 // For plugins that have not been unloaded (because there was no mention in the init file) |
|
2371 // we will simply ask for the config params again, and we should get the current values. |
|
2372 |
|
2373 UpdateConfigParametersL(); |
|
2374 |
|
2375 if( foundCdsSection ) |
|
2376 { |
|
2377 //LOG_MSG( " -> ChangeConfigParamsL( COptionConfig::ECoreDumpServer\n" ); |
|
2378 ChangeConfigParamsL( COptionConfig::ECoreDumpServer, iPersistConfigData ); |
|
2379 } |
|
2380 |
|
2381 for(TInt i = 0; i <= foundFormatterSection; i++) |
|
2382 { |
|
2383 //LOG_MSG( " -> ChangeConfigParamsL( COptionConfig::EFormatterPlugin\n" ); |
|
2384 ChangeConfigParamsL( COptionConfig::EFormatterPlugin, iPersistConfigData, foundFormatterSection ); |
|
2385 } |
|
2386 |
|
2387 for(TInt i = 0; i <= foundWriterSection; i++) |
|
2388 { |
|
2389 //LOG_MSG( " -> ChangeConfigParamsL( COptionConfig::EWriterPlugin\n" ); |
|
2390 ChangeConfigParamsL( COptionConfig::EWriterPlugin, iPersistConfigData, foundWriterSection ); |
|
2391 } |
|
2392 |
|
2393 // Now rebuild the Observed list from the file |
|
2394 { |
|
2395 |
|
2396 //LOG_MSG( " About to Rebuild Observed Target List from Ini File\n" ); |
|
2397 |
|
2398 HBufC * iniTargetValue; |
|
2399 HBufC * iniOwnerType; |
|
2400 TInt observeIndex = 0; |
|
2401 TBool targetFound = ETrue; |
|
2402 while( targetFound ) |
|
2403 { |
|
2404 |
|
2405 // Each value obtained via EIniKeyIndex from the file is the CConfigOption index |
|
2406 // and is used to tie the saved to the live index. |
|
2407 |
|
2408 //LOG_MSG2(" GenerateKeyStringLC( EIniKeyValue =%d)\n", observeIndex ); |
|
2409 iniTargetValue = GenerateKeyStringLC( observeIndex, EIniKeyValue ); |
|
2410 |
|
2411 TPtrC observeTargetValue; |
|
2412 |
|
2413 //LOG_MSG(" iPersistConfigData->GetKeyValue( KObservedConfig, targetName )\n" ); |
|
2414 ret = iPersistConfigData->GetKeyValue( KObservedConfig, |
|
2415 iniTargetValue->Des(), |
|
2416 observeTargetValue ); |
|
2417 //LOG_MSG2(" iPersistConfigData->GetKeyValue( ) returned %d\n", ret ); |
|
2418 |
|
2419 CleanupStack::PopAndDestroy( iniTargetValue ); |
|
2420 |
|
2421 if( KErrNone != ret ) |
|
2422 { |
|
2423 LOG_MSG2( " Could not find a target : FindVar(EIniKeyValue) index %d returned false\n", |
|
2424 observeIndex ); |
|
2425 break; |
|
2426 } |
|
2427 |
|
2428 //LOG_MSG2(" GenerateKeyStringLC( EIniKeyType =%d)\n", observeIndex ); |
|
2429 iniOwnerType = GenerateKeyStringLC( observeIndex, EIniKeyType ); |
|
2430 |
|
2431 TPtrC observeTargetOwner; |
|
2432 |
|
2433 /* |
|
2434 LOG_MSG3( " ->FindVar( KObservedConfig, target owner %d. iniOwnerType.Length()=%d\n", |
|
2435 observeIndex, iniOwnerType->Des().Length() ); |
|
2436 */ |
|
2437 |
|
2438 ret = iPersistConfigData->GetKeyValue( KObservedConfig, |
|
2439 iniOwnerType->Des(), |
|
2440 observeTargetOwner ); |
|
2441 //LOG_MSG2(" iPersistConfigData->GetKeyValue( ) returned %d\n", ret ); |
|
2442 |
|
2443 CleanupStack::PopAndDestroy( iniOwnerType ); |
|
2444 |
|
2445 if( KErrNone != ret ) |
|
2446 { |
|
2447 LOG_MSG2( " Could not find a target owner: FindVar(EIniKeyValue) index %d returned false\n", |
|
2448 observeIndex ); |
|
2449 break; |
|
2450 } |
|
2451 |
|
2452 //LOG_MSG(" Creating observation request\n" ); |
|
2453 |
|
2454 AttachTargetL(observeTargetValue, observeTargetOwner); |
|
2455 |
|
2456 observeIndex++; |
|
2457 |
|
2458 }// while targetFound |
|
2459 |
|
2460 } // Now rebuild the Observed list from the file |
|
2461 |
|
2462 //LOG_MSG( " <- returning from RecreateConfigurationL()\n" ); |
|
2463 |
|
2464 } |
|
2465 |
|
2466 |
|
2467 /** |
|
2468 Method that reads the saved configuration and attempts to recreate that state. |
|
2469 For a given section of the ini file (indicated by the parameter aSource), |
|
2470 recreate each parameter from a triplet of settings (index, type, value) |
|
2471 and then apply the setting by calling SetConfigParameterL(). |
|
2472 |
|
2473 @param aSource Section of the config file to read and update state for. |
|
2474 @param aPersistConfigData Pointer to CIniDocument16 object that contains |
|
2475 the parameters to restore |
|
2476 |
|
2477 @see CIniDocument16 |
|
2478 */ |
|
2479 void CCoreDumpSession::ChangeConfigParamsL( const COptionConfig::TParameterSource aSource, |
|
2480 CIniDocument16 * aPersistConfigData, const TInt aInstance) |
|
2481 { |
|
2482 |
|
2483 //LOG_MSG2( "ChangeConfigParamsL( source=%d )\n", aSource ); |
|
2484 |
|
2485 TPtrC sectName; |
|
2486 TInt ret = KErrNone; |
|
2487 |
|
2488 switch( aSource ) |
|
2489 { |
|
2490 case COptionConfig::ECoreDumpServer: |
|
2491 sectName.Set( KCDSConfig ); |
|
2492 break; |
|
2493 case COptionConfig::EFormatterPlugin: |
|
2494 sectName.Set( KFormatterConfig ); |
|
2495 break; |
|
2496 case COptionConfig::EWriterPlugin: |
|
2497 sectName.Set( KWriterConfig ); |
|
2498 break; |
|
2499 default: |
|
2500 User::Leave( KErrArgument ); |
|
2501 } |
|
2502 |
|
2503 |
|
2504 HBufC * iniStringKey; |
|
2505 TUint index = 0; |
|
2506 |
|
2507 // Loop to recreate all the parameters for a given section and then |
|
2508 // call SetConfigParameterL() for each parameter |
|
2509 // As soon as one of the FindVar fails, we assume that there are no more entries for |
|
2510 // this section, and thus give up. |
|
2511 |
|
2512 // Parameter index |
|
2513 TInt keyIndex; |
|
2514 |
|
2515 // Parameter type |
|
2516 TInt keyType; |
|
2517 |
|
2518 // Parameter integer value |
|
2519 TInt keyIntValue; |
|
2520 |
|
2521 TLex paramLex; |
|
2522 |
|
2523 while( KErrNone == ret ) |
|
2524 { |
|
2525 |
|
2526 keyIndex = ELastParam; |
|
2527 keyType = -1; |
|
2528 keyIntValue = 0; |
|
2529 TPtrC keyStringValue; |
|
2530 |
|
2531 // Get parameter index |
|
2532 { |
|
2533 // Each value obtained via EIniKeyIndex from the file is the CConfigOption index |
|
2534 // and is used to tie the saved to the live index. |
|
2535 //LOG_MSG2(" ->GenerateKeyStringLC( index=%d, EIniKeyIndex )\n", index ); |
|
2536 iniStringKey = GenerateKeyStringLC( index, EIniKeyIndex ); |
|
2537 TPtrC keyIndexString; |
|
2538 |
|
2539 //LOG_MSG(" ->aPersistConfigData->GetKeyValue( EIniKeyIndex )\n" ); |
|
2540 ret = aPersistConfigData->GetKeyValue( sectName, iniStringKey->Des(), keyIndexString ); |
|
2541 CleanupStack::PopAndDestroy( iniStringKey ); |
|
2542 if( KErrNone != ret ) |
|
2543 { |
|
2544 LOG_MSG3(" aPersistConfigData->GetKeyValue( EIniKeyIndex ) returned %d for index %d\n", ret, index ); |
|
2545 break; |
|
2546 } |
|
2547 |
|
2548 paramLex.Assign( keyIndexString ); |
|
2549 keyIndex = 0; |
|
2550 paramLex.Val( keyIndex ); |
|
2551 //LOG_MSG2( " found EIniKeyIndex =%d\n", keyIndex ); |
|
2552 } |
|
2553 |
|
2554 |
|
2555 // Get parameter type |
|
2556 { |
|
2557 |
|
2558 //LOG_MSG2(" ->GenerateKeyStringLC( index=%d, EIniKeyType )\n", index ); |
|
2559 iniStringKey = GenerateKeyStringLC( index, EIniKeyType ); |
|
2560 TPtrC keyTypeString; |
|
2561 |
|
2562 //LOG_MSG(" ->aPersistConfigData->GetKeyValue( EIniKeyType )\n" ); |
|
2563 ret = aPersistConfigData->GetKeyValue( sectName, iniStringKey->Des(), keyTypeString ); |
|
2564 CleanupStack::PopAndDestroy( iniStringKey ); |
|
2565 if( KErrNone != ret ) |
|
2566 { |
|
2567 LOG_MSG3(" aPersistConfigData->GetKeyValue( EIniKeyType ) returned %d for index %d\n", ret, index ); |
|
2568 break; |
|
2569 } |
|
2570 |
|
2571 paramLex.Assign( keyTypeString ); |
|
2572 paramLex.Val( keyType ); |
|
2573 //LOG_MSG2( " found EIniKeyType =%d\n", keyType ); |
|
2574 } |
|
2575 |
|
2576 // Get parameter value |
|
2577 { |
|
2578 |
|
2579 //LOG_MSG2(" ->GenerateKeyStringLC( index=%d, EIniKeyValue )\n", index ); |
|
2580 iniStringKey = GenerateKeyStringLC( index, EIniKeyValue ); |
|
2581 |
|
2582 //LOG_MSG( " aPersistConfigData->GetKeyValue( EIniKeyValue )\n" ); |
|
2583 ret = aPersistConfigData->GetKeyValue( sectName, iniStringKey->Des(), keyStringValue ); |
|
2584 |
|
2585 //LOG_MSG2( " aPersistConfigData->GetKeyValue( EIniKeyValue ) returned string with length=%d\n", keyStringValue.Length() ); |
|
2586 CleanupStack::PopAndDestroy( iniStringKey ); |
|
2587 if( KErrNone != ret ) |
|
2588 { |
|
2589 LOG_MSG3(" aPersistConfigData->GetKeyValue( EIniKeyValue ) returned %d for index %d\n", ret, index ); |
|
2590 break; |
|
2591 } |
|
2592 |
|
2593 switch( (COptionConfig::TOptionType) keyType ) |
|
2594 { |
|
2595 case COptionConfig::ETInt: |
|
2596 case COptionConfig::ETUInt: |
|
2597 case COptionConfig::ETBool: |
|
2598 paramLex.Assign( keyStringValue ); |
|
2599 paramLex.Val( keyIntValue ); |
|
2600 keyStringValue.Set( KNullDesC ); |
|
2601 break; |
|
2602 } |
|
2603 } |
|
2604 |
|
2605 |
|
2606 /* |
|
2607 { |
|
2608 if( -1 != keyIntValue ) |
|
2609 { |
|
2610 LOG_MSG2( " found EIniKeyValue as Int =%d\n", keyIntValue ); |
|
2611 } |
|
2612 |
|
2613 RBuf value; |
|
2614 value.Create( keyStringValue ); |
|
2615 char* cl = (char*) value.Collapse().PtrZ(); |
|
2616 RDebug::Printf(" found EIniKeyValue as String =%s\n", cl ); |
|
2617 } |
|
2618 */ |
|
2619 |
|
2620 LOG_MSG3( " SetConfigParameterL( value=%d, string length=%d\n", keyIntValue, keyStringValue.Length() ); |
|
2621 |
|
2622 switch( aSource ) |
|
2623 { |
|
2624 |
|
2625 case COptionConfig::ECoreDumpServer: |
|
2626 SetConfigParameterL( keyIndex, keyIntValue, keyStringValue ); |
|
2627 break; |
|
2628 |
|
2629 case COptionConfig::EFormatterPlugin: |
|
2630 |
|
2631 if( (iFormatterPlugins.Count() > 0 ) && (iFormatterPlugins.Count() < aInstance) ) |
|
2632 { |
|
2633 iFormatterPlugins[aInstance]->SetConfigParameterL( keyIndex, keyIntValue, keyStringValue ); |
|
2634 } |
|
2635 else |
|
2636 { |
|
2637 LOG_MSG2("CCoreDumpSession::ChangeConfigParamsL() : formatter:%d not loaded\n", aInstance); |
|
2638 User::Leave( KErrArgument ); |
|
2639 } |
|
2640 break; |
|
2641 |
|
2642 case COptionConfig::EWriterPlugin: |
|
2643 |
|
2644 if( (iWriterPlugins.Count() > 0 ) && (iWriterPlugins.Count() < aInstance) ) |
|
2645 { |
|
2646 iWriterPlugins[aInstance]->SetConfigParameterL( keyIndex, keyIntValue, keyStringValue ); |
|
2647 } |
|
2648 else |
|
2649 { |
|
2650 LOG_MSG2("CCoreDumpSession::ChangeConfigParamsL() : writer:%d not loaded\n", aInstance); |
|
2651 User::Leave( KErrArgument ); |
|
2652 } |
|
2653 break; |
|
2654 |
|
2655 default: |
|
2656 User::Leave( KErrArgument ); |
|
2657 } |
|
2658 |
|
2659 index ++; |
|
2660 }//while |
|
2661 } |
|
2662 |
|
2663 |
|
2664 _LIT(KKey,"Key"); |
|
2665 _LIT(KType,"Type"); |
|
2666 _LIT(KIndex,"Index"); |
|
2667 _LIT(KValue,"Value"); |
|
2668 |
|
2669 /** |
|
2670 This method allocates a string of two concatenated components. The first component is based on |
|
2671 the parameter aKey. The second component is the string representation of aIndex. |
|
2672 Thus it maps an enum to a string and then it appends the index. The string is left on the |
|
2673 cleanup stack and it is the responsibility of the caller to remove it from the cleanup stack. |
|
2674 */ |
|
2675 HBufC * CCoreDumpSession::GenerateKeyStringLC( TUint aIndex, |
|
2676 CCoreDumpSession::TCoreDumpIniKey aKey ) |
|
2677 { |
|
2678 |
|
2679 HBufC * keyString = HBufC::NewL( 20 ); |
|
2680 CleanupStack::PushL( keyString ); |
|
2681 |
|
2682 TPtr ptr = keyString->Des(); |
|
2683 ptr.Append( KKey ); |
|
2684 |
|
2685 switch( aKey ) |
|
2686 { |
|
2687 case EIniKeyType: |
|
2688 ptr.Append( KType ); |
|
2689 break; |
|
2690 |
|
2691 case EIniKeyIndex: |
|
2692 ptr.Append( KIndex ); |
|
2693 break; |
|
2694 |
|
2695 case EIniKeyValue: |
|
2696 ptr.Append( KValue ); |
|
2697 break; |
|
2698 } |
|
2699 |
|
2700 ptr.AppendNum( aIndex ); |
|
2701 return keyString; |
|
2702 } |
|
2703 |
|
2704 void CCoreDumpSession::SuspendProcessL(TUint64 aPid) |
|
2705 { |
|
2706 LOG_MSG("->CCoreDumpSession::SuspendProcessL()\n"); |
|
2707 iDataSource->GetThreadListL( aPid, iThreadPointerList, iTotalThreadListDescSize ); |
|
2708 TInt err = KErrNone; |
|
2709 for(TInt i = 0; i < iThreadPointerList.Count(); i++) |
|
2710 { |
|
2711 LOG_MSG2("CCoreDumpSession::SuspenProcessL - suspending thread:%Ld\n", iThreadPointerList[i]->Id()); |
|
2712 err = iSecSess.SuspendThread(iThreadPointerList[i]->Id()); |
|
2713 if( (err != KErrNone) && (err != KErrAlreadyExists) ) |
|
2714 { |
|
2715 LOG_MSG2("CCoreDumpSession::SuspendProcessL - unable to suspend thread! err:%d\n", err); |
|
2716 User::LeaveIfError(err); |
|
2717 } |
|
2718 } |
|
2719 } |
|
2720 |
|
2721 void CCoreDumpSession::ResumeThreadL(TUint64 aTid) |
|
2722 { |
|
2723 LOG_MSG2("->CCoreDumpSession::ResumeThreadL(aTid=%Ld)\n", aTid); |
|
2724 |
|
2725 TInt err = iSecSess.ResumeThread(TThreadId(aTid)); |
|
2726 if(err != KErrNone) |
|
2727 { |
|
2728 LOG_MSG2("CCoreDumpSession::ResumeThreadL - unable to resume thread! err:%d\n", err); |
|
2729 User::LeaveIfError(err); |
|
2730 } |
|
2731 } |
|
2732 |
|
2733 /** |
|
2734 Called to resume all the threads of the specified process. CCoreCrashHandler executes it as a post-processing action. |
|
2735 @param aPid ID of process to be resumed |
|
2736 @leave err one of the system wide error codes |
|
2737 @see SuspendProcessL |
|
2738 */ |
|
2739 void CCoreDumpSession::ResumeProcessL(TUint64 aPid) |
|
2740 { |
|
2741 LOG_MSG2("->CCoreDumpSession::ResumeProcessL(aPid=%Ld)\n", aPid); |
|
2742 |
|
2743 iDataSource->GetThreadListL( aPid, iThreadPointerList, iTotalThreadListDescSize ); |
|
2744 |
|
2745 TInt err = KErrNone; |
|
2746 //first resume child threads |
|
2747 TInt looperr = KErrNone; |
|
2748 for(TInt j = 1; j < iThreadPointerList.Count(); j++) |
|
2749 { |
|
2750 LOG_MSG2("CCoreDumpSession::ResumeProcessL - resuming thread:%Ld\n", iThreadPointerList[j]->Id()); |
|
2751 looperr = iSecSess.ResumeThread( iThreadPointerList[j]->Id() ); |
|
2752 if( (looperr != KErrNone) && (looperr != KErrNotFound) ) |
|
2753 { |
|
2754 err = looperr; |
|
2755 LOG_MSG2("CCoreDumpSession::ResumeProcessL - unable to resume thread! err:%d\n", err); |
|
2756 } |
|
2757 } |
|
2758 |
|
2759 looperr = KErrNone; |
|
2760 //then resume the main thread |
|
2761 if(iThreadPointerList.Count()) |
|
2762 { |
|
2763 LOG_MSG2("CCoreDumpSession::ResumeProcessL - resuming main thread:%Ld\n", iThreadPointerList[0]->Id()); |
|
2764 looperr = iSecSess.ResumeThread(iThreadPointerList[0]->Id()); |
|
2765 } |
|
2766 |
|
2767 if( (looperr != KErrNone) && (looperr != KErrNotFound) ) |
|
2768 { |
|
2769 err = looperr; |
|
2770 LOG_MSG2("CCoreDumpSession::ResumeProcessL - unable to resume main thread! err:%d\n", err); |
|
2771 } |
|
2772 |
|
2773 User::LeaveIfError(err); |
|
2774 } |
|
2775 |
|
2776 |
|
2777 void CCoreDumpSession::KillProcessL(TUint64 aPid) |
|
2778 { |
|
2779 LOG_MSG2("->CCoreDumpSession::KillProcessL(aPid=%Ld)\n", aPid); |
|
2780 RProcess target; |
|
2781 //LOG_MSG("CCoreDumpSession::KillProcessL - opening crashed process handle\n"); |
|
2782 TInt err = target.Open(aPid); |
|
2783 if(err != KErrNone) |
|
2784 { |
|
2785 LOG_MSG2("CCoreDumpSession::KillProcessL - unable to open process handle! err:%d\n", err); |
|
2786 User::Leave(err); |
|
2787 } |
|
2788 |
|
2789 CleanupClosePushL(target); |
|
2790 |
|
2791 TInt i; |
|
2792 for(i = 0; i < iObservationList.Count(); i++) |
|
2793 { |
|
2794 if(iObservationList[i]->TargetName().CompareF(target.FileName()) == 0) break; |
|
2795 } |
|
2796 |
|
2797 ResumeProcessL(aPid); |
|
2798 |
|
2799 if(i == iObservationList.Count()) |
|
2800 { |
|
2801 LOG_MSG("CCoreDumpSession::KillProcessL - unable to find process observer!\n"); |
|
2802 User::Leave(KErrNotFound); |
|
2803 } |
|
2804 |
|
2805 LOG_MSG(" -> SetCrashEventsL(*iObservationList[i], EActionIgnore)\n" ); |
|
2806 SetCrashEventsL(*iObservationList[i], EActionIgnore); |
|
2807 |
|
2808 LOG_MSG(" -> target.Terminate(KErrAbort)\n" ); |
|
2809 target.Terminate(KErrAbort); |
|
2810 |
|
2811 TRequestStatus logonStatus; |
|
2812 LOG_MSG(" -> target.Logon( logonStatus );\n" ); |
|
2813 target.Logon( logonStatus ); |
|
2814 LOG_MSG(" <- target.Logon( logonStatus );\n" ); |
|
2815 |
|
2816 CleanupStack::PopAndDestroy(&target); //target |
|
2817 |
|
2818 User::WaitForRequest( logonStatus ); |
|
2819 LOG_MSG(" <- User::WaitForRequest( logonStatus );\n" ); |
|
2820 |
|
2821 |
|
2822 if( (iPreCrashEventAction & ESuspendThread) || |
|
2823 (iPreCrashEventAction & ESuspendProcess) ) |
|
2824 SetCrashEventsL(*iObservationList[i], EActionSuspend); |
|
2825 else |
|
2826 SetCrashEventsL(*iObservationList[i], EActionContinue); |
|
2827 } |
|
2828 |
|
2829 /** |
|
2830 * Cleanup item implementation for SCMConfiguration |
|
2831 */ |
|
2832 void CCoreDumpSession::CleanupSCMConfiguration(TAny* aScmConfig) |
|
2833 { |
|
2834 SCMConfiguration* config = static_cast<SCMConfiguration*> (aScmConfig); |
|
2835 delete config; |
|
2836 config = NULL; |
|
2837 } |
|
2838 |
|
2839 |
|
2840 //void CCoreDumpSession::ReadSCMConfigListL() |
|
2841 // { |
|
2842 // // read the config data from the flash data source |
|
2843 // } |
|
2844 // |
|
2845 //void CCoreDumpSession::WriteSCMConfigListL() |
|
2846 // { |
|
2847 // // read the config data from the flash data source |
|
2848 // iFlashDataSource->WriteSCMConfigL(); |
|
2849 // } |
|
2850 // |
|
2851 |