|
1 // Copyright (c) 2008-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 // |
|
15 |
|
16 |
|
17 |
|
18 /** |
|
19 @file CFlashDataSourceWrapper.cpp |
|
20 @internalTechnology |
|
21 */ |
|
22 #include "CFlashDataSourceWrapper.h" |
|
23 |
|
24 using namespace Debug; |
|
25 |
|
26 //Names of functions to be tested - referenced from script file |
|
27 _LIT(KNewL_Debug, "NewL"); |
|
28 _LIT(KReadCrashLog, "ReadCrashLog"); |
|
29 _LIT(KGetFlashBuffer, "GetFlashBuffer"); |
|
30 _LIT(KProcessCrashHeader1, "ProcessCrashHeader1"); |
|
31 _LIT(KProcessCrashHeader2, "ProcessCrashHeader2"); |
|
32 _LIT(KGetProcessListL1, "GetProcessListL1"); |
|
33 _LIT(KGetProcessListL2, "GetProcessListL2"); |
|
34 _LIT(KGetThreadListL1, "GetThreadListL1"); |
|
35 _LIT(KGetThreadListL2, "GetThreadListL2"); |
|
36 _LIT(KGetThreadListL3, "GetThreadListL3"); |
|
37 _LIT(KReadRegistersL1, "ReadRegistersL1"); |
|
38 _LIT(KReadMemoryL1, "ReadMemoryL1"); |
|
39 _LIT(KReadMemoryL2, "ReadMemoryL2"); |
|
40 _LIT(KGetCodeSegmentsL1, "GetCodeSegmentsL1"); |
|
41 _LIT(KGetCodeSegmentsL2, "GetCodeSegmentsL2"); |
|
42 _LIT(KGetCodeSegmentsL3, "GetCodeSegmentsL3"); |
|
43 |
|
44 _LIT(KReadTraceBufferL1, "ReadTraceBufferL1"); |
|
45 _LIT(KReadTraceBufferL2, "ReadTraceBufferL2"); |
|
46 _LIT(KCalcChecksum, "CalcChecksum"); |
|
47 _LIT(KTraceDataSize, "TraceDataSize"); |
|
48 _LIT(KTraceDataSizeNotFound, "TraceDataSizeNotFound"); |
|
49 |
|
50 _LIT8(KCrashDummyData, "This is a sample write"); |
|
51 |
|
52 const TInt FLASH_ALIGN = sizeof(TInt32); |
|
53 const TInt START_OF_FLASH = 0; |
|
54 |
|
55 /** |
|
56 * Constructor for test wrapper |
|
57 */ |
|
58 CFlashDataSourceWrapper::CFlashDataSourceWrapper() |
|
59 :iObject(NULL) |
|
60 { |
|
61 } |
|
62 |
|
63 /** |
|
64 * Destructor |
|
65 */ |
|
66 CFlashDataSourceWrapper::~CFlashDataSourceWrapper() |
|
67 { |
|
68 } |
|
69 |
|
70 /** |
|
71 * Two phase constructor for CFlashDataSourceWrapper |
|
72 * @return CFlashDataSourceWrapper object |
|
73 * @leave |
|
74 */ |
|
75 CFlashDataSourceWrapper* CFlashDataSourceWrapper::NewL() |
|
76 { |
|
77 CFlashDataSourceWrapper* ret = new (ELeave) CFlashDataSourceWrapper(); |
|
78 CleanupStack::PushL(ret); |
|
79 ret->ConstructL(); |
|
80 CleanupStack::Pop(ret); |
|
81 return ret; |
|
82 } |
|
83 |
|
84 /** |
|
85 * Safe construction |
|
86 * @leave |
|
87 */ |
|
88 void CFlashDataSourceWrapper::ConstructL() |
|
89 { |
|
90 |
|
91 } |
|
92 |
|
93 /** |
|
94 * Assign the object |
|
95 * |
|
96 * @param aObject TAny* to the object to test |
|
97 * @leave |
|
98 */ |
|
99 void CFlashDataSourceWrapper::SetObjectL(TAny* aObject) |
|
100 { |
|
101 delete iObject; |
|
102 iObject = NULL; |
|
103 iObject = static_cast<CFlashDataSource*> (aObject); |
|
104 } |
|
105 |
|
106 /** |
|
107 * Runs a test preamble |
|
108 */ |
|
109 void CFlashDataSourceWrapper::PrepareTestL() |
|
110 { |
|
111 SetBlockResult(EPass); |
|
112 |
|
113 INFO_PRINTF1(_L("Connecting to DSS")); |
|
114 //get a session to the security server |
|
115 User::LeaveIfError(iSecSess.Connect(securityServerVersion)); |
|
116 |
|
117 INFO_PRINTF1(_L("Erasing crash log")); |
|
118 User::LeaveIfError(iSecSess.EraseCrashLog(0, 1)); |
|
119 |
|
120 INFO_PRINTF1(_L("Creating data source")); |
|
121 |
|
122 //Hackage: TEF doesnt support preamble/postamble and destructs iObject each time. Until they sort it out |
|
123 //or document how it is done the hackage shall have to continue. Oh for JUnit.... |
|
124 delete iObject; //to be sure |
|
125 iObject = CFlashDataSource::NewL(iSecSess); |
|
126 //end of hackage |
|
127 |
|
128 INFO_PRINTF1(_L("Ready to start test")); |
|
129 } |
|
130 |
|
131 /** |
|
132 * Process command to see what test to run |
|
133 */ |
|
134 TBool CFlashDataSourceWrapper::DoCommandL(const TTEFFunction& aCommand, const TTEFSectionName& aSection, const TInt aAsyncErrorIndex) |
|
135 { |
|
136 __UHEAP_MARK; |
|
137 |
|
138 PrepareTestL(); |
|
139 |
|
140 if (KNewL_Debug() == aCommand) |
|
141 { |
|
142 RDebug::Printf("Looking at CFlashDataSource::NewL()"); |
|
143 TRAPD(err , DoCmdCrashFlashDataSource_NewL_TestL()); |
|
144 if(BlockResult() != EPass || KErrNone != err) |
|
145 { |
|
146 RDebug::Printf("\tFailed!"); |
|
147 INFO_PRINTF2(_L("Failed with err = [%d]"), err); |
|
148 SetBlockResult(EFail); |
|
149 } |
|
150 } |
|
151 else if (KReadCrashLog() == aCommand) |
|
152 { |
|
153 RDebug::Printf("Looking at CFlashDataSource::ReadCrashLog()"); |
|
154 TRAPD(err , DoCmd_ReadCrashLog_L()); |
|
155 if(BlockResult() != EPass || KErrNone != err) |
|
156 { |
|
157 RDebug::Printf("\tFailed! [%d]", err); |
|
158 INFO_PRINTF2(_L("Failed with err = [%d]"), err); |
|
159 SetBlockResult(EFail); |
|
160 } |
|
161 } |
|
162 else if (KGetFlashBuffer() == aCommand) |
|
163 { |
|
164 RDebug::Printf("Looking at CFlashDataSource::GetFlashBuffer()"); |
|
165 TRAPD(err , DoCmd_GetFlashBuffer_L()); |
|
166 if(BlockResult() != EPass || KErrNone != err) |
|
167 { |
|
168 RDebug::Printf("\tFailed! [%d]", err); |
|
169 INFO_PRINTF2(_L("Failed with err = [%d]"), err); |
|
170 SetBlockResult(EFail); |
|
171 } |
|
172 } |
|
173 else if (KProcessCrashHeader1() == aCommand) |
|
174 { |
|
175 TRAPD(err , DoCmd_ProcessCrashHeader1_L()); |
|
176 if(BlockResult() != EPass || KErrNone != err) |
|
177 { |
|
178 RDebug::Printf("\tFailed! [%d]", err); |
|
179 INFO_PRINTF2(_L("Failed with err = [%d]"), err); |
|
180 SetBlockResult(EFail); |
|
181 } |
|
182 } |
|
183 else if (KProcessCrashHeader2() == aCommand) |
|
184 { |
|
185 RDebug::Printf("Looking at CFlashDataSource::ProcessCrashHeader() - 2nd test"); |
|
186 TRAPD(err , DoCmd_ProcessCrashHeader2_L()); |
|
187 if(BlockResult() != EPass || KErrNone != err) |
|
188 { |
|
189 RDebug::Printf("\tFailed! [%d]", err); |
|
190 INFO_PRINTF2(_L("Failed with err = [%d]"), err); |
|
191 SetBlockResult(EFail); |
|
192 } |
|
193 } |
|
194 else if( KGetProcessListL1() == aCommand) |
|
195 { |
|
196 RDebug::Printf("Looking at CFlashDataSource::GetProcessListL() - 1st test"); |
|
197 TRAPD(err , DoCmd_GetProcessListL1_Test_L()); |
|
198 if(BlockResult() != EPass || KErrNone != err) |
|
199 { |
|
200 RDebug::Printf("\tFailed! [%d]", err); |
|
201 INFO_PRINTF2(_L("Failed with err = [%d]"), err); |
|
202 SetBlockResult(EFail); |
|
203 } |
|
204 } |
|
205 else if ( KGetProcessListL2() == aCommand) |
|
206 { |
|
207 RDebug::Printf("Looking at CFlashDataSource::GetProcessListL() - 2nd test"); |
|
208 TRAPD(err , DoCmd_GetProcessListL2_Test_L()); |
|
209 if(BlockResult() != EPass || KErrNone != err) |
|
210 { |
|
211 RDebug::Printf("\tFailed! [%d]", err); |
|
212 INFO_PRINTF2(_L("Failed with err = [%d]"), err); |
|
213 SetBlockResult(EFail); |
|
214 } |
|
215 } |
|
216 else if (KGetThreadListL1() == aCommand) |
|
217 { |
|
218 RDebug::Printf("Looking at CFlashDataSource::GetThreadListL() - 1st test"); |
|
219 TRAPD(err , DoCmd_GetThreadListL1_Test_L()); |
|
220 if(BlockResult() != EPass || KErrNone != err) |
|
221 { |
|
222 RDebug::Printf("\tFailed! [%d]", err); |
|
223 INFO_PRINTF2(_L("Failed with err = [%d]"), err); |
|
224 SetBlockResult(EFail); |
|
225 } |
|
226 } |
|
227 else if( KGetThreadListL2() == aCommand) |
|
228 { |
|
229 RDebug::Printf("Looking at CFlashDataSource::GetThreadListL() - 2nd test"); |
|
230 TRAPD(err , DoCmd_GetThreadListL2_Test_L()); |
|
231 if(BlockResult() != EPass || KErrNone != err) |
|
232 { |
|
233 RDebug::Printf("\tFailed! [%d]", err); |
|
234 INFO_PRINTF2(_L("Failed with err = [%d]"), err); |
|
235 SetBlockResult(EFail); |
|
236 } |
|
237 } |
|
238 else if( KGetThreadListL3() == aCommand) |
|
239 { |
|
240 RDebug::Printf("Looking at CFlashDataSource::GetThreadListL() - 3rd test"); |
|
241 TRAPD(err , DoCmd_GetThreadListL3_Test_L()); |
|
242 if(BlockResult() != EPass || KErrNone != err) |
|
243 { |
|
244 RDebug::Printf("\tFailed! [%d]", err); |
|
245 INFO_PRINTF2(_L("Failed with err = [%d]"), err); |
|
246 SetBlockResult(EFail); |
|
247 } |
|
248 } |
|
249 else if( KReadRegistersL1() == aCommand) |
|
250 { |
|
251 RDebug::Printf("Looking at CFlashDataSource::ReadRegistersL() - 1st test"); |
|
252 TRAPD(err , DoCmd_ReadRegistersL1_Test_L()); |
|
253 if(BlockResult() != EPass || KErrNone != err) |
|
254 { |
|
255 RDebug::Printf("\tFailed! [%d]", err); |
|
256 INFO_PRINTF2(_L("Failed with err = [%d]"), err); |
|
257 SetBlockResult(EFail); |
|
258 } |
|
259 } |
|
260 else if( KReadMemoryL1() == aCommand) |
|
261 { |
|
262 RDebug::Printf("Looking at CFlashDataSource::ReadMemoryL() - 1st test"); |
|
263 TRAPD(err , DoCmd_ReadMemoryL1_Test_L()); |
|
264 if(BlockResult() != EPass || KErrNone != err) |
|
265 { |
|
266 RDebug::Printf("\tFailed! [%d]", err); |
|
267 INFO_PRINTF2(_L("Failed with err = [%d]"), err); |
|
268 SetBlockResult(EFail); |
|
269 } |
|
270 } |
|
271 else if( KReadMemoryL2() == aCommand) |
|
272 { |
|
273 RDebug::Printf("Looking at CFlashDataSource::ReadMemoryL() - 2nd test"); |
|
274 TRAPD(err , DoCmd_ReadMemoryL2_Test_L()); |
|
275 if(BlockResult() != EPass || KErrNone != err) |
|
276 { |
|
277 RDebug::Printf("\tFailed! [%d]", err); |
|
278 INFO_PRINTF2(_L("Failed with err = [%d]"), err); |
|
279 SetBlockResult(EFail); |
|
280 } |
|
281 } |
|
282 else if( KGetCodeSegmentsL1() == aCommand) |
|
283 { |
|
284 RDebug::Printf("Looking at CFlashDataSource::GetCodeSegmentsL() - 1st test"); |
|
285 TRAPD(err , DoCmd_GetCodeSegmentsL1_Test_L()); |
|
286 if(BlockResult() != EPass || KErrNone != err) |
|
287 { |
|
288 RDebug::Printf("\tFailed! [%d]", err); |
|
289 INFO_PRINTF2(_L("Failed with err = [%d]"), err); |
|
290 SetBlockResult(EFail); |
|
291 } |
|
292 } |
|
293 else if( KGetCodeSegmentsL2() == aCommand) |
|
294 { |
|
295 RDebug::Printf("Looking at CFlashDataSource - Code Segment Analysis - 2nd test"); |
|
296 TRAPD(err , DoCmd_GetCodeSegmentsL2_Test_L()); |
|
297 if(BlockResult() != EPass || KErrNone != err) |
|
298 { |
|
299 RDebug::Printf("\tFailed! [%d]", err); |
|
300 INFO_PRINTF2(_L("Failed with err = [%d]"), err); |
|
301 SetBlockResult(EFail); |
|
302 } |
|
303 } |
|
304 else if( KGetCodeSegmentsL3() == aCommand) |
|
305 { |
|
306 RDebug::Printf("Looking at CFlashDataSource - Code Segment Analysis - 3rd test"); |
|
307 TRAPD(err , DoCmd_GetCodeSegmentsL3_Test_L()); |
|
308 if(BlockResult() != EPass || KErrNone != err) |
|
309 { |
|
310 RDebug::Printf("\tFailed! [%d]", err); |
|
311 INFO_PRINTF2(_L("Failed with err = [%d]"), err); |
|
312 SetBlockResult(EFail); |
|
313 } |
|
314 } |
|
315 else if( KReadTraceBufferL1() == aCommand) |
|
316 { |
|
317 RDebug::Printf("Looking at CFlashDataSource - Trace Buffer - 1st test"); |
|
318 TRAPD(err , DoCmd_ReadTraceBufferL1_Test_L()); |
|
319 if(BlockResult() != EPass || KErrNone != err) |
|
320 { |
|
321 RDebug::Printf("\tFailed! [%d]", err); |
|
322 INFO_PRINTF2(_L("Failed with err = [%d]"), err); |
|
323 SetBlockResult(EFail); |
|
324 } |
|
325 } |
|
326 else if(KCalcChecksum() == aCommand) |
|
327 { |
|
328 TRAPD(err , DoCmd_CalculateChecksum_TestL()); |
|
329 if(BlockResult() != EPass || KErrNone != err) |
|
330 { |
|
331 RDebug::Printf("\tFailed! [%d]", err); |
|
332 } |
|
333 } |
|
334 else if(KTraceDataSizeNotFound() == aCommand) |
|
335 { |
|
336 TRAPD(err , DoCmd_TraceDataSizeNotFoundL_TestL()); |
|
337 if(BlockResult() != EPass || KErrNone != err) |
|
338 { |
|
339 RDebug::Printf("\tFailed! [%d]", err); |
|
340 } |
|
341 } |
|
342 else if(KTraceDataSize() == aCommand) |
|
343 { |
|
344 TRAPD(err , DoCmd_TraceDataSizeL_TestL()); |
|
345 if(BlockResult() != EPass || KErrNone != err) |
|
346 { |
|
347 RDebug::Printf("\tFailed! [%d]", err); |
|
348 } |
|
349 } |
|
350 else if(KReadTraceBufferL2() == aCommand) |
|
351 { |
|
352 TRAPD(err , DoCmd_ReadTraceBufferL2_Test_L()); |
|
353 if(BlockResult() != EPass || KErrNone != err) |
|
354 { |
|
355 RDebug::Printf("\tFailed! [%d]", err); |
|
356 } |
|
357 } |
|
358 else |
|
359 { |
|
360 RDebug::Printf("Not found"); |
|
361 |
|
362 delete iObject; |
|
363 iSecSess.Close(); |
|
364 |
|
365 __UHEAP_MARKEND; |
|
366 |
|
367 return EFalse; |
|
368 } |
|
369 |
|
370 delete iObject; |
|
371 iSecSess.Close(); |
|
372 |
|
373 __UHEAP_MARKEND; |
|
374 |
|
375 return ETrue; |
|
376 } |
|
377 |
|
378 /** |
|
379 * This tests that we can succesfully construct |
|
380 * @leave |
|
381 */ |
|
382 void CFlashDataSourceWrapper::DoCmdCrashFlashDataSource_NewL_TestL() |
|
383 { |
|
384 //first we delete the CFlashDataSource created by our post amble to ensure we are testing a fresh object |
|
385 delete iObject; |
|
386 |
|
387 SetBlockResult(EPass); |
|
388 |
|
389 INFO_PRINTF1(_L("Testing: CFlashDataSource::NewL()")); |
|
390 |
|
391 //Try to create a flash data source object |
|
392 TRAPD(err, iObject = CFlashDataSource::NewL(iSecSess)); |
|
393 |
|
394 //Check errors |
|
395 if(KErrNone != err) |
|
396 { |
|
397 ERR_PRINTF2(_L("Leave when creating CFlashDataSource: [%d]"),err); |
|
398 SetBlockResult(EFail); |
|
399 } |
|
400 |
|
401 //make sure its not null |
|
402 if(!iObject) |
|
403 { |
|
404 ERR_PRINTF1(_L("Problems with creating CFlashDataSource object")); |
|
405 SetBlockResult(EFail); |
|
406 } |
|
407 |
|
408 INFO_PRINTF1(_L("CFlashDataSource object constructed succesfully")); |
|
409 } |
|
410 |
|
411 /** |
|
412 * Tests the ReadCrashLog method on the flash data source |
|
413 */ |
|
414 void CFlashDataSourceWrapper::DoCmd_ReadCrashLog_L() |
|
415 { |
|
416 INFO_PRINTF1(_L("Testing CFlashDataSource::ReadCrashLog()")); |
|
417 |
|
418 //Write some expected data to the flash partition |
|
419 TUint32 size = 0; |
|
420 |
|
421 INFO_PRINTF1(_L("Writing dummy data to crash log")); |
|
422 iSecSess.WriteCrashConfig(START_OF_FLASH, KCrashDummyData, size); |
|
423 |
|
424 INFO_PRINTF1(_L("Reading dummy data back from crash log")); |
|
425 TInt err = iObject->ReadCrashLog(START_OF_FLASH, size); |
|
426 |
|
427 //make sure we got the right data back |
|
428 if( KErrNone != err || 0 != iObject->GetFlashBuffer().Compare(KCrashDummyData) ) |
|
429 { |
|
430 ERR_PRINTF2(_L("Failed to read the correct data back via flash data source: Err = [%d]"), err); |
|
431 SetBlockResult(EFail); |
|
432 return; |
|
433 } |
|
434 |
|
435 //test the parameters |
|
436 INFO_PRINTF1(_L("Testing that reading from a negative position will fail")); |
|
437 |
|
438 TInt32 negative = -2; |
|
439 err = iObject->ReadCrashLog(negative, size); |
|
440 |
|
441 if(err != KErrArgument) |
|
442 { |
|
443 ERR_PRINTF1(_L("We were able to read data from a negative position")); |
|
444 SetBlockResult(EFail); |
|
445 return; |
|
446 } |
|
447 } |
|
448 |
|
449 /** |
|
450 * Tests the flash data source get flash buffer |
|
451 */ |
|
452 void CFlashDataSourceWrapper::DoCmd_GetFlashBuffer_L() |
|
453 { |
|
454 INFO_PRINTF1(_L("Testing CFlashDataSource::GetFlashBuffer()")); |
|
455 |
|
456 //Ensure that the buffer has been created |
|
457 INFO_PRINTF1(_L("Ensuring the buffer has been succesfully created")); |
|
458 |
|
459 TDes8& buf = iObject->GetFlashBuffer(); |
|
460 |
|
461 if(KInitialBufferSize != buf.Size()) |
|
462 { |
|
463 ERR_PRINTF1(_L("Buffer was not created")); |
|
464 SetBlockResult(EFail); |
|
465 return; |
|
466 } |
|
467 } |
|
468 |
|
469 /** |
|
470 * Tests that we correctly process the crash header |
|
471 */ |
|
472 void CFlashDataSourceWrapper::DoCmd_ProcessCrashHeader1_L() |
|
473 { |
|
474 INFO_PRINTF1(_L("Testing CFlashDataSource::ProcessCrashHeader() - 1st Test")); |
|
475 |
|
476 TInt64 tid = 22; |
|
477 |
|
478 iContextHdr.iNumRegisters = 0; |
|
479 iInfHdr.iFlashAlign = FLASH_ALIGN; |
|
480 iInfHdr.iTid = tid; |
|
481 iInfHdr.iCrashId = CRASH_ID; |
|
482 |
|
483 TInt logSz = iInfHdr.GetSize() + iContextHdr.GetSize() + iOffsetsHdr.GetSize(); |
|
484 iInfHdr.iLogSize = logSz; |
|
485 |
|
486 TInt bufLength = TCrashInfoHeader::KSCMCrashInfoMaxSize + TCrashOffsetsHeader::KSCMCrashOffsetsMaxSize + TRegisterSet::KSCMRegisterSetMaxSize + KMaxCacheSize; |
|
487 RBuf8 data; |
|
488 data.CreateL(bufLength); |
|
489 data.SetLength(bufLength); |
|
490 data.CleanupClosePushL(); |
|
491 |
|
492 TByteStreamWriter writer(const_cast<TUint8*>(data.Ptr()), EFalse); |
|
493 |
|
494 iInfHdr.Serialize(writer); |
|
495 iOffsetsHdr.Serialize(writer); |
|
496 iContextHdr.Serialize(writer); |
|
497 |
|
498 INFO_PRINTF1(_L("Writing header to flash")); |
|
499 |
|
500 TUint32 size = 0; |
|
501 User::LeaveIfError(iSecSess.WriteCrashConfig(START_OF_FLASH, data, size)); |
|
502 |
|
503 CleanupStack::PopAndDestroy(); |
|
504 |
|
505 INFO_PRINTF1(_L("Processing crash header")); |
|
506 |
|
507 TRAPD(err, iObject->AnalyseCrashL(CRASH_ID)); |
|
508 if(KErrNone != err) |
|
509 { |
|
510 ERR_PRINTF2(_L("Failed to process crash log: [%d]"), err); |
|
511 SetBlockResult(EFail); |
|
512 return; |
|
513 } |
|
514 |
|
515 //Read the buffer back |
|
516 TDes8& buf = iObject->GetFlashBuffer(); |
|
517 |
|
518 INFO_PRINTF1(_L("Ensuring crash header read back is correct")); |
|
519 |
|
520 //Test our getters work correctly too |
|
521 if(tid != iObject->GetCrashedThreadId()) |
|
522 { |
|
523 ERR_PRINTF1(_L("Unable to Get Crashed Thread ID from header")); |
|
524 SetBlockResult(EFail); |
|
525 return; |
|
526 } |
|
527 |
|
528 if(FLASH_ALIGN != iObject->GetFlashAlignment()) |
|
529 { |
|
530 ERR_PRINTF1(_L("Unable to Get Correct flash alignment from header")); |
|
531 SetBlockResult(EFail); |
|
532 return; |
|
533 } |
|
534 |
|
535 if(logSz != iObject->GetCrashLogSize()) |
|
536 { |
|
537 ERR_PRINTF1(_L("Unable to Get correct log size from header")); |
|
538 SetBlockResult(EFail); |
|
539 return; |
|
540 } |
|
541 |
|
542 INFO_PRINTF1(_L("All is good. Move along now.")); |
|
543 } |
|
544 |
|
545 /** |
|
546 * Negative test to make sure if there is no header we get told so |
|
547 */ |
|
548 void CFlashDataSourceWrapper::DoCmd_ProcessCrashHeader2_L() |
|
549 { |
|
550 INFO_PRINTF1(_L("Testing CFlashDataSource::ProcessCrashHeader() - 2nd Test")); |
|
551 |
|
552 //write a struct that isnt TCrashInfoHeader |
|
553 TProcessData dummy; |
|
554 TPtr8 data((TUint8*)&dummy, sizeof(TProcessData), sizeof(TProcessData)); |
|
555 |
|
556 TUint32 size = 0; |
|
557 |
|
558 INFO_PRINTF1(_L("Writing header to flash")); |
|
559 User::LeaveIfError(iSecSess.WriteCrashConfig(START_OF_FLASH, data, size)); |
|
560 |
|
561 INFO_PRINTF1(_L("Processing crash header")); |
|
562 TRAPD(err, iObject->AnalyseCrashL(CRASH_ID)); |
|
563 if(KErrNotFound != err) |
|
564 { |
|
565 ERR_PRINTF2(_L("Process header should have been corrupt but wasnt [%d]"), err); |
|
566 SetBlockResult(EFail); |
|
567 return; |
|
568 } |
|
569 } |
|
570 |
|
571 /** |
|
572 * Tests we can succesfully read back known processes from flash |
|
573 */ |
|
574 void CFlashDataSourceWrapper::DoCmd_GetProcessListL1_Test_L() |
|
575 { |
|
576 INFO_PRINTF1(_L("Testing CFlashDataSource::GetProcessListL() - 1st test")); |
|
577 |
|
578 //We need to write some process data (will just do 2) to the flash, and update the header with its location |
|
579 TInt64 p1id = 100; |
|
580 TInt32 p1prior = 4; |
|
581 |
|
582 TInt64 p2id = 200; |
|
583 TInt32 p2prior = 5; |
|
584 |
|
585 //Process names |
|
586 _LIT8(KProc1, "t_proc1"); |
|
587 _LIT8(KProc2, "tproc2"); |
|
588 |
|
589 //buffer for data |
|
590 TInt bufLength = TCrashInfoHeader::KSCMCrashInfoMaxSize + TCrashOffsetsHeader::KSCMCrashOffsetsMaxSize + TRegisterSet::KSCMRegisterSetMaxSize + 2 * TProcessData::KSCMProcessDataMaxSize + KMaxCacheSize; |
|
591 RBuf8 data; |
|
592 data.CreateL(bufLength); |
|
593 data.SetLength(bufLength); |
|
594 data.CleanupClosePushL(); |
|
595 |
|
596 TByteStreamWriter writer(const_cast<TUint8*>(data.Ptr()), EFalse); |
|
597 |
|
598 TCrashOffsetsHeader hdr; |
|
599 hdr.iPLstOffset = sizeof(TCrashInfoHeader) + sizeof(TCrashOffsetsHeader); //starts right after headers |
|
600 |
|
601 //The first process data |
|
602 TProcessData proc1; |
|
603 proc1.iPid = p1id; |
|
604 proc1.iPriority = p1prior; |
|
605 proc1.iNamesize = KProc1().Size(); |
|
606 proc1.iName = KProc1; |
|
607 |
|
608 //The second process data |
|
609 TProcessData proc2; |
|
610 proc2.iPid = p2id; |
|
611 proc2.iPriority = p2prior; |
|
612 proc2.iNamesize = KProc2().Size(); |
|
613 proc2.iName = KProc2; |
|
614 |
|
615 iInfHdr.iCrashId = CRASH_ID; |
|
616 iContextHdr.iNumRegisters = 0; //no context |
|
617 iOffsetsHdr.iPLstOffset = iInfHdr.GetSize() + iOffsetsHdr.GetSize() + iContextHdr.GetSize(); //starts right after headers |
|
618 iInfHdr.iLogSize = iOffsetsHdr.iPLstOffset + proc1.GetSize() + proc2.GetSize(); |
|
619 |
|
620 INFO_PRINTF1(_L("Writing known processes to flash")); |
|
621 |
|
622 iInfHdr.Serialize(writer); |
|
623 iOffsetsHdr.Serialize(writer); |
|
624 iContextHdr.Serialize(writer); |
|
625 proc1.Serialize(writer); |
|
626 proc2.Serialize(writer); |
|
627 |
|
628 TUint32 written = 0; |
|
629 User::LeaveIfError(iSecSess.WriteCrashConfig(START_OF_FLASH, data ,written)); |
|
630 |
|
631 //Now we try get these processes back via GetProcessListL |
|
632 TRAPD(err, iObject->AnalyseCrashL(CRASH_ID)); |
|
633 if(KErrNone != err) |
|
634 { |
|
635 ERR_PRINTF2(_L("Failed to process crash header: [%d]"), err); |
|
636 SetBlockResult(EFail); |
|
637 CleanupStack::PopAndDestroy(); |
|
638 return; |
|
639 } |
|
640 |
|
641 RProcessPointerList *processList = new(ELeave)RProcessPointerList; |
|
642 TCleanupItem processCleanup(CFlashDataSource::CleanupProcessList, (TAny*)processList); |
|
643 CleanupStack::PushL(processCleanup); |
|
644 |
|
645 TUint wr = 0; |
|
646 |
|
647 INFO_PRINTF1(_L("Getting process list")); |
|
648 TRAP(err, iObject->GetProcessListL(*processList, wr)); |
|
649 if(KErrNone != err) |
|
650 { |
|
651 ERR_PRINTF2(_L("Failed to get process list: [%d]"), err); |
|
652 SetBlockResult(EFail); |
|
653 CleanupStack::PopAndDestroy(2); |
|
654 return; |
|
655 } |
|
656 |
|
657 if(processList->Count() != 2) |
|
658 { |
|
659 ERR_PRINTF2(_L("Didnt find the expected 2 processes. There were [%d] instead"), processList->Count()); |
|
660 SetBlockResult(EFail); |
|
661 CleanupStack::PopAndDestroy(2); |
|
662 return; |
|
663 } |
|
664 |
|
665 CProcessInfo* p1 = (*processList)[0]; |
|
666 CProcessInfo* p2 = (*processList)[1]; |
|
667 |
|
668 INFO_PRINTF1(_L("Retrieveing processes")); |
|
669 if(!p1 || !p2) |
|
670 { |
|
671 ERR_PRINTF1(_L("Failed to retrieve non null processes")); |
|
672 SetBlockResult(EFail); |
|
673 CleanupStack::PopAndDestroy(2); |
|
674 return; |
|
675 } |
|
676 |
|
677 INFO_PRINTF1(_L("Making sure processes are as expected")); |
|
678 |
|
679 //Check ID's |
|
680 if(p1->Id() != proc1.iPid || p2->Id() != proc2.iPid) |
|
681 { |
|
682 ERR_PRINTF1(_L("Failed to retrieve correct process ID's:")); |
|
683 ERR_PRINTF3(_L("P1 expected [%d] but found [%d]"), proc1.iPid, p1->Id()); |
|
684 ERR_PRINTF3(_L("P2 expected [%d] but found [%d]"), proc2.iPid, p2->Id()); |
|
685 SetBlockResult(EFail); |
|
686 CleanupStack::PopAndDestroy(2); |
|
687 return; |
|
688 } |
|
689 |
|
690 //check names |
|
691 RBuf wide; |
|
692 wide.CreateL(KProc1().Size()); |
|
693 wide.CleanupClosePushL(); |
|
694 wide.Copy(KProc1); |
|
695 |
|
696 INFO_PRINTF1(_L("Checking process 1 name is ok")); |
|
697 if( p1->Name().Compare(wide) != 0 ) |
|
698 { |
|
699 ERR_PRINTF3(_L("Wrong name retrieved, expected [%S] but got [%S]"), &KProc1, &wide); |
|
700 SetBlockResult(EFail); |
|
701 CleanupStack::PopAndDestroy(3); |
|
702 return; |
|
703 } |
|
704 |
|
705 wide.Copy(KProc2); |
|
706 |
|
707 INFO_PRINTF1(_L("Checking process 2 name is ok")); |
|
708 if( p2->Name().Compare(wide) != 0 ) |
|
709 { |
|
710 ERR_PRINTF3(_L("Wrong name retrieved, expected [%S] but got [%S]"), &KProc2, &wide); |
|
711 SetBlockResult(EFail); |
|
712 CleanupStack::PopAndDestroy(3); |
|
713 return; |
|
714 } |
|
715 |
|
716 INFO_PRINTF1(_L("All looks good")); |
|
717 |
|
718 CleanupStack::PopAndDestroy(3); |
|
719 |
|
720 } |
|
721 |
|
722 /** |
|
723 * Negative tests should the flash contain corrupt data |
|
724 */ |
|
725 void CFlashDataSourceWrapper::DoCmd_GetProcessListL2_Test_L() |
|
726 { |
|
727 INFO_PRINTF1(_L("Testing CFlashDataSource::GetProcessList() - 2nd test")); |
|
728 |
|
729 //buffer for data |
|
730 TInt bufLength = TCrashInfoHeader::KSCMCrashInfoMaxSize + TCrashOffsetsHeader::KSCMCrashOffsetsMaxSize + 3 * TRegisterSet::KSCMRegisterSetMaxSize + KMaxCacheSize; |
|
731 RBuf8 data; |
|
732 data.CreateL(bufLength); |
|
733 data.SetLength(bufLength); |
|
734 data.CleanupClosePushL(); |
|
735 |
|
736 TByteStreamWriter writer(const_cast<TUint8*>(data.Ptr()), EFalse); |
|
737 |
|
738 iInfHdr.iCrashId = CRASH_ID; |
|
739 iContextHdr.iNumRegisters = 0; //no context |
|
740 iOffsetsHdr.iPLstOffset = iInfHdr.GetSize() + iOffsetsHdr.GetSize() + iContextHdr.GetSize(); //starts right after headers |
|
741 iInfHdr.iLogSize = iOffsetsHdr.iPLstOffset + 2 * iContextHdr.GetSize(); |
|
742 |
|
743 INFO_PRINTF1(_L("Writing known processes to flash")); |
|
744 |
|
745 iInfHdr.Serialize(writer); |
|
746 iOffsetsHdr.Serialize(writer); |
|
747 iContextHdr.Serialize(writer); |
|
748 iContextHdr.Serialize(writer); |
|
749 iContextHdr.Serialize(writer); |
|
750 |
|
751 TUint32 written = 0; |
|
752 User::LeaveIfError(iSecSess.WriteCrashConfig(START_OF_FLASH, data ,written)); |
|
753 |
|
754 RProcessPointerList *processList = new(ELeave)RProcessPointerList; |
|
755 TCleanupItem processCleanup(CFlashDataSource::CleanupProcessList, (TAny*)processList); |
|
756 CleanupStack::PushL(processCleanup); |
|
757 |
|
758 |
|
759 INFO_PRINTF1(_L("Getting process list")); |
|
760 |
|
761 TRAPD(err, iObject->AnalyseCrashL(CRASH_ID)); |
|
762 if(KErrNone != err) |
|
763 { |
|
764 ERR_PRINTF2(_L("Unable to process header [%d]"), err); |
|
765 SetBlockResult(EFail); |
|
766 CleanupStack::PopAndDestroy(2); |
|
767 return; |
|
768 } |
|
769 |
|
770 |
|
771 TUint wr = 0; |
|
772 TRAP(err, iObject->GetProcessListL( *processList, wr)); |
|
773 if(KErrNone != err) |
|
774 { |
|
775 ERR_PRINTF2(_L("Should have retrieved zero sized process list"), err); |
|
776 SetBlockResult(EFail); |
|
777 CleanupStack::PopAndDestroy(2); |
|
778 return; |
|
779 } |
|
780 |
|
781 |
|
782 if(processList->Count() != 0) |
|
783 { |
|
784 ERR_PRINTF1(_L("Should have retrieved zero sized process list")); |
|
785 SetBlockResult(EFail); |
|
786 CleanupStack::PopAndDestroy(2); |
|
787 return; |
|
788 } |
|
789 |
|
790 INFO_PRINTF1(_L("Everything is as expected")); |
|
791 |
|
792 CleanupStack::PopAndDestroy(2); |
|
793 } |
|
794 |
|
795 /** |
|
796 * Tests to make sure we can get back a thread list (two here) from the flash |
|
797 */ |
|
798 void CFlashDataSourceWrapper::DoCmd_GetThreadListL1_Test_L() |
|
799 { |
|
800 INFO_PRINTF1(_L("Testing CFlashDataSource::GetThreadListL() 1st Test - System wide thread list")); |
|
801 |
|
802 //We need to write some thread data (will just do 2) to the flash, and update the header with its location |
|
803 TInt64 t1id = 100; |
|
804 TInt32 t1prior = 4; |
|
805 TInt32 t1SvcSp = 20; |
|
806 TInt32 t1UsrStkSize = 40; |
|
807 |
|
808 TInt64 t2id = 200; |
|
809 TInt32 t2prior = 5; |
|
810 TInt32 t2SvcSp = 25; |
|
811 TInt32 t2UsrStkSize = 47; |
|
812 |
|
813 //thread names |
|
814 _LIT8(KThread1, "t_thread1"); |
|
815 _LIT8(KThread2, "thread2"); |
|
816 |
|
817 //buffer for data |
|
818 TInt bufLength = TCrashInfoHeader::KSCMCrashInfoMaxSize + TCrashOffsetsHeader::KSCMCrashOffsetsMaxSize + |
|
819 TRegisterSet::KSCMRegisterSetMaxSize + 2 * TThreadData::KSCMThreadDataMaxSize + |
|
820 KMaxCacheSize; |
|
821 |
|
822 RBuf8 data; |
|
823 data.CreateL(bufLength); |
|
824 data.SetLength(bufLength); |
|
825 data.CleanupClosePushL(); |
|
826 |
|
827 TByteStreamWriter writer(const_cast<TUint8*>(data.Ptr()), EFalse); |
|
828 |
|
829 TInt owner1 = 100; |
|
830 TInt owner2 = 200; |
|
831 |
|
832 //The first thread data |
|
833 TThreadData t1; |
|
834 t1.iTid = t1id; |
|
835 t1.iPriority = t1prior; |
|
836 t1.iSvcSP = t1SvcSp; |
|
837 t1.iUsrStacksize = t1UsrStkSize; |
|
838 t1.iNamesize = KThread1().Size(); |
|
839 t1.iName = KThread1; |
|
840 t1.iOwnerId = owner1; |
|
841 |
|
842 //The second thread data |
|
843 TThreadData t2; |
|
844 t2.iTid = t2id; |
|
845 t2.iPriority = t2prior; |
|
846 t2.iSvcSP = t2SvcSp; |
|
847 t2.iUsrStacksize = t2UsrStkSize; |
|
848 t2.iNamesize = KThread2().Size(); |
|
849 t2.iName = KThread2; |
|
850 t2.iOwnerId = owner2; |
|
851 |
|
852 iInfHdr.iCrashId = CRASH_ID; |
|
853 iContextHdr.iNumRegisters = 0; //no context |
|
854 iOffsetsHdr.iTLstOffset = iInfHdr.GetSize() + iOffsetsHdr.GetSize() + iContextHdr.GetSize(); //starts right after headers |
|
855 iInfHdr.iLogSize = iOffsetsHdr.iTLstOffset + t1.GetSize() + t2.GetSize(); |
|
856 |
|
857 iInfHdr.Serialize(writer); |
|
858 iOffsetsHdr.Serialize(writer); |
|
859 iContextHdr.Serialize(writer); |
|
860 t1.Serialize(writer); |
|
861 t2.Serialize(writer); |
|
862 |
|
863 TUint32 written = 0; |
|
864 User::LeaveIfError(iSecSess.WriteCrashConfig(START_OF_FLASH, data ,written)); |
|
865 |
|
866 //Now we try get these threads back via GetThreadListL |
|
867 TRAPD(err, iObject->AnalyseCrashL(CRASH_ID)); |
|
868 if(KErrNone != err) |
|
869 { |
|
870 ERR_PRINTF2(_L("Failed to process crash header: [%d]"), err); |
|
871 SetBlockResult(EFail); |
|
872 CleanupStack::PopAndDestroy(); |
|
873 return; |
|
874 } |
|
875 |
|
876 RThreadPointerList *threadList = new(ELeave)RThreadPointerList; |
|
877 TCleanupItem threadCleanup(CFlashDataSource::CleanupThreadList, (TAny*)threadList); |
|
878 CleanupStack::PushL(threadCleanup); |
|
879 |
|
880 TUint wr = 0; |
|
881 |
|
882 INFO_PRINTF1(_L("Getting thread list")); |
|
883 TRAP(err, iObject->GetThreadListL(((TUint64)-1), *threadList, wr)); |
|
884 if(KErrNone != err) |
|
885 { |
|
886 ERR_PRINTF2(_L("Failed to get thread list: [%d]"), err); |
|
887 SetBlockResult(EFail); |
|
888 CleanupStack::PopAndDestroy(2); |
|
889 return; |
|
890 } |
|
891 |
|
892 if(threadList->Count() != 2) |
|
893 { |
|
894 ERR_PRINTF1(_L("Retrieved wrong number of threads")); |
|
895 SetBlockResult(EFail); |
|
896 CleanupStack::PopAndDestroy(2); |
|
897 return; |
|
898 } |
|
899 |
|
900 CThreadInfo* ti1 = (*threadList)[0]; |
|
901 CThreadInfo* ti2 = (*threadList)[1]; |
|
902 |
|
903 INFO_PRINTF1(_L("Retrieveing threads")); |
|
904 if(!ti1 || !ti2) |
|
905 { |
|
906 ERR_PRINTF1(_L("Failed to retrieve non null threads")); |
|
907 SetBlockResult(EFail); |
|
908 CleanupStack::PopAndDestroy(2); |
|
909 return; |
|
910 } |
|
911 |
|
912 INFO_PRINTF1(_L("Making sure processes are as expected")); |
|
913 |
|
914 //Check ID's |
|
915 if(ti1->Id() != t1.iTid || ti2->Id() != t2.iTid) |
|
916 { |
|
917 ERR_PRINTF1(_L("Failed to retrieve correct thread ID's:")); |
|
918 ERR_PRINTF3(_L("T1 expected [%d] but found [%d]"), t1.iTid, ti1->Id()); |
|
919 ERR_PRINTF3(_L("T2 expected [%d] but found [%d]"), t2.iTid, ti2->Id()); |
|
920 SetBlockResult(EFail); |
|
921 CleanupStack::PopAndDestroy(2); |
|
922 return; |
|
923 } |
|
924 |
|
925 //check names |
|
926 RBuf wide; |
|
927 wide.CreateL(KThread1().Size()); |
|
928 wide.CleanupClosePushL(); |
|
929 wide.Copy(KThread1); |
|
930 |
|
931 INFO_PRINTF1(_L("Checking thread 1 name is ok")); |
|
932 if( ti1->Name().Compare(wide) != 0 ) |
|
933 { |
|
934 ERR_PRINTF3(_L("Wrong name retrieved, expected [%S] but got [%S]"), &KThread1, &wide); |
|
935 SetBlockResult(EFail); |
|
936 CleanupStack::PopAndDestroy(3); |
|
937 return; |
|
938 } |
|
939 |
|
940 if(KThread2().Size() > wide.Size()) |
|
941 { |
|
942 wide.ReAllocL(KThread2().Size()); |
|
943 } |
|
944 wide.Copy(KThread2); |
|
945 |
|
946 INFO_PRINTF1(_L("Checking thread 2 name is ok")); |
|
947 if( ti2->Name().Compare(wide) != 0 ) |
|
948 { |
|
949 ERR_PRINTF3(_L("Wrong name retrieved, expected [%S] but got [%S]"), &KThread2, &wide); |
|
950 SetBlockResult(EFail); |
|
951 CleanupStack::PopAndDestroy(3); |
|
952 return; |
|
953 } |
|
954 |
|
955 INFO_PRINTF1(_L("All looks good")); |
|
956 |
|
957 CleanupStack::PopAndDestroy(3); |
|
958 |
|
959 } |
|
960 |
|
961 /** |
|
962 * Looks at a process specific thread list |
|
963 */ |
|
964 void CFlashDataSourceWrapper::DoCmd_GetThreadListL3_Test_L() |
|
965 { |
|
966 INFO_PRINTF1(_L("Testing CFlashDataSource::GetThreadListL() 3rd Test - Process specific thread list")); |
|
967 |
|
968 //We need to write some thread data (will just do 2) to the flash, and update the header with its location |
|
969 TInt64 t1id = 100; |
|
970 TInt32 t1prior = 4; |
|
971 TInt32 t1SvcSp = 20; |
|
972 TInt32 t1UsrStkSize = 40; |
|
973 |
|
974 TInt64 t2id = 200; |
|
975 TInt32 t2prior = 5; |
|
976 TInt32 t2SvcSp = 25; |
|
977 TInt32 t2UsrStkSize = 47; |
|
978 |
|
979 //thread names |
|
980 _LIT8(KThread1, "t_thread1"); |
|
981 _LIT8(KThread2, "thread2"); |
|
982 |
|
983 //buffer for data |
|
984 TInt bufLength = TCrashInfoHeader::KSCMCrashInfoMaxSize + TCrashOffsetsHeader::KSCMCrashOffsetsMaxSize + |
|
985 TRegisterSet::KSCMRegisterSetMaxSize + 2 * TThreadData::KSCMThreadDataMaxSize + |
|
986 KMaxCacheSize; |
|
987 |
|
988 RBuf8 data; |
|
989 data.CreateL(bufLength); |
|
990 data.SetLength(bufLength); |
|
991 data.CleanupClosePushL(); |
|
992 |
|
993 TByteStreamWriter writer(const_cast<TUint8*>(data.Ptr()), EFalse); |
|
994 |
|
995 TInt owner1 = 100; |
|
996 TInt owner2 = 200; |
|
997 |
|
998 //The first thread data |
|
999 TThreadData t1; |
|
1000 t1.iTid = t1id; |
|
1001 t1.iPriority = t1prior; |
|
1002 t1.iSvcSP = t1SvcSp; |
|
1003 t1.iUsrStacksize = t1UsrStkSize; |
|
1004 t1.iNamesize = KThread1().Size(); |
|
1005 t1.iName = KThread1; |
|
1006 t1.iOwnerId = owner1; |
|
1007 |
|
1008 //The second thread data |
|
1009 TThreadData t2; |
|
1010 t2.iTid = t2id; |
|
1011 t2.iPriority = t2prior; |
|
1012 t2.iSvcSP = t2SvcSp; |
|
1013 t2.iUsrStacksize = t2UsrStkSize; |
|
1014 t2.iNamesize = KThread2().Size(); |
|
1015 t2.iName = KThread2; |
|
1016 t2.iOwnerId = owner2; |
|
1017 |
|
1018 iInfHdr.iCrashId = CRASH_ID; |
|
1019 iContextHdr.iNumRegisters = 0; //no context |
|
1020 iOffsetsHdr.iTLstOffset = iInfHdr.GetSize() + iOffsetsHdr.GetSize() + iContextHdr.GetSize(); //starts right after headers |
|
1021 iInfHdr.iLogSize = iOffsetsHdr.iTLstOffset + t1.GetSize() + t2.GetSize(); |
|
1022 |
|
1023 iInfHdr.Serialize(writer); |
|
1024 iOffsetsHdr.Serialize(writer); |
|
1025 iContextHdr.Serialize(writer); |
|
1026 t1.Serialize(writer); |
|
1027 t2.Serialize(writer); |
|
1028 |
|
1029 TUint32 written = 0; |
|
1030 User::LeaveIfError(iSecSess.WriteCrashConfig(START_OF_FLASH, data ,written)); |
|
1031 |
|
1032 //Now we try get these threads back via GetThreadListL |
|
1033 TRAPD(err, iObject->AnalyseCrashL(CRASH_ID)); |
|
1034 if(KErrNone != err) |
|
1035 { |
|
1036 ERR_PRINTF2(_L("Failed to process crash header: [%d]"), err); |
|
1037 SetBlockResult(EFail); |
|
1038 CleanupStack::PopAndDestroy(); |
|
1039 return; |
|
1040 } |
|
1041 |
|
1042 RThreadPointerList *threadList = new(ELeave)RThreadPointerList; |
|
1043 TCleanupItem threadCleanup(CFlashDataSource::CleanupThreadList, (TAny*)threadList); |
|
1044 CleanupStack::PushL(threadCleanup); |
|
1045 |
|
1046 TUint wr = 0; |
|
1047 |
|
1048 INFO_PRINTF1(_L("Getting thread list")); |
|
1049 TRAP(err, iObject->GetThreadListL(owner1, *threadList, wr)); |
|
1050 if(KErrNone != err) |
|
1051 { |
|
1052 ERR_PRINTF2(_L("Failed to get thread list: [%d]"), err); |
|
1053 SetBlockResult(EFail); |
|
1054 CleanupStack::PopAndDestroy(2); |
|
1055 return; |
|
1056 } |
|
1057 |
|
1058 if(threadList->Count() != 1) |
|
1059 { |
|
1060 ERR_PRINTF1(_L("Retrieved wrong number of threads")); |
|
1061 SetBlockResult(EFail); |
|
1062 CleanupStack::PopAndDestroy(2); |
|
1063 return; |
|
1064 } |
|
1065 |
|
1066 CThreadInfo* ti1 = (*threadList)[0]; |
|
1067 |
|
1068 INFO_PRINTF1(_L("Retrieveing threads")); |
|
1069 if(!ti1) |
|
1070 { |
|
1071 ERR_PRINTF1(_L("Failed to retrieve non null threads")); |
|
1072 SetBlockResult(EFail); |
|
1073 CleanupStack::PopAndDestroy(2); |
|
1074 return; |
|
1075 } |
|
1076 |
|
1077 INFO_PRINTF1(_L("Making sure processes are as expected")); |
|
1078 |
|
1079 //Check ID's |
|
1080 if(ti1->Id() != t1.iTid) |
|
1081 { |
|
1082 ERR_PRINTF1(_L("Failed to retrieve correct thread ID's:")); |
|
1083 ERR_PRINTF3(_L("T1 expected [%d] but found [%d]"), t1.iTid, ti1->Id()); |
|
1084 SetBlockResult(EFail); |
|
1085 CleanupStack::PopAndDestroy(2); |
|
1086 return; |
|
1087 } |
|
1088 |
|
1089 //check names |
|
1090 RBuf wide; |
|
1091 wide.CreateL(KThread1().Size()); |
|
1092 wide.CleanupClosePushL(); |
|
1093 wide.Copy(KThread1); |
|
1094 |
|
1095 INFO_PRINTF1(_L("Checking thread 1 name is ok")); |
|
1096 if( ti1->Name().Compare(wide) != 0 ) |
|
1097 { |
|
1098 ERR_PRINTF3(_L("Wrong name retrieved, expected [%S] but got [%S]"), &KThread1, &wide); |
|
1099 SetBlockResult(EFail); |
|
1100 CleanupStack::PopAndDestroy(3); |
|
1101 return; |
|
1102 } |
|
1103 |
|
1104 INFO_PRINTF1(_L("All looks good")); |
|
1105 |
|
1106 CleanupStack::PopAndDestroy(3); |
|
1107 |
|
1108 } |
|
1109 |
|
1110 |
|
1111 /** |
|
1112 * Negative tests should the flash contain corrupt data |
|
1113 */ |
|
1114 void CFlashDataSourceWrapper::DoCmd_GetThreadListL2_Test_L() |
|
1115 { |
|
1116 INFO_PRINTF1(_L("Testing CFlashDataSource::GetThreadList() - 2nd test")); |
|
1117 |
|
1118 //buffer for data |
|
1119 TInt bufLength = TCrashInfoHeader::KSCMCrashInfoMaxSize + TCrashOffsetsHeader::KSCMCrashOffsetsMaxSize + 3 * TRegisterSet::KSCMRegisterSetMaxSize + KMaxCacheSize; |
|
1120 RBuf8 data; |
|
1121 data.CreateL(bufLength); |
|
1122 data.SetLength(bufLength); |
|
1123 data.CleanupClosePushL(); |
|
1124 |
|
1125 TByteStreamWriter writer(const_cast<TUint8*>(data.Ptr()), EFalse); |
|
1126 |
|
1127 iInfHdr.iCrashId = CRASH_ID; |
|
1128 iContextHdr.iNumRegisters = 0; //no context |
|
1129 iOffsetsHdr.iTLstOffset = iInfHdr.GetSize() + iOffsetsHdr.GetSize() + iContextHdr.GetSize(); //starts right after headers |
|
1130 iInfHdr.iLogSize = iOffsetsHdr.iTLstOffset + 2 * iContextHdr.GetSize(); |
|
1131 |
|
1132 INFO_PRINTF1(_L("Writing known processes to flash")); |
|
1133 |
|
1134 iInfHdr.Serialize(writer); |
|
1135 iOffsetsHdr.Serialize(writer); |
|
1136 iContextHdr.Serialize(writer); |
|
1137 iContextHdr.Serialize(writer); |
|
1138 iContextHdr.Serialize(writer); |
|
1139 |
|
1140 TUint32 written = 0; |
|
1141 User::LeaveIfError(iSecSess.WriteCrashConfig(START_OF_FLASH, data ,written)); |
|
1142 |
|
1143 RThreadPointerList *threadList = new(ELeave)RThreadPointerList; |
|
1144 TCleanupItem threadCleanup(CFlashDataSource::CleanupThreadList, (TAny*)threadList); |
|
1145 CleanupStack::PushL(threadCleanup); |
|
1146 |
|
1147 |
|
1148 INFO_PRINTF1(_L("Getting thread list")); |
|
1149 |
|
1150 TRAPD(err, iObject->AnalyseCrashL(CRASH_ID)); |
|
1151 if(KErrNone != err) |
|
1152 { |
|
1153 ERR_PRINTF2(_L("Unable to process header [%d]"), err); |
|
1154 SetBlockResult(EFail); |
|
1155 CleanupStack::PopAndDestroy(2); |
|
1156 return; |
|
1157 } |
|
1158 |
|
1159 TUint wr = 0; |
|
1160 TRAP(err, iObject->GetThreadListL(START_OF_FLASH, *threadList, wr)); |
|
1161 |
|
1162 if(threadList->Count() != 0) |
|
1163 { |
|
1164 ERR_PRINTF1(_L("Should have retrieved zero sized thread list")); |
|
1165 SetBlockResult(EFail); |
|
1166 CleanupStack::PopAndDestroy(2); |
|
1167 return; |
|
1168 } |
|
1169 |
|
1170 INFO_PRINTF1(_L("Everything is as expected")); |
|
1171 |
|
1172 CleanupStack::PopAndDestroy(2); |
|
1173 |
|
1174 } |
|
1175 |
|
1176 /** |
|
1177 * Tests we can read registers back from the flash succesfully |
|
1178 */ |
|
1179 void CFlashDataSourceWrapper::DoCmd_ReadRegistersL1_Test_L() |
|
1180 { |
|
1181 |
|
1182 /** |
|
1183 * The 3 different register sets corrospond to the 3 different register related configuration |
|
1184 * options: |
|
1185 * ECrashedThreadFullRegisters starts from iCTFullReg |
|
1186 * EThreadsUsrRegisters starts from iSysSvrReg |
|
1187 * EThreadsSvrRegisters starts from iSysUsrReg |
|
1188 * |
|
1189 * Are going to write the following data to flash: |
|
1190 * |
|
1191 * |--TCrashHeader--||--TRegisterValue--| ... |--TRegisterValue--| at the ECrashedThreadFullRegisters point |
|
1192 * <-- For a crashed thread --> |
|
1193 * |--TRegisterValue--| ... |--TRegisterValue--| at the EThreadsUsrRegisters point |
|
1194 * <-- For a system thread (at user registers point) --> |
|
1195 * |--TRegisterValue--| ... |--TRegisterValue--| at the EThreadsSvrRegisters point |
|
1196 * <-- For a system thread (at svr register point) --> |
|
1197 */ |
|
1198 |
|
1199 INFO_PRINTF1(_L("Testing CFlashDataSource::ReadRegistersL() Test1")); |
|
1200 |
|
1201 TThreadId crashedThread = TThreadId(139); //arbitrary vals |
|
1202 TThreadId otherThread = TThreadId(15); //arbitrary vals |
|
1203 |
|
1204 //buffer for data |
|
1205 TInt bufLength = TCrashInfoHeader::KSCMCrashInfoMaxSize + TCrashOffsetsHeader::KSCMCrashOffsetsMaxSize + 6 * TRegisterValue::KSCMRegisterValueMaxSize + KMaxCacheSize; |
|
1206 RBuf8 data; |
|
1207 data.CreateL(bufLength); |
|
1208 data.SetLength(bufLength); |
|
1209 data.CleanupClosePushL(); |
|
1210 |
|
1211 TByteStreamWriter writer(const_cast<TUint8*>(data.Ptr()), EFalse); |
|
1212 |
|
1213 //Headers - as much as we need |
|
1214 iInfHdr.iTid = crashedThread.Id(); |
|
1215 iInfHdr.iCrashId = CRASH_ID; |
|
1216 iOffsetsHdr.iCTFullRegOffset = iInfHdr.GetSize() + iOffsetsHdr.GetSize() + iContextHdr.GetSize(); //starts right after headers |
|
1217 iContextHdr.iNumRegisters = 0; //no context |
|
1218 |
|
1219 //For this test we will put in 2 registers for each config option |
|
1220 TRegisterValue r1; |
|
1221 r1.iValue32 = 0xDEADDEAA; |
|
1222 r1.iOwnId = crashedThread.Id(); |
|
1223 |
|
1224 TRegisterValue r2; |
|
1225 r2.iValue32 = 0xDEADEADB; |
|
1226 r2.iOwnId = crashedThread.Id(); |
|
1227 |
|
1228 TRegisterValue r3; |
|
1229 r3.iValue32 = 0xDEADEADC; |
|
1230 r3.iOwnId = otherThread.Id(); |
|
1231 |
|
1232 TRegisterValue r4; |
|
1233 r4.iValue32 = 0xDEADEADD; |
|
1234 r4.iOwnId = otherThread.Id(); |
|
1235 |
|
1236 TRegisterValue r5; |
|
1237 r5.iValue32 = 0xDEADEADE; |
|
1238 r5.iOwnId = otherThread.Id(); |
|
1239 |
|
1240 TRegisterValue r6; |
|
1241 r6.iValue32 = 0xDEADEADF; |
|
1242 r6.iOwnId = otherThread.Id(); |
|
1243 |
|
1244 iOffsetsHdr.iSysSvrRegOffset = iOffsetsHdr.iCTFullRegOffset + r1.GetSize() + r2.GetSize(); |
|
1245 iOffsetsHdr.iSysUsrRegOffset = iOffsetsHdr.iSysSvrRegOffset + r3.GetSize() + r4.GetSize(); |
|
1246 iInfHdr.iLogSize = iOffsetsHdr.iSysUsrRegOffset + r6.GetSize() + r5.GetSize(); |
|
1247 |
|
1248 iInfHdr.Serialize(writer); |
|
1249 iOffsetsHdr.Serialize(writer); |
|
1250 iContextHdr.Serialize(writer); |
|
1251 r1.Serialize(writer); |
|
1252 r2.Serialize(writer); |
|
1253 r3.Serialize(writer); |
|
1254 r4.Serialize(writer); |
|
1255 r5.Serialize(writer); |
|
1256 r6.Serialize(writer); |
|
1257 |
|
1258 INFO_PRINTF1(_L("Writing known registers to flash")); |
|
1259 |
|
1260 TUint32 written = 0; |
|
1261 User::LeaveIfError(iSecSess.WriteCrashConfig(0, data ,written)); |
|
1262 |
|
1263 //Now we try and get them back via ReadRegistersL |
|
1264 RRegisterList regList; |
|
1265 CleanupClosePushL(regList); |
|
1266 |
|
1267 INFO_PRINTF1(_L("Reading back registers")); |
|
1268 |
|
1269 TRAPD(err, iObject->AnalyseCrashL(1)); |
|
1270 if(KErrNone != err) |
|
1271 { |
|
1272 ERR_PRINTF2(_L("Failed to analyse crash header: [%d]"), err); |
|
1273 SetBlockResult(EFail); |
|
1274 CleanupStack::PopAndDestroy(2); |
|
1275 return; |
|
1276 } |
|
1277 |
|
1278 //Read for crashed thread first (hard coded in the absence of TSymbianInfo for now) |
|
1279 TRAP(err, iObject->ReadRegistersL(crashedThread.Id(), regList)); |
|
1280 if(KErrNone != err) |
|
1281 { |
|
1282 ERR_PRINTF2(_L("Unable to read registers: [%d]"), err); |
|
1283 SetBlockResult(EFail); |
|
1284 CleanupStack::PopAndDestroy(2); |
|
1285 return; |
|
1286 } |
|
1287 |
|
1288 if(regList.Count() != 2) |
|
1289 { |
|
1290 ERR_PRINTF2(_L("Got wrong amount of registers back: [%d]"), regList.Count()); |
|
1291 SetBlockResult(EFail); |
|
1292 CleanupStack::PopAndDestroy(2); |
|
1293 return; |
|
1294 } |
|
1295 |
|
1296 if(regList[0].iValue32 != r1.iValue32 || regList[1].iValue32 != r2.iValue32) |
|
1297 { |
|
1298 ERR_PRINTF1(_L("Got wrong register values back")); |
|
1299 ERR_PRINTF3(_L("\tExpected Expected [0x%X] but got [0x%X]"),r1.iValue32,regList[0].iValue32); |
|
1300 ERR_PRINTF3(_L("\tExpected Expected [0x%X] but got [0x%X]"),r2.iValue32,regList[1].iValue32); |
|
1301 |
|
1302 SetBlockResult(EFail); |
|
1303 CleanupStack::PopAndDestroy(2); |
|
1304 return; |
|
1305 } |
|
1306 |
|
1307 //and for "system" thread |
|
1308 TRAP(err, iObject->ReadRegistersL(otherThread.Id(), regList)); |
|
1309 if(KErrNone != err) |
|
1310 { |
|
1311 ERR_PRINTF2(_L("Unable to read registers: [%d]"), err); |
|
1312 SetBlockResult(EFail); |
|
1313 CleanupStack::PopAndDestroy(2); |
|
1314 return; |
|
1315 } |
|
1316 |
|
1317 if(regList.Count() != 4) |
|
1318 { |
|
1319 ERR_PRINTF2(_L("Got wrong amount of registers back: [%d]"), regList.Count()); |
|
1320 SetBlockResult(EFail); |
|
1321 CleanupStack::PopAndDestroy(2); |
|
1322 return; |
|
1323 } |
|
1324 |
|
1325 if(regList[0].iValue32 != r3.iValue32 |
|
1326 || regList[1].iValue32 != r4.iValue32 |
|
1327 || regList[2].iValue32 != r5.iValue32 |
|
1328 || regList[3].iValue32 != r6.iValue32) |
|
1329 { |
|
1330 ERR_PRINTF1(_L("Got wrong register values back")); |
|
1331 ERR_PRINTF3(_L("\tExpected Expected [0x%X] but got [0x%X]"),r3.iValue32,regList[0].iValue32); |
|
1332 ERR_PRINTF3(_L("\tExpected Expected [0x%X] but got [0x%X]"),r4.iValue32,regList[1].iValue32); |
|
1333 ERR_PRINTF3(_L("\tExpected Expected [0x%X] but got [0x%X]"),r5.iValue32,regList[2].iValue32); |
|
1334 ERR_PRINTF3(_L("\tExpected Expected [0x%X] but got [0x%X]"),r6.iValue32,regList[3].iValue32); |
|
1335 |
|
1336 SetBlockResult(EFail); |
|
1337 CleanupStack::PopAndDestroy(2); |
|
1338 return; |
|
1339 } |
|
1340 |
|
1341 INFO_PRINTF1(_L("Got back all registers as expected")); |
|
1342 |
|
1343 CleanupStack::PopAndDestroy(2); |
|
1344 } |
|
1345 |
|
1346 /** |
|
1347 * Tests that we can read memory from the crash log |
|
1348 */ |
|
1349 void CFlashDataSourceWrapper::DoCmd_ReadMemoryL1_Test_L() |
|
1350 { |
|
1351 INFO_PRINTF1(_L("Testing CFlashDataSource::ReadMemoryL() Test1")); |
|
1352 |
|
1353 //buffer to hold memory |
|
1354 TInt32 numBytes = 8; //we will dump 8 bytes of memory |
|
1355 TUint8 memoryToDump = 0xAB; |
|
1356 |
|
1357 RBuf8 mem; |
|
1358 mem.CreateL(numBytes * sizeof(TUint8)); |
|
1359 mem.CleanupClosePushL(); |
|
1360 |
|
1361 for(TInt cnt = numBytes -1; cnt >= 0; cnt--) |
|
1362 { |
|
1363 mem.Append(&memoryToDump, sizeof(TUint8)); |
|
1364 } |
|
1365 |
|
1366 //buffer to hold log |
|
1367 TInt dataLength = TCrashInfoHeader::KSCMCrashInfoMaxSize + TCrashOffsetsHeader::KSCMCrashOffsetsMaxSize + TRegisterSet::KSCMRegisterSetMaxSize + numBytes + TMemoryDump::KSCMMemDumpMaxSize + TRawData::KSCMRawDataMaxSize; |
|
1368 |
|
1369 RBuf8 data; |
|
1370 data.CreateL(dataLength); |
|
1371 data.SetLength(dataLength); |
|
1372 data.CleanupClosePushL(); |
|
1373 |
|
1374 TByteStreamWriter writer(const_cast<TUint8*>(data.Ptr()), EFalse); |
|
1375 |
|
1376 TUint32 startAdd = 0x10000000; |
|
1377 TUint64 procId = 100; |
|
1378 |
|
1379 TMemoryDump memDump; |
|
1380 memDump.iStartAddress = startAdd; |
|
1381 memDump.iPid = procId; |
|
1382 memDump.iLength = mem.Length(); |
|
1383 |
|
1384 TRawData rawData; |
|
1385 rawData.iLength = mem.Length(); |
|
1386 rawData.iData.Set(mem.MidTPtr(0)); |
|
1387 |
|
1388 TInt32 crashSize = iInfHdr.GetSize() + iOffsetsHdr.GetSize() + iContextHdr.GetSize() + memDump.GetSize() + rawData.GetSize(); |
|
1389 iInfHdr.iLogSize = crashSize; |
|
1390 iInfHdr.iCrashId = CRASH_ID; |
|
1391 |
|
1392 iInfHdr.Serialize(writer); |
|
1393 iOffsetsHdr.Serialize(writer); |
|
1394 iContextHdr.Serialize(writer); |
|
1395 memDump.Serialize(writer); |
|
1396 rawData.Serialize(writer); |
|
1397 |
|
1398 INFO_PRINTF1(_L("Writing known memory to flash")); |
|
1399 |
|
1400 TUint32 written = 0; |
|
1401 User::LeaveIfError(iSecSess.WriteCrashConfig(START_OF_FLASH, data ,written)); |
|
1402 |
|
1403 TRAPD(err, iObject->AnalyseCrashL(CRASH_ID)); |
|
1404 if(KErrNone != err) |
|
1405 { |
|
1406 ERR_PRINTF2(_L("Unable to analyse crash: [%d]"), err); |
|
1407 SetBlockResult(EFail); |
|
1408 CleanupStack::PopAndDestroy(2); |
|
1409 return; |
|
1410 } |
|
1411 |
|
1412 RBuf8 found; |
|
1413 found.CreateL(mem.Length()); |
|
1414 found.CleanupClosePushL(); |
|
1415 |
|
1416 |
|
1417 //We read memory by thread ID. So we will create an arbitrary thread and assign it to belong to the |
|
1418 //process ID we have dumped memory for |
|
1419 TInt64 threadId = 23; |
|
1420 iObject->AssignOwner(procId, threadId); |
|
1421 |
|
1422 TRAP(err, iObject->ReadMemoryL(threadId, startAdd, mem.Length(), found)); |
|
1423 if(KErrNone != err) |
|
1424 { |
|
1425 ERR_PRINTF2(_L("Unable to read memory: [%d]"), err); |
|
1426 SetBlockResult(EFail); |
|
1427 CleanupStack::PopAndDestroy(3); |
|
1428 return; |
|
1429 } |
|
1430 |
|
1431 for(TInt cnt = found.Length() -1; cnt >= 0; cnt--) |
|
1432 { |
|
1433 if(found[cnt] != memoryToDump) |
|
1434 { |
|
1435 ERR_PRINTF2(_L("Wrong memory returned = [0x%X]"),found[cnt]); |
|
1436 SetBlockResult(EFail); |
|
1437 CleanupStack::PopAndDestroy(3); |
|
1438 return; |
|
1439 } |
|
1440 } |
|
1441 |
|
1442 INFO_PRINTF1(_L("Got back all memory as expected")); |
|
1443 |
|
1444 CleanupStack::PopAndDestroy(3); |
|
1445 } |
|
1446 |
|
1447 /** |
|
1448 * Negative Tests to see we can handle dodgy params |
|
1449 */ |
|
1450 void CFlashDataSourceWrapper::DoCmd_ReadMemoryL2_Test_L() |
|
1451 { |
|
1452 INFO_PRINTF1(_L("Testing CFlashDataSource::ReadMemoryL() Test2")); |
|
1453 |
|
1454 //buffer to hold memory |
|
1455 TInt32 numBytes = 8; //we will dump 8 bytes of memory |
|
1456 TUint8 memoryToDump = 0xAB; |
|
1457 |
|
1458 RBuf8 mem; |
|
1459 mem.CreateL(numBytes * sizeof(TUint8)); |
|
1460 mem.CleanupClosePushL(); |
|
1461 |
|
1462 for(TInt cnt = numBytes -1; cnt >= 0; cnt--) |
|
1463 { |
|
1464 mem.Append(&memoryToDump, sizeof(TUint8)); |
|
1465 } |
|
1466 |
|
1467 //buffer to hold log |
|
1468 TInt dataLength = TCrashInfoHeader::KSCMCrashInfoMaxSize + TCrashOffsetsHeader::KSCMCrashOffsetsMaxSize + TRegisterSet::KSCMRegisterSetMaxSize + numBytes + TMemoryDump::KSCMMemDumpMaxSize + TRawData::KSCMRawDataMaxSize; |
|
1469 |
|
1470 RBuf8 data; |
|
1471 data.CreateL(dataLength); |
|
1472 data.SetLength(dataLength); |
|
1473 data.CleanupClosePushL(); |
|
1474 |
|
1475 TByteStreamWriter writer(const_cast<TUint8*>(data.Ptr()), EFalse); |
|
1476 |
|
1477 TUint32 startAdd = 0x10000000; |
|
1478 TUint64 procId = 100; |
|
1479 |
|
1480 TMemoryDump memDump; |
|
1481 memDump.iStartAddress = startAdd; |
|
1482 memDump.iPid = procId; |
|
1483 memDump.iLength = mem.Length(); |
|
1484 TRawData rawData; |
|
1485 rawData.iLength = mem.Length(); |
|
1486 rawData.iData.Set(mem.MidTPtr(0)); |
|
1487 |
|
1488 TInt32 crashSize = iInfHdr.GetSize() + iOffsetsHdr.GetSize() + iContextHdr.GetSize() + memDump.GetSize() + rawData.GetSize(); |
|
1489 iInfHdr.iLogSize = crashSize; |
|
1490 iInfHdr.iCrashId = CRASH_ID; |
|
1491 |
|
1492 iInfHdr.Serialize(writer); |
|
1493 iOffsetsHdr.Serialize(writer); |
|
1494 iContextHdr.Serialize(writer); |
|
1495 memDump.Serialize(writer); |
|
1496 rawData.Serialize(writer); |
|
1497 |
|
1498 INFO_PRINTF1(_L("Writing known memory to flash")); |
|
1499 |
|
1500 TUint32 written = 0; |
|
1501 User::LeaveIfError(iSecSess.WriteCrashConfig(START_OF_FLASH, data ,written)); |
|
1502 |
|
1503 TRAPD(err, iObject->AnalyseCrashL(CRASH_ID)); |
|
1504 if(KErrNone != err) |
|
1505 { |
|
1506 ERR_PRINTF2(_L("Unable to analyse crash: [%d]"), err); |
|
1507 SetBlockResult(EFail); |
|
1508 CleanupStack::PopAndDestroy(2); |
|
1509 return; |
|
1510 } |
|
1511 |
|
1512 RBuf8 found; |
|
1513 found.CreateL(mem.Length()); |
|
1514 found.CleanupClosePushL(); |
|
1515 |
|
1516 //reading from address not dumped |
|
1517 TRAP(err, iObject->ReadMemoryL(procId, 0xDEDEADAD, mem.Length(), found)); |
|
1518 if(KErrNotFound != err) |
|
1519 { |
|
1520 ERR_PRINTF2(_L("Able to read memory not dumped: [%d]"), err); |
|
1521 SetBlockResult(EFail); |
|
1522 CleanupStack::PopAndDestroy(3); |
|
1523 return; |
|
1524 } |
|
1525 |
|
1526 //read from a thread not dumped |
|
1527 TRAP(err, iObject->ReadMemoryL(50, startAdd, mem.Length(), found)); |
|
1528 if(KErrNotFound != err) |
|
1529 { |
|
1530 ERR_PRINTF2(_L("able to read memory from thread not dumped: [%d]"), err); |
|
1531 SetBlockResult(EFail); |
|
1532 CleanupStack::PopAndDestroy(3); |
|
1533 return; |
|
1534 } |
|
1535 |
|
1536 INFO_PRINTF1(_L("Got back all memory as expected")); |
|
1537 |
|
1538 CleanupStack::PopAndDestroy(3); |
|
1539 } |
|
1540 |
|
1541 /** |
|
1542 * Tests CFlashDataSource::GetCodeSegmentsL |
|
1543 * Writes known code segments to flash and ensures we can get them back |
|
1544 * |
|
1545 * Description: |
|
1546 * We will pretend we have a process ID of 100. We will also have a thread ID of 101. |
|
1547 * We will assign ownership between these two - ie. thread ID 101 exists in process ID 100. |
|
1548 * We will write a mini crash log to flash: |
|
1549 * <---Crash Header---><---Code Segment Set---><---Code Segment 1---><---Code Segment 2---> |
|
1550 * |
|
1551 * The code segments will exist for process ID 100. We will then try to read the code segments |
|
1552 * for thread ID 101 and we should retrieve code seg 1 and 2. |
|
1553 * |
|
1554 */ |
|
1555 void CFlashDataSourceWrapper::DoCmd_GetCodeSegmentsL1_Test_L() |
|
1556 { |
|
1557 INFO_PRINTF1(_L("Testing CFlashDataSource::GetCodeSegmentsL() - 1st test")); |
|
1558 |
|
1559 TUint64 procId = 100; //arbitrary |
|
1560 TInt numSegs = 2; |
|
1561 |
|
1562 TCodeSegmentSet segSet; |
|
1563 segSet.iNumSegs = 2; |
|
1564 segSet.iPid = procId; |
|
1565 segSet.iNumSegs = numSegs; |
|
1566 |
|
1567 //seg names |
|
1568 _LIT8(KSeg1, "seg1"); |
|
1569 _LIT8(KSeg2, "cseg2"); |
|
1570 |
|
1571 |
|
1572 //buffer for data |
|
1573 TInt bufLength = TCrashInfoHeader::KSCMCrashInfoMaxSize + TCrashOffsetsHeader::KSCMCrashOffsetsMaxSize + |
|
1574 TRegisterSet::KSCMRegisterSetMaxSize + 2 * TCodeSegment::KMaxSegmentNameSize + |
|
1575 KMaxCacheSize; |
|
1576 |
|
1577 RBuf8 data; |
|
1578 data.CreateL(bufLength); |
|
1579 data.SetLength(bufLength); |
|
1580 data.CleanupClosePushL(); |
|
1581 |
|
1582 TByteStreamWriter writer(const_cast<TUint8*>(data.Ptr()), EFalse); |
|
1583 |
|
1584 TCodeSegment seg1; |
|
1585 seg1.iNameLength = KSeg1().Size(); |
|
1586 seg1.iName = KSeg1; |
|
1587 seg1.iCodeSegType = EExeCodeSegType; |
|
1588 |
|
1589 TCodeSegment seg2; |
|
1590 seg2.iNameLength = KSeg2().Size(); |
|
1591 seg2.iName = KSeg2; |
|
1592 seg2.iCodeSegType = EExeCodeSegType; |
|
1593 |
|
1594 //For code segments to make sense we need to assign thread to process ownership |
|
1595 TInt64 threadId = 101; |
|
1596 iObject->AssignOwner(procId, threadId); |
|
1597 |
|
1598 iInfHdr.iCrashId = CRASH_ID; |
|
1599 iContextHdr.iNumRegisters = 0; //no context |
|
1600 iInfHdr.iLogSize = iInfHdr.GetSize() + iContextHdr.GetSize() + iOffsetsHdr.GetSize() + segSet.GetSize() + seg1.GetSize() + seg2.GetSize(); |
|
1601 |
|
1602 iInfHdr.Serialize(writer); |
|
1603 iOffsetsHdr.Serialize(writer); |
|
1604 iContextHdr.Serialize(writer); |
|
1605 segSet.Serialize(writer); |
|
1606 seg1.Serialize(writer); |
|
1607 seg2.Serialize(writer); |
|
1608 |
|
1609 INFO_PRINTF1(_L("Writing known Code Segs to flash")); |
|
1610 |
|
1611 TUint32 written = 0; |
|
1612 User::LeaveIfError(iSecSess.WriteCrashConfig(START_OF_FLASH, data ,written)); |
|
1613 |
|
1614 //Now we try get these threads back via GetCodeSegmentsL |
|
1615 TRAPD(err, iObject->AnalyseCrashL(CRASH_ID)); |
|
1616 if(KErrNone != err) |
|
1617 { |
|
1618 ERR_PRINTF2(_L("Failed to process crash header: [%d]"), err); |
|
1619 SetBlockResult(EFail); |
|
1620 CleanupStack::PopAndDestroy(); |
|
1621 return; |
|
1622 } |
|
1623 |
|
1624 RCodeSegPointerList* list = new(ELeave)RCodeSegPointerList; |
|
1625 TCleanupItem segCleanup(CFlashDataSource::CleanupCodeSegList, (TAny*)list); |
|
1626 CleanupStack::PushL(segCleanup); |
|
1627 |
|
1628 TUint sz = 0; |
|
1629 TRAP(err, iObject->GetCodeSegmentsL(threadId, *list, sz)); |
|
1630 |
|
1631 if(list->Count() != numSegs) |
|
1632 { |
|
1633 ERR_PRINTF3(_L("Failed to retrieve right amount of code segs. Expected [%d] got [%d]"),numSegs, list->Count()); |
|
1634 SetBlockResult(EFail); |
|
1635 CleanupStack::PopAndDestroy(2); |
|
1636 return; |
|
1637 } |
|
1638 |
|
1639 TCodeSegInfo* cs1 = (*list)[0]; |
|
1640 TCodeSegInfo* cs2 = (*list)[1]; |
|
1641 |
|
1642 INFO_PRINTF1(_L("Retrieveing code segs")); |
|
1643 if(!cs1 || !cs2) |
|
1644 { |
|
1645 ERR_PRINTF1(_L("Failed to retrieve non null threads")); |
|
1646 SetBlockResult(EFail); |
|
1647 CleanupStack::PopAndDestroy(2); |
|
1648 return; |
|
1649 } |
|
1650 |
|
1651 //Check types |
|
1652 INFO_PRINTF1(_L("Checking code seg types are ok")); |
|
1653 if(cs1->iType != EExeCodeSegType || cs2->iType != EExeCodeSegType) |
|
1654 { |
|
1655 ERR_PRINTF1(_L("Failed to retrieve correct code seg types:")); |
|
1656 ERR_PRINTF3(_L("CS1 expected [%d] but found [%d]"), EExeCodeSegType, cs1->iType); |
|
1657 ERR_PRINTF3(_L("CS2 expected [%d] but found [%d]"), EExeCodeSegType, cs2->iType); |
|
1658 SetBlockResult(EFail); |
|
1659 CleanupStack::PopAndDestroy(2); |
|
1660 return; |
|
1661 } |
|
1662 |
|
1663 //check names |
|
1664 RBuf wide; |
|
1665 wide.CreateL(KSeg1().Size()); |
|
1666 wide.CleanupClosePushL(); |
|
1667 wide.Copy(KSeg1); |
|
1668 |
|
1669 INFO_PRINTF1(_L("Checking code seg name's are ok")); |
|
1670 |
|
1671 TBool passed = (cs1->iName.Compare(wide) == 0) || (cs2->iName.Compare(wide) == 0); |
|
1672 |
|
1673 if(!passed) |
|
1674 { |
|
1675 ERR_PRINTF4(_L("Wrong name retrieved, expected [%S] but got [%S] and [%S]"), &wide, &cs2->iName, &cs1->iName); |
|
1676 SetBlockResult(EFail); |
|
1677 CleanupStack::PopAndDestroy(3); |
|
1678 return; |
|
1679 } |
|
1680 |
|
1681 if(2 *KSeg2().Size() > wide.Size()) |
|
1682 { |
|
1683 wide.ReAllocL(2 * KSeg2().Size()); |
|
1684 } |
|
1685 |
|
1686 wide.Copy(KSeg2); |
|
1687 |
|
1688 INFO_PRINTF1(_L("Checking second code seg name is ok")); |
|
1689 |
|
1690 passed = (cs1->iName.Compare(wide) == 0) || (cs2->iName.Compare(wide) == 0); |
|
1691 |
|
1692 if(!passed) |
|
1693 { |
|
1694 ERR_PRINTF4(_L("Wrong name retrieved, expected [%S] but got [%S] and [%S]"), &wide, &cs2->iName, &cs1->iName); |
|
1695 SetBlockResult(EFail); |
|
1696 CleanupStack::PopAndDestroy(3); |
|
1697 return; |
|
1698 } |
|
1699 |
|
1700 CleanupStack::PopAndDestroy(3); |
|
1701 |
|
1702 } |
|
1703 |
|
1704 /** |
|
1705 * Tests CFlashDataSource::GetCodeSegmentsL |
|
1706 * Ensure we recognise corrupt segments (ie. no segment set to describe it) |
|
1707 */ |
|
1708 void CFlashDataSourceWrapper::DoCmd_GetCodeSegmentsL2_Test_L() |
|
1709 { |
|
1710 INFO_PRINTF1(_L("Testing CFlashDataSource() - Code Segment Analysis - 2nd test")); |
|
1711 |
|
1712 //seg names |
|
1713 _LIT8(KSeg1, "seg1"); |
|
1714 _LIT8(KSeg2, "cseg2"); |
|
1715 |
|
1716 //buffer for data |
|
1717 TInt bufLength = TCrashInfoHeader::KSCMCrashInfoMaxSize + TCrashOffsetsHeader::KSCMCrashOffsetsMaxSize + |
|
1718 TRegisterSet::KSCMRegisterSetMaxSize + 2 * TCodeSegment::KMaxSegmentNameSize + |
|
1719 KMaxCacheSize; |
|
1720 |
|
1721 RBuf8 data; |
|
1722 data.CreateL(bufLength); |
|
1723 data.SetLength(bufLength); |
|
1724 data.CleanupClosePushL(); |
|
1725 |
|
1726 TByteStreamWriter writer(const_cast<TUint8*>(data.Ptr()), EFalse); |
|
1727 |
|
1728 TCodeSegment seg1; |
|
1729 seg1.iNameLength = KSeg1().Size(); |
|
1730 seg1.iName = KSeg1; |
|
1731 seg1.iCodeSegType = EExeCodeSegType; |
|
1732 |
|
1733 TCodeSegment seg2; |
|
1734 seg2.iNameLength = KSeg2().Size(); |
|
1735 seg2.iName = KSeg2; |
|
1736 seg2.iCodeSegType = EExeCodeSegType; |
|
1737 |
|
1738 iInfHdr.iCrashId = CRASH_ID; |
|
1739 iContextHdr.iNumRegisters = 0; //no context |
|
1740 iInfHdr.iLogSize = iInfHdr.GetSize() + iContextHdr.GetSize() + iOffsetsHdr.GetSize()+ seg1.GetSize() + seg2.GetSize(); |
|
1741 |
|
1742 iInfHdr.Serialize(writer); |
|
1743 iOffsetsHdr.Serialize(writer); |
|
1744 iContextHdr.Serialize(writer); |
|
1745 seg1.Serialize(writer); |
|
1746 seg2.Serialize(writer); |
|
1747 |
|
1748 INFO_PRINTF1(_L("Writing known corrupt Code Segs to flash")); |
|
1749 |
|
1750 TUint32 written = 0; |
|
1751 User::LeaveIfError(iSecSess.WriteCrashConfig(START_OF_FLASH, data ,written)); |
|
1752 |
|
1753 //Now we try get these threads back via GetCodeSegmentsL |
|
1754 TRAPD(err, iObject->AnalyseCrashL(CRASH_ID)); |
|
1755 if(KErrCorrupt != err) |
|
1756 { |
|
1757 ERR_PRINTF2(_L("Failed to recognise corrupt data: [%d]"), err); |
|
1758 SetBlockResult(EFail); |
|
1759 CleanupStack::PopAndDestroy(); |
|
1760 return; |
|
1761 } |
|
1762 |
|
1763 CleanupStack::PopAndDestroy(); |
|
1764 |
|
1765 INFO_PRINTF1(_L("Corrupt data recognised")); |
|
1766 } |
|
1767 |
|
1768 |
|
1769 |
|
1770 /** |
|
1771 * Tests CFlashDataSource::GetCodeSegmentsL |
|
1772 * Ensure we do not reciev duplicate segments |
|
1773 * even after we place then in flash |
|
1774 */ |
|
1775 void CFlashDataSourceWrapper::DoCmd_GetCodeSegmentsL3_Test_L() |
|
1776 { |
|
1777 INFO_PRINTF1(_L("Testing CFlashDataSource() - Code Segment Analysis - 3rd test")); |
|
1778 |
|
1779 TUint64 procId = 100; //arbitrary |
|
1780 const TInt KNumRepeatSegs = 3; |
|
1781 |
|
1782 TCodeSegmentSet segSet; |
|
1783 segSet.iNumSegs = KNumRepeatSegs; |
|
1784 segSet.iPid = procId; |
|
1785 |
|
1786 //seg names |
|
1787 _LIT8(KSeg1, "seg1"); |
|
1788 |
|
1789 //buffer for data |
|
1790 TInt bufLength = TCrashInfoHeader::KSCMCrashInfoMaxSize + TCrashOffsetsHeader::KSCMCrashOffsetsMaxSize + |
|
1791 TRegisterSet::KSCMRegisterSetMaxSize + 2 * TCodeSegment::KMaxSegmentNameSize + |
|
1792 KMaxCacheSize; |
|
1793 |
|
1794 RBuf8 data; |
|
1795 data.CreateL(bufLength); |
|
1796 data.SetLength(bufLength); |
|
1797 data.CleanupClosePushL(); |
|
1798 |
|
1799 TByteStreamWriter writer(const_cast<TUint8*>(data.Ptr()), EFalse); |
|
1800 |
|
1801 TCodeSegment seg1; |
|
1802 seg1.iNameLength = KSeg1().Size(); |
|
1803 seg1.iName = KSeg1; |
|
1804 seg1.iCodeSegType = EExeCodeSegType; |
|
1805 |
|
1806 |
|
1807 //For code segments to make sense we need to assign thread to process ownership |
|
1808 TInt64 threadId = 101; |
|
1809 iObject->AssignOwner(procId, threadId); |
|
1810 |
|
1811 iInfHdr.iCrashId = CRASH_ID; |
|
1812 iContextHdr.iNumRegisters = 0; //no context |
|
1813 |
|
1814 |
|
1815 iInfHdr.iLogSize = |
|
1816 iInfHdr.GetSize() + iContextHdr.GetSize() + iOffsetsHdr.GetSize() |
|
1817 + segSet.GetSize() + ( seg1.GetSize() * KNumRepeatSegs); |
|
1818 |
|
1819 iInfHdr.Serialize(writer); |
|
1820 iOffsetsHdr.Serialize(writer); |
|
1821 iContextHdr.Serialize(writer); |
|
1822 segSet.Serialize(writer); |
|
1823 |
|
1824 // serialize the same segment a number of times |
|
1825 for(TInt i=0;i<segSet.iNumSegs;i++) |
|
1826 { |
|
1827 seg1.Serialize(writer); |
|
1828 } |
|
1829 |
|
1830 |
|
1831 TUint32 written = 0; |
|
1832 User::LeaveIfError(iSecSess.WriteCrashConfig(START_OF_FLASH, data ,written)); |
|
1833 |
|
1834 //Now we try get these threads back via GetCodeSegmentsL |
|
1835 TRAPD(err, iObject->AnalyseCrashL(CRASH_ID)); |
|
1836 if(KErrNone != err) |
|
1837 { |
|
1838 ERR_PRINTF2(_L("Failed to process crash header: [%d]"), err); |
|
1839 SetBlockResult(EFail); |
|
1840 CleanupStack::PopAndDestroy(); |
|
1841 return; |
|
1842 } |
|
1843 |
|
1844 RCodeSegPointerList* list = new(ELeave)RCodeSegPointerList; |
|
1845 TCleanupItem segCleanup(CFlashDataSource::CleanupCodeSegList, (TAny*)list); |
|
1846 CleanupStack::PushL(segCleanup); |
|
1847 |
|
1848 TUint sz = 0; |
|
1849 TRAP(err, iObject->GetCodeSegmentsL(threadId, *list, sz)); |
|
1850 |
|
1851 |
|
1852 // loop through the code seg list check that none are the same |
|
1853 for(TInt i=0;i<list->Count();i++) |
|
1854 { |
|
1855 TCodeSegInfo* csinf1 = (*list)[i]; |
|
1856 for(TInt j=1;j<list->Count();j++) |
|
1857 { |
|
1858 TCodeSegInfo* csinf2 = (*list)[j]; |
|
1859 |
|
1860 // check not checking same item |
|
1861 if( csinf1 != csinf2 ) |
|
1862 { |
|
1863 if(csinf1->iDataRunAddr == csinf2->iDataRunAddr && |
|
1864 csinf1->iDataSize == csinf2->iDataSize ) |
|
1865 { |
|
1866 ERR_PRINTF1(_L("DUPLICATE code segs 1") ); |
|
1867 SetBlockResult(EFail); |
|
1868 CleanupStack::PopAndDestroy(2); |
|
1869 return; |
|
1870 |
|
1871 } |
|
1872 } |
|
1873 } |
|
1874 } |
|
1875 |
|
1876 CleanupStack::PopAndDestroy(2); // data , list |
|
1877 } |
|
1878 |
|
1879 /** |
|
1880 * Tests we can get ALL expected trace data back |
|
1881 */ |
|
1882 void CFlashDataSourceWrapper::DoCmd_ReadTraceBufferL1_Test_L() |
|
1883 { |
|
1884 INFO_PRINTF1(_L("Testing CFlashDataSource::ReadTraceBufferL() Test1")); |
|
1885 |
|
1886 //buffer to hold trace - will do in 2 parts to simulate the circular buffer |
|
1887 TInt32 numBytes = 8; //we will dump 8 bytes of trace |
|
1888 TUint8 traceToDump1 = 0xAB; |
|
1889 TUint8 traceToDump2 = 0xCD; |
|
1890 |
|
1891 RBuf8 trace1; |
|
1892 trace1.CreateL(numBytes * sizeof(TUint8)); |
|
1893 trace1.CleanupClosePushL(); |
|
1894 |
|
1895 for(TInt cnt = numBytes -1; cnt >= 0; cnt--) |
|
1896 { |
|
1897 trace1.Append(&traceToDump1, sizeof(TUint8)); |
|
1898 } |
|
1899 |
|
1900 RBuf8 trace2; |
|
1901 trace2.CreateL(numBytes * sizeof(TUint8)); |
|
1902 trace2.CleanupClosePushL(); |
|
1903 |
|
1904 for(TInt cnt = numBytes -1; cnt >= 0; cnt--) |
|
1905 { |
|
1906 trace2.Append(&traceToDump2, sizeof(TUint8)); |
|
1907 } |
|
1908 |
|
1909 //buffer to hold log |
|
1910 TInt dataLength = TCrashInfoHeader::KSCMCrashInfoMaxSize + |
|
1911 TCrashOffsetsHeader::KSCMCrashOffsetsMaxSize + |
|
1912 TRegisterSet::KSCMRegisterSetMaxSize + |
|
1913 TTraceDump::KSCMTraceDumpMaxSize + |
|
1914 2 * (TRawData::KSCMRawDataMaxSize + numBytes); |
|
1915 |
|
1916 RBuf8 data; |
|
1917 data.CreateL(dataLength); |
|
1918 data.SetLength(dataLength); |
|
1919 data.CleanupClosePushL(); |
|
1920 |
|
1921 TByteStreamWriter writer(const_cast<TUint8*>(data.Ptr()), EFalse); |
|
1922 |
|
1923 TTraceDump traceDump; |
|
1924 traceDump.iSizeOfMemory = 2 * numBytes; |
|
1925 traceDump.iNumberOfParts = 2; |
|
1926 |
|
1927 TRawData rawData1; |
|
1928 rawData1.iLength = trace1.Length(); |
|
1929 rawData1.iData.Set(trace1.MidTPtr(0)); |
|
1930 |
|
1931 TRawData rawData2; |
|
1932 rawData2.iLength = trace2.Length(); |
|
1933 rawData2.iData.Set(trace2.MidTPtr(0)); |
|
1934 |
|
1935 TInt32 crashSize = iInfHdr.GetSize() + iOffsetsHdr.GetSize() + iContextHdr.GetSize() + traceDump.GetSize() + rawData1.GetSize() + rawData2.GetSize(); |
|
1936 iInfHdr.iLogSize = crashSize; |
|
1937 iInfHdr.iCrashId = CRASH_ID; |
|
1938 iOffsetsHdr.iTraceOffset = iInfHdr.GetSize() + iOffsetsHdr.GetSize() + iContextHdr.GetSize(); |
|
1939 |
|
1940 iInfHdr.Serialize(writer); |
|
1941 iOffsetsHdr.Serialize(writer); |
|
1942 iContextHdr.Serialize(writer); |
|
1943 traceDump.Serialize(writer); |
|
1944 rawData1.Serialize(writer); |
|
1945 rawData2.Serialize(writer); |
|
1946 |
|
1947 INFO_PRINTF1(_L("Writing known trace to flash")); |
|
1948 |
|
1949 TUint32 written = 0; |
|
1950 User::LeaveIfError(iSecSess.WriteCrashConfig(START_OF_FLASH, data ,written)); |
|
1951 |
|
1952 //Now we try get the trace data back |
|
1953 TRAPD(err, iObject->AnalyseCrashL(CRASH_ID)); |
|
1954 |
|
1955 if(KErrNone != err) |
|
1956 { |
|
1957 ERR_PRINTF2(_L("Failed to process crash header: [%d]"), err); |
|
1958 SetBlockResult(EFail); |
|
1959 CleanupStack::PopAndDestroy(3); |
|
1960 return; |
|
1961 } |
|
1962 |
|
1963 TUint traceBufferAvailable = 0; |
|
1964 |
|
1965 TRAP(err, traceBufferAvailable = iObject->GetAvailableTraceSizeL()); |
|
1966 if(KErrNone != err) |
|
1967 { |
|
1968 ERR_PRINTF2(_L("Unable to read trace data size: [%d]"), err); |
|
1969 SetBlockResult(EFail); |
|
1970 CleanupStack::PopAndDestroy(3); |
|
1971 return; |
|
1972 } |
|
1973 |
|
1974 RBuf8 found; |
|
1975 found.CreateL(traceBufferAvailable); |
|
1976 found.CleanupClosePushL(); |
|
1977 |
|
1978 //reading from address not dumped |
|
1979 TRAP(err, iObject->ReadTraceBufferL(found)); |
|
1980 |
|
1981 RDebug::Printf("Printing trace found"); |
|
1982 for(TInt x = 0; x<found.Length(); x++) |
|
1983 { |
|
1984 RDebug::Printf("[0x%X]", found[x]); |
|
1985 } |
|
1986 |
|
1987 RBuf8 totalTrace; |
|
1988 totalTrace.CreateL(trace1.Length() + trace2.Length()); |
|
1989 totalTrace.CleanupClosePushL(); |
|
1990 |
|
1991 totalTrace.Append(trace1); |
|
1992 totalTrace.Append(trace2); |
|
1993 |
|
1994 if(totalTrace.Compare(found) != 0) |
|
1995 { |
|
1996 ERR_PRINTF1(_L("Found trace did not match expected trace")); |
|
1997 SetBlockResult(EFail); |
|
1998 CleanupStack::PopAndDestroy(5); |
|
1999 return; |
|
2000 } |
|
2001 |
|
2002 CleanupStack::PopAndDestroy(5); |
|
2003 } |
|
2004 |
|
2005 void CFlashDataSourceWrapper::DoCmd_CalculateChecksum_TestL() |
|
2006 { |
|
2007 // check sum is commutative - so it should add up to same value |
|
2008 // however blocks were requested |
|
2009 |
|
2010 INFO_PRINTF1(_L("DoCmd_CalculateChecksum_TestL called")); |
|
2011 |
|
2012 TScmChecksum chksm1, chksm2; |
|
2013 |
|
2014 iObject->CalculateChecksumL(0, 10, chksm1); |
|
2015 iObject->CalculateChecksumL(10, 10, chksm1); |
|
2016 iObject->CalculateChecksumL(0, 20, chksm2); |
|
2017 |
|
2018 SetBlockResult((chksm1 == chksm2) ? EPass : EFail ); |
|
2019 } |
|
2020 |
|
2021 /** |
|
2022 * Tests we can get back the correct trace buffer size |
|
2023 */ |
|
2024 void CFlashDataSourceWrapper::DoCmd_TraceDataSizeL_TestL() |
|
2025 { |
|
2026 INFO_PRINTF1(_L("Testing CFlashDataSource() - Trace Size Test")); |
|
2027 |
|
2028 //buffer for data |
|
2029 TInt bufLength = TCrashInfoHeader::KSCMCrashInfoMaxSize + TCrashOffsetsHeader::KSCMCrashOffsetsMaxSize + |
|
2030 TRegisterSet::KSCMRegisterSetMaxSize + 2 * TCodeSegment::KMaxSegmentNameSize + |
|
2031 KMaxCacheSize; |
|
2032 |
|
2033 RBuf8 data; |
|
2034 data.CreateL(bufLength); |
|
2035 data.SetLength(bufLength); |
|
2036 data.CleanupClosePushL(); |
|
2037 |
|
2038 TByteStreamWriter writer(const_cast<TUint8*>(data.Ptr()), EFalse); |
|
2039 |
|
2040 TUint memSize = 1243; |
|
2041 TTraceDump trace; |
|
2042 trace.iSizeOfMemory = memSize; |
|
2043 |
|
2044 iInfHdr.iCrashId = CRASH_ID; |
|
2045 iContextHdr.iNumRegisters = 0; //no context |
|
2046 iInfHdr.iLogSize = iInfHdr.GetSize() + iContextHdr.GetSize() + iOffsetsHdr.GetSize()+ trace.GetSize(); |
|
2047 iOffsetsHdr.iTraceOffset = iInfHdr.GetSize() + iContextHdr.GetSize() + iOffsetsHdr.GetSize(); |
|
2048 |
|
2049 iInfHdr.Serialize(writer); |
|
2050 iOffsetsHdr.Serialize(writer); |
|
2051 iContextHdr.Serialize(writer); |
|
2052 trace.Serialize(writer); |
|
2053 |
|
2054 INFO_PRINTF1(_L("Writing known trace struct to flash")); |
|
2055 |
|
2056 TUint32 written = 0; |
|
2057 User::LeaveIfError(iSecSess.WriteCrashConfig(START_OF_FLASH, data ,written)); |
|
2058 |
|
2059 //Now we try get these threads back via GetCodeSegmentsL |
|
2060 TRAPD(err, iObject->AnalyseCrashL(CRASH_ID)); |
|
2061 if(KErrNone != err) |
|
2062 { |
|
2063 ERR_PRINTF2(_L("Failed to analyse crash: [%d]"), err); |
|
2064 SetBlockResult(EFail); |
|
2065 CleanupStack::PopAndDestroy(); |
|
2066 return; |
|
2067 } |
|
2068 |
|
2069 CleanupStack::PopAndDestroy(); |
|
2070 |
|
2071 TUint recoveredMemSize = 0; |
|
2072 TRAP(err, recoveredMemSize = iObject->GetAvailableTraceSizeL()); |
|
2073 if(KErrNone != err) |
|
2074 { |
|
2075 ERR_PRINTF2(_L("Failed to get back trace size: [%d]"), err); |
|
2076 SetBlockResult(EFail); |
|
2077 return; |
|
2078 } |
|
2079 |
|
2080 if(recoveredMemSize != memSize) |
|
2081 { |
|
2082 ERR_PRINTF3(_L("Failed to get back correct trace size: Got [%d] Expected [%d]"), recoveredMemSize, memSize); |
|
2083 SetBlockResult(EFail); |
|
2084 return; |
|
2085 } |
|
2086 |
|
2087 INFO_PRINTF1(_L("Trace size looks good")); |
|
2088 } |
|
2089 |
|
2090 /** |
|
2091 * Tests we can get back the correct trace buffer size |
|
2092 */ |
|
2093 void CFlashDataSourceWrapper::DoCmd_TraceDataSizeNotFoundL_TestL() |
|
2094 { |
|
2095 INFO_PRINTF1(_L("Testing CFlashDataSource() - Trace Size Test - Negative")); |
|
2096 |
|
2097 //buffer for data |
|
2098 TInt bufLength = TCrashInfoHeader::KSCMCrashInfoMaxSize + TCrashOffsetsHeader::KSCMCrashOffsetsMaxSize + |
|
2099 TRegisterSet::KSCMRegisterSetMaxSize + 2 * TCodeSegment::KMaxSegmentNameSize + |
|
2100 KMaxCacheSize; |
|
2101 |
|
2102 RBuf8 data; |
|
2103 data.CreateL(bufLength); |
|
2104 data.SetLength(bufLength); |
|
2105 data.CleanupClosePushL(); |
|
2106 |
|
2107 TByteStreamWriter writer(const_cast<TUint8*>(data.Ptr()), EFalse); |
|
2108 |
|
2109 iInfHdr.iCrashId = CRASH_ID; |
|
2110 iContextHdr.iNumRegisters = 0; //no context |
|
2111 iInfHdr.iLogSize = iInfHdr.GetSize() + iContextHdr.GetSize() + iOffsetsHdr.GetSize(); |
|
2112 |
|
2113 iInfHdr.Serialize(writer); |
|
2114 iOffsetsHdr.Serialize(writer); |
|
2115 iContextHdr.Serialize(writer); |
|
2116 |
|
2117 INFO_PRINTF1(_L("Writing known trace struct to flash")); |
|
2118 |
|
2119 TUint32 written = 0; |
|
2120 User::LeaveIfError(iSecSess.WriteCrashConfig(START_OF_FLASH, data ,written)); |
|
2121 |
|
2122 //Now we try get these threads back via GetCodeSegmentsL |
|
2123 TRAPD(err, iObject->AnalyseCrashL(CRASH_ID)); |
|
2124 if(KErrNone != err) |
|
2125 { |
|
2126 ERR_PRINTF2(_L("Failed to analyse crash: [%d]"), err); |
|
2127 SetBlockResult(EFail); |
|
2128 CleanupStack::PopAndDestroy(); |
|
2129 return; |
|
2130 } |
|
2131 |
|
2132 CleanupStack::PopAndDestroy(); |
|
2133 |
|
2134 TRAP(err, TUint recoveredMemSize = iObject->GetAvailableTraceSizeL()); |
|
2135 if(KErrNotFound != err) |
|
2136 { |
|
2137 ERR_PRINTF2(_L("Failed to get back KErrNone for non available trace size: [%d]"), err); |
|
2138 SetBlockResult(EFail); |
|
2139 return; |
|
2140 } |
|
2141 |
|
2142 INFO_PRINTF1(_L("All as expected.")); |
|
2143 } |
|
2144 |
|
2145 /** |
|
2146 * Tests we can get ALL expected trace data back |
|
2147 */ |
|
2148 void CFlashDataSourceWrapper::DoCmd_ReadTraceBufferL2_Test_L() |
|
2149 { |
|
2150 INFO_PRINTF1(_L("Testing CFlashDataSource::ReadTraceBufferL() Test2")); |
|
2151 |
|
2152 //buffer to hold trace - will do in 2 parts to simulate the circular buffer |
|
2153 TInt32 numBytes = 8; //we will dump 8 bytes of trace |
|
2154 TUint8 traceToDump1 = 0xAB; |
|
2155 TUint8 traceToDump2 = 0xCD; |
|
2156 |
|
2157 RBuf8 trace1; |
|
2158 trace1.CreateL(numBytes * sizeof(TUint8)); |
|
2159 trace1.CleanupClosePushL(); |
|
2160 |
|
2161 for(TInt cnt = numBytes -1; cnt >= 0; cnt--) |
|
2162 { |
|
2163 trace1.Append(&traceToDump1, sizeof(TUint8)); |
|
2164 } |
|
2165 |
|
2166 RBuf8 trace2; |
|
2167 trace2.CreateL(numBytes * sizeof(TUint8)); |
|
2168 trace2.CleanupClosePushL(); |
|
2169 |
|
2170 for(TInt cnt = numBytes -1; cnt >= 0; cnt--) |
|
2171 { |
|
2172 trace2.Append(&traceToDump2, sizeof(TUint8)); |
|
2173 } |
|
2174 |
|
2175 //buffer to hold log |
|
2176 TInt dataLength = TCrashInfoHeader::KSCMCrashInfoMaxSize + |
|
2177 TCrashOffsetsHeader::KSCMCrashOffsetsMaxSize + |
|
2178 TRegisterSet::KSCMRegisterSetMaxSize + |
|
2179 TTraceDump::KSCMTraceDumpMaxSize + |
|
2180 2 * (TRawData::KSCMRawDataMaxSize + numBytes); |
|
2181 |
|
2182 RBuf8 data; |
|
2183 data.CreateL(dataLength); |
|
2184 data.SetLength(dataLength); |
|
2185 data.CleanupClosePushL(); |
|
2186 |
|
2187 TByteStreamWriter writer(const_cast<TUint8*>(data.Ptr()), EFalse); |
|
2188 |
|
2189 TTraceDump traceDump; |
|
2190 traceDump.iSizeOfMemory = 2 * numBytes; |
|
2191 traceDump.iNumberOfParts = 2; |
|
2192 |
|
2193 TRawData rawData1; |
|
2194 rawData1.iLength = trace1.Length(); |
|
2195 rawData1.iData.Set(trace1.MidTPtr(0)); |
|
2196 |
|
2197 TRawData rawData2; |
|
2198 rawData2.iLength = trace2.Length(); |
|
2199 rawData2.iData.Set(trace2.MidTPtr(0)); |
|
2200 |
|
2201 TInt32 crashSize = iInfHdr.GetSize() + iOffsetsHdr.GetSize() + iContextHdr.GetSize() + traceDump.GetSize() + rawData1.GetSize() + rawData2.GetSize(); |
|
2202 iInfHdr.iLogSize = crashSize; |
|
2203 iInfHdr.iCrashId = CRASH_ID; |
|
2204 iOffsetsHdr.iTraceOffset = iInfHdr.GetSize() + iOffsetsHdr.GetSize() + iContextHdr.GetSize(); |
|
2205 |
|
2206 iInfHdr.Serialize(writer); |
|
2207 iOffsetsHdr.Serialize(writer); |
|
2208 iContextHdr.Serialize(writer); |
|
2209 traceDump.Serialize(writer); |
|
2210 rawData1.Serialize(writer); |
|
2211 rawData2.Serialize(writer); |
|
2212 |
|
2213 INFO_PRINTF1(_L("Writing known trace to flash")); |
|
2214 |
|
2215 TUint32 written = 0; |
|
2216 User::LeaveIfError(iSecSess.WriteCrashConfig(START_OF_FLASH, data ,written)); |
|
2217 |
|
2218 //Now we try get the trace data back |
|
2219 TRAPD(err, iObject->AnalyseCrashL(CRASH_ID)); |
|
2220 |
|
2221 if(KErrNone != err) |
|
2222 { |
|
2223 ERR_PRINTF2(_L("Failed to process crash header: [%d]"), err); |
|
2224 SetBlockResult(EFail); |
|
2225 CleanupStack::PopAndDestroy(3); |
|
2226 return; |
|
2227 } |
|
2228 |
|
2229 TUint traceBufferAvailable = 0; |
|
2230 |
|
2231 TRAP(err, traceBufferAvailable = iObject->GetAvailableTraceSizeL()); |
|
2232 if(KErrNone != err) |
|
2233 { |
|
2234 ERR_PRINTF2(_L("Unable to read trace data size: [%d]"), err); |
|
2235 SetBlockResult(EFail); |
|
2236 CleanupStack::PopAndDestroy(3); |
|
2237 return; |
|
2238 } |
|
2239 |
|
2240 RBuf8 totalTrace; |
|
2241 totalTrace.CreateL(trace1.Length() + trace2.Length()); |
|
2242 totalTrace.CleanupClosePushL(); |
|
2243 |
|
2244 totalTrace.Append(trace1); |
|
2245 totalTrace.Append(trace2); |
|
2246 |
|
2247 //Read 1 byte at a time |
|
2248 RBuf8 read; |
|
2249 read.CreateL(1); |
|
2250 read.CleanupClosePushL(); |
|
2251 |
|
2252 for(TInt x = 0; x< traceBufferAvailable; x++) |
|
2253 { |
|
2254 TRAP(err, iObject->ReadTraceBufferL(read, x)); |
|
2255 if(err != KErrNone) |
|
2256 { |
|
2257 ERR_PRINTF2(_L("Unable to read trace data: [%d]"), err); |
|
2258 SetBlockResult(EFail); |
|
2259 CleanupStack::PopAndDestroy(5); |
|
2260 return; |
|
2261 } |
|
2262 |
|
2263 RDebug::Printf("Found [0x%X] expected [0x%X]", read[0], totalTrace[x]); |
|
2264 |
|
2265 if(read[0] != totalTrace[x]) |
|
2266 { |
|
2267 ERR_PRINTF1(_L("Didnt get back expected trace")); |
|
2268 SetBlockResult(EFail); |
|
2269 CleanupStack::PopAndDestroy(5); |
|
2270 return; |
|
2271 } |
|
2272 } |
|
2273 |
|
2274 CleanupStack::PopAndDestroy(5); |
|
2275 } |
|
2276 |
|
2277 //eof |
|
2278 |
|
2279 |