|
1 // Copyright (c) 2005-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 the License "Eclipse Public License v1.0" |
|
5 // which accompanies this distribution, and is available |
|
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
7 // |
|
8 // Initial Contributors: |
|
9 // Nokia Corporation - initial contribution. |
|
10 // |
|
11 // Contributors: |
|
12 // |
|
13 // Description: |
|
14 // e32test\debug\t_debugapi.cpp |
|
15 // User-side harness for LDD-based debug agent that checks debug API |
|
16 // interface provided by kernel extension kdebug.dll (ARMv5) or kdebugv6 (ARMv6). |
|
17 // It uses debug port to print the list of processes, threads, etc. |
|
18 // Usage: t_debugapi [process] [thread] [chunk] [ipaccess] |
|
19 // Performs all steps if there are no input arguments. |
|
20 // The test is automated (does not require any input argument or manual assistance, but needs |
|
21 // non-standard image file that includes kdebug.dll (ARMv5 based target) or kdebugV6.dll |
|
22 // (ARMv6 based target). It can be achieved by adding: #define STOP_MODE_DEBUGGING in .oby/iby file. |
|
23 // Supported and tested on H2 (ARMv5) and integrator_1136 (ARMv6) platforms. |
|
24 // It requires D_DEBUGAPI.DLL as well. |
|
25 // Using debug interfaca only, it completes (prints) the list of: |
|
26 // - processes; |
|
27 // - threads; |
|
28 // - chunks; |
|
29 // in the system. On multiple-memory-model based target (ARMv6 architecture), |
|
30 // it also reads from address space of another process. This part is not checked |
|
31 // on moving-memory-model target (ARMv5) (e.g. always passes). |
|
32 // Note: The test may cause system fail on ARM1136(r0p2) with L210 cache due to Erratum 317041. |
|
33 // In that case, uncomment two relevant lines in DDebugAPIChecker::ReadFromOtherProcessArmv6 (in |
|
34 // d_debugapi.cia) and rebuild d_debugapi.ldd. |
|
35 // |
|
36 // |
|
37 |
|
38 //! @file t_debugapi.h |
|
39 //! @SYMTestCaseID KBASE/T_DEBUGAPI |
|
40 //! @SYMTestType UT |
|
41 //! @SYMTestCaseDesc |
|
42 //! @SYMREQ PREQ835 |
|
43 //! @SYMTestActions |
|
44 //! @SYMTestExpectedResults Test program completes with no errors. |
|
45 //! @SYMTestPriority Low |
|
46 //! @SYMTestStatus Defined |
|
47 |
|
48 |
|
49 #include <e32test.h> |
|
50 #include "d_debugapi.h" |
|
51 |
|
52 RTest test(_L("T_DebugAPI")); |
|
53 |
|
54 _LIT(KProcessName,"t_DebugAPI.exe"); |
|
55 _LIT(KProcess,"Process"); |
|
56 _LIT(KChunk,"Chunk"); |
|
57 _LIT(KThread,"Thread"); |
|
58 _LIT(KIPAccess,"IPAccess"); |
|
59 _LIT(KIPAccessStep2,"IPAccessStep2"); |
|
60 |
|
61 TBuf<64> command; |
|
62 |
|
63 //The main program for the first instance of the process. |
|
64 void Main() |
|
65 { |
|
66 RDebugAPIChecker debugAPI; |
|
67 TInt r; |
|
68 TBool checkAll = EFalse; |
|
69 |
|
70 if (command.Length() == 0) |
|
71 checkAll = ETrue; |
|
72 |
|
73 r = User::LoadLogicalDevice(_L("D_DebugAPI.LDD")); |
|
74 test(r == KErrNone || r == KErrAlreadyExists); |
|
75 test (debugAPI.Open() == KErrNone); |
|
76 |
|
77 if (checkAll || command.FindF(KProcess) >= 0) |
|
78 { |
|
79 test.Next(_L("Printing process info")); |
|
80 test(debugAPI.Process() == KErrNone); |
|
81 } |
|
82 |
|
83 if (checkAll || command.FindF(KChunk) >= 0) |
|
84 { |
|
85 test.Next(_L("Printing chunk info")); |
|
86 test(debugAPI.Chunk() == KErrNone); |
|
87 } |
|
88 |
|
89 if (checkAll || command.FindF(KThread) >= 0) |
|
90 { |
|
91 test.Next(_L("Printing thread info")); |
|
92 test(debugAPI.Thread() == KErrNone); |
|
93 } |
|
94 |
|
95 if (checkAll || command.FindF(KIPAccess) >= 0) |
|
96 { |
|
97 test.Next(_L("KIPAccess")); |
|
98 |
|
99 RProcess process; |
|
100 TRequestStatus status; |
|
101 |
|
102 //The other process will try to read this variable. |
|
103 TInt probeVariable = 0x55555555; |
|
104 TUint id = process.Id(); |
|
105 TBuf<64> command; |
|
106 command.Format(_L("%08x %08x %08x IPAccessStep2"), id, &probeVariable, probeVariable); |
|
107 |
|
108 test(process.Create(KProcessName, command) == KErrNone); |
|
109 process.Logon(status); |
|
110 process.Resume(); |
|
111 User::WaitForRequest(status); |
|
112 test(process.ExitType() == EExitKill); |
|
113 test(process.ExitReason() == KErrNone); |
|
114 process.Close(); |
|
115 |
|
116 //Now try another value. |
|
117 probeVariable = 0xaaaaaaaa; |
|
118 command.Format(_L("%08x %08x %08x IPAccessStep2"), id, &probeVariable, probeVariable); |
|
119 |
|
120 test(process.Create(KProcessName, command) == KErrNone); |
|
121 process.Logon(status); |
|
122 process.Resume(); |
|
123 User::WaitForRequest(status); |
|
124 test(process.ExitType() == EExitKill); |
|
125 test(process.ExitReason() == KErrNone); |
|
126 process.Close(); |
|
127 } |
|
128 |
|
129 debugAPI.Close(); |
|
130 r = User::FreeLogicalDevice(KTestLddName); |
|
131 test(r == KErrNone || r == KErrNotFound); |
|
132 } |
|
133 |
|
134 /** |
|
135 The main program for the second instance of the process. |
|
136 We need two processes two check inter-process data access. |
|
137 */ |
|
138 void SecondProcessMain() |
|
139 { |
|
140 RDebugAPIChecker debugAPI; |
|
141 TInt r; |
|
142 |
|
143 r = User::LoadLogicalDevice(_L("D_DebugAPI.LDD")); |
|
144 test(r == KErrNone || r == KErrAlreadyExists); |
|
145 test (debugAPI.Open() == KErrNone); |
|
146 |
|
147 if (command.FindF(KIPAccessStep2) >= 0) |
|
148 { |
|
149 RDebugAPIChecker::IPAccessArgs args; |
|
150 |
|
151 TPtrC ptr = command.Mid(0,8); |
|
152 TLex lex(ptr); |
|
153 lex.Val(args.iProcessID, EHex); |
|
154 |
|
155 ptr.Set(command.Mid(9,8)); |
|
156 lex.Assign(ptr); |
|
157 lex.Val(args.iAddress, EHex); |
|
158 |
|
159 ptr.Set(command.Mid(18,8)); |
|
160 lex.Assign(ptr); |
|
161 lex.Val(args.iValue, EHex); |
|
162 |
|
163 r = debugAPI.IPAccess(&args); |
|
164 test(r == KErrNone || r==KErrNotSupported); |
|
165 } |
|
166 |
|
167 debugAPI.Close(); |
|
168 r = User::FreeLogicalDevice(KTestLddName); |
|
169 } |
|
170 |
|
171 TInt E32Main() |
|
172 { |
|
173 test.Title(); |
|
174 __UHEAP_MARK; |
|
175 |
|
176 User::CommandLine(command); |
|
177 |
|
178 if (command.FindF(KIPAccessStep2) < 0) //The second process is recognized by the specific input parameter |
|
179 { |
|
180 //This is the first instance of the running process. |
|
181 test.Start(_L("Testing Debug API")); |
|
182 Main(); |
|
183 test.End(); |
|
184 } |
|
185 else |
|
186 { |
|
187 //This is the second instance of the running process. |
|
188 SecondProcessMain(); |
|
189 } |
|
190 |
|
191 __UHEAP_MARKEND; |
|
192 return 0; |
|
193 } |