0
|
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 |
// Implement the interface to the Core Dump Server
|
|
15 |
//
|
|
16 |
|
|
17 |
|
|
18 |
|
|
19 |
/**
|
|
20 |
@file
|
|
21 |
@internalTechnology
|
|
22 |
@released
|
|
23 |
@see RCoreDumpSession
|
|
24 |
*/
|
|
25 |
|
|
26 |
|
|
27 |
// Project includes
|
|
28 |
#include <coredumpinterface.h>
|
|
29 |
|
|
30 |
/**
|
|
31 |
Called to start the server (by the RCoreDumpSession::Connect())
|
|
32 |
The function is only called if the server is not running.
|
|
33 |
@return KErrNone if server was successfully started, or one of the other
|
|
34 |
system wide error codes
|
|
35 |
*/
|
|
36 |
TInt RCoreDumpSession::StartServer()
|
|
37 |
{
|
|
38 |
LOG_MSG("->RCoreDumpSession::StartServer()\n");
|
|
39 |
TInt err;
|
|
40 |
// Create the server process
|
|
41 |
const TUidType serverUid( KNullUid, KNullUid, KCoreDumpServUid );
|
|
42 |
|
|
43 |
RProcess server;
|
|
44 |
_LIT(KServerCommand, "");
|
|
45 |
LOG_MSG("RCoreDumpSession::StartServer -> Create()\n");
|
|
46 |
err = server.Create( KCoreDumpServerName, KServerCommand, serverUid );
|
|
47 |
|
|
48 |
if(err != KErrNone)
|
|
49 |
{
|
|
50 |
LOG_MSG2("RCoreDumpSession::StartServer - creating server failed! err:%d\n", err);
|
|
51 |
return err;
|
|
52 |
}
|
|
53 |
|
|
54 |
//Set up Rendezvous so that server thread can signal correct startup
|
|
55 |
TRequestStatus serverDiedRequestStatus;
|
|
56 |
server.Rendezvous( serverDiedRequestStatus );
|
|
57 |
|
|
58 |
// Status flag should still be pending as we haven't resumed the server yet!
|
|
59 |
if( serverDiedRequestStatus != KRequestPending )
|
|
60 |
{
|
|
61 |
LOG_MSG2("RCoreDumpSession::StartServer - rendezvous failed! err:%d\n", serverDiedRequestStatus.Int());
|
|
62 |
server.Kill(KErrAbort);
|
|
63 |
server.Close();
|
|
64 |
return serverDiedRequestStatus.Int();
|
|
65 |
}
|
|
66 |
server.Resume();
|
|
67 |
|
|
68 |
LOG_MSG("RCoreDumpSession::StartServer -> User::WaitForRequest()\n");
|
|
69 |
|
|
70 |
// Will block here until server signals starts
|
|
71 |
User::WaitForRequest( serverDiedRequestStatus );
|
|
72 |
|
|
73 |
LOG_MSG("RCoreDumpSession::StartServer -> Close()\n");
|
|
74 |
|
|
75 |
// we can't use the 'exit reason' if the server panicked as this
|
|
76 |
// is the panic 'reason' and may be '0' which cannot be distinguished from KErrNone
|
|
77 |
err = ( server.ExitType()==EExitPanic ) ? KErrGeneral : serverDiedRequestStatus.Int();
|
|
78 |
server.Close();
|
|
79 |
return err;
|
|
80 |
}
|
|
81 |
|
|
82 |
|
|
83 |
/**
|
|
84 |
Constructor. It initializes the member variables to zero.
|
|
85 |
*/
|
|
86 |
EXPORT_C RCoreDumpSession::RCoreDumpSession()
|
|
87 |
: iConnected(EFalse), iMaxConfigParamSize(0)
|
|
88 |
{
|
|
89 |
}
|
|
90 |
|
|
91 |
|
|
92 |
/**
|
|
93 |
First call that a client must make to use the Core Dump server. This call
|
|
94 |
starts the server if not already running, and then connects to it.
|
|
95 |
@return KErrNone if connection was successfully created, or one of the other
|
|
96 |
system wide error codes
|
|
97 |
*/
|
|
98 |
EXPORT_C TInt RCoreDumpSession::Connect()
|
|
99 |
{
|
|
100 |
LOG_MSG("->RCoreDumpSession::Connect()\n");
|
|
101 |
|
|
102 |
if(iConnected != EFalse)
|
|
103 |
{
|
|
104 |
LOG_MSG("RCoreDumpSession::Connect - already connected\n");
|
|
105 |
return KErrNone;
|
|
106 |
}
|
|
107 |
|
|
108 |
TInt err;
|
|
109 |
|
|
110 |
for(TInt i = 0; i < KConnectionRetries; i++)
|
|
111 |
{
|
|
112 |
LOG_MSG("RCoreDumpSession::Connect -> StartServer()\n");
|
|
113 |
err = StartServer();
|
|
114 |
if( (KErrNone != err) && (KErrAlreadyExists != err) )
|
|
115 |
{
|
|
116 |
return err;
|
|
117 |
}
|
|
118 |
|
|
119 |
LOG_MSG("RCoreDumpSession::Connect - CreateSession()\n");
|
|
120 |
err = CreateSession( KCoreDumpServerName, Version(), KTTDefaultMessageSlots );
|
|
121 |
|
|
122 |
if(KErrNone == err)
|
|
123 |
{
|
|
124 |
LOG_MSG("RCoreDumpSession::Connect - session created successfully\n");
|
|
125 |
iConnected = ETrue;
|
|
126 |
return KErrNone;
|
|
127 |
}
|
|
128 |
}
|
|
129 |
LOG_MSG("RCoreDumpSession::Connect - too many retries!\n");
|
|
130 |
return err;
|
|
131 |
}
|
|
132 |
|
|
133 |
/**
|
|
134 |
Required to be called to close the session with the CoreDumpServer.
|
|
135 |
It automatically closes this session handle.
|
|
136 |
*/
|
|
137 |
EXPORT_C void RCoreDumpSession::Disconnect()
|
|
138 |
{
|
|
139 |
iConnected = EFalse;
|
|
140 |
RSessionBase::Close();
|
|
141 |
}
|
|
142 |
|
|
143 |
/**
|
|
144 |
Provides the version number of the server we require for this API.
|
|
145 |
@return TVersion object representing the version of the server
|
|
146 |
*/
|
|
147 |
TVersion RCoreDumpSession::Version () const
|
|
148 |
{
|
|
149 |
return TVersion(KCoreDumpServMajorVersionNumber,
|
|
150 |
KCoreDumpServMinorVersionNumber,
|
|
151 |
KCoreDumpServBuildVersionNumber);
|
|
152 |
}
|
|
153 |
|
|
154 |
/**
|
|
155 |
Provides the caller with a list of the currently running processes.
|
|
156 |
@param aProcessList Reference to the pointer list that is going to be filled
|
|
157 |
with CProcessInfo objects. The caller takes ownership of the content.
|
|
158 |
@see RProcessPointerList
|
|
159 |
*/
|
|
160 |
EXPORT_C void RCoreDumpSession::GetProcessesL( RProcessPointerList & aProcessList ) const
|
|
161 |
{
|
|
162 |
LOG_MSG("->RCoreDumpSession::GetProcessesL()\n");
|
|
163 |
|
|
164 |
aProcessList.ResetAndDestroy();
|
|
165 |
|
|
166 |
TListRequest request;
|
|
167 |
request.iListType = TListRequest::EProcessList;
|
|
168 |
request.iSubId1 = 0;
|
|
169 |
request.iSubId2 = 0;
|
|
170 |
request.iRequiredDescriptorSize = 0;
|
|
171 |
|
|
172 |
const TUint8 * bufStart = GetListLC(request).Ptr();
|
|
173 |
TUint nextObjOffset = 0;
|
|
174 |
for(TInt i = 0 ; i < request.iRemaining; i++)
|
|
175 |
{
|
|
176 |
TPtrC8 nextObj( (bufStart + nextObjOffset), CProcessInfo::MaxSize() );
|
|
177 |
CProcessInfo * processInfoPtr = CProcessInfo::NewL( nextObj );
|
|
178 |
|
|
179 |
TInt err = aProcessList.Append(processInfoPtr);
|
|
180 |
if(err != KErrNone)
|
|
181 |
{
|
|
182 |
LOG_MSG2("RCoreDumpSession::GetProcessesL - unable to append process info object! err:%d\n", err);
|
|
183 |
delete processInfoPtr;
|
|
184 |
User::Leave(err);
|
|
185 |
}
|
|
186 |
nextObjOffset += processInfoPtr->Size();
|
|
187 |
}
|
|
188 |
CleanupStack::PopAndDestroy(); //GetListLC
|
|
189 |
}
|
|
190 |
|
|
191 |
|
|
192 |
/**
|
|
193 |
Provides the caller with a list of executables.
|
|
194 |
@param aExecutableList reference to the pointer list that is going to be filled
|
|
195 |
with CExecutableInfo objects. The caller takes ownership of the content.
|
|
196 |
@see RExecutablePointerList
|
|
197 |
*/
|
|
198 |
EXPORT_C void RCoreDumpSession::GetExecutablesL( RExecutablePointerList & aExecutableList ) const
|
|
199 |
{
|
|
200 |
LOG_MSG("->RCoreDumpSession::GetExecutablesL()\n");
|
|
201 |
|
|
202 |
aExecutableList.ResetAndDestroy();
|
|
203 |
|
|
204 |
TListRequest request;
|
|
205 |
request.iListType = TListRequest::EExecutableList;
|
|
206 |
request.iSubId1 = 0;
|
|
207 |
request.iSubId2 = 0;
|
|
208 |
request.iRequiredDescriptorSize = 0;
|
|
209 |
|
|
210 |
const TUint8 * bufStart = GetListLC(request).Ptr();
|
|
211 |
TUint nextObjOffset = 0;
|
|
212 |
for(TInt i = 0 ; i < request.iRemaining; i++)
|
|
213 |
{
|
|
214 |
TPtrC8 nextObj( (bufStart + nextObjOffset), CExecutableInfo::MaxSize() );
|
|
215 |
CExecutableInfo * executableInfoPtr = CExecutableInfo::NewL( nextObj );
|
|
216 |
|
|
217 |
TInt err = aExecutableList.Append( executableInfoPtr );
|
|
218 |
if(err != KErrNone)
|
|
219 |
{
|
|
220 |
LOG_MSG2("RCoreDumpSession::GetExecutablesL - unable to append Executable info object! err:%d\n", err);
|
|
221 |
delete executableInfoPtr;
|
|
222 |
User::Leave(err);
|
|
223 |
}
|
|
224 |
nextObjOffset += executableInfoPtr->Size();
|
|
225 |
}
|
|
226 |
CleanupStack::PopAndDestroy(); //GetListLC
|
|
227 |
}
|
|
228 |
|
|
229 |
/**
|
|
230 |
Provides the caller with a list of currently running threads.
|
|
231 |
@param aThreadList reference to the pointer list that is going to be filled
|
|
232 |
with CThreadInfo objects. The caller takes ownership of the content.
|
|
233 |
@param aPid Specify this to narrow the list of threads to a particular process.
|
|
234 |
@see RThreadPointerList
|
|
235 |
*/
|
|
236 |
EXPORT_C void RCoreDumpSession::GetThreadsL( RThreadPointerList & aThreadList, const TUint64 aPid ) const
|
|
237 |
{
|
|
238 |
LOG_MSG("->RCoreDumpSession::GetThreadsL()\n");
|
|
239 |
|
|
240 |
aThreadList.ResetAndDestroy();
|
|
241 |
|
|
242 |
TListRequest request;
|
|
243 |
request.iListType = TListRequest::EThreadList;
|
|
244 |
request.iSubId1 = aPid;
|
|
245 |
request.iSubId2 = 0;
|
|
246 |
request.iRequiredDescriptorSize = 0;
|
|
247 |
|
|
248 |
const TUint8 * bufStart = GetListLC(request).Ptr();
|
|
249 |
TUint nextObjOffset = 0;
|
|
250 |
|
|
251 |
for(TInt i = 0 ; i < request.iRemaining; i++)
|
|
252 |
{
|
|
253 |
TPtrC8 nextObj( (bufStart + nextObjOffset), CThreadInfo::MaxSize() );
|
|
254 |
CThreadInfo * threadInfoPtr = CThreadInfo::NewL( nextObj );
|
|
255 |
TInt err = aThreadList.Append(threadInfoPtr);
|
|
256 |
if(err != KErrNone)
|
|
257 |
{
|
|
258 |
LOG_MSG2("RCoreDumpSession::GetThreads - unable to append thread info object! err:%d\n", err);
|
|
259 |
delete threadInfoPtr;
|
|
260 |
User::Leave(err);
|
|
261 |
}
|
|
262 |
nextObjOffset += threadInfoPtr->Size();
|
|
263 |
}
|
|
264 |
|
|
265 |
CleanupStack::PopAndDestroy(); //GetListLC
|
|
266 |
}
|
|
267 |
|
|
268 |
/**
|
|
269 |
@param aFormatterList Reference to the pointer list that is going to be filled
|
|
270 |
with CPluginInfo objects. The caller takes ownership of the content.
|
|
271 |
@see RPluginPointerList
|
|
272 |
*/
|
|
273 |
EXPORT_C void RCoreDumpSession::GetFormattersL( RPluginPointerList &aFormatterList ) const
|
|
274 |
{
|
|
275 |
LOG_MSG("->RCoreDumpSession::GetFormattersL()\n");
|
|
276 |
|
|
277 |
aFormatterList.ResetAndDestroy();
|
|
278 |
|
|
279 |
TListRequest request;
|
|
280 |
request.iListType = TListRequest::EFormatterList;
|
|
281 |
request.iSubId1 = 0;
|
|
282 |
request.iSubId2 = 0;
|
|
283 |
request.iRequiredDescriptorSize = 0;
|
|
284 |
|
|
285 |
const TUint8 * bufStart = GetListLC(request).Ptr();
|
|
286 |
TUint nextObjOffset = 0;
|
|
287 |
for(TInt i = 0 ; i < request.iRemaining; i++)
|
|
288 |
{
|
|
289 |
TPtrC8 nextObj( (bufStart + nextObjOffset), CPluginInfo::MaxSize() );
|
|
290 |
CPluginInfo * pluginInfoPtr = CPluginInfo::NewL( nextObj );
|
|
291 |
|
|
292 |
TInt err = aFormatterList.Append(pluginInfoPtr);
|
|
293 |
if(err != KErrNone)
|
|
294 |
{
|
|
295 |
LOG_MSG2("RCoreDumpSession::GetPluginsL - unable to append plugin info object! err:%d\n", err);
|
|
296 |
delete pluginInfoPtr;
|
|
297 |
User::Leave(err);
|
|
298 |
}
|
|
299 |
nextObjOffset += pluginInfoPtr->Size();
|
|
300 |
}
|
|
301 |
CleanupStack::PopAndDestroy(); //GetListLC
|
|
302 |
}
|
|
303 |
|
|
304 |
/**
|
|
305 |
* Lists the crashes in the flash partition
|
|
306 |
* @param aCrashes Array in which to store the list of crashes
|
|
307 |
* @leave one of the OS wide codes
|
|
308 |
*/
|
|
309 |
EXPORT_C void RCoreDumpSession::ListCrashesInFlashL(RCrashInfoPointerList& aCrashes) const
|
|
310 |
{
|
|
311 |
LOG_MSG("->RCoreDumpSession::ListCrashesInFlash()\n");
|
|
312 |
|
|
313 |
aCrashes.ResetAndDestroy();
|
|
314 |
|
|
315 |
TListRequest request;
|
|
316 |
request.iListType = TListRequest::ECrashList;
|
|
317 |
request.iSubId1 = 0;
|
|
318 |
request.iSubId2 = 0;
|
|
319 |
request.iRequiredDescriptorSize = 0;
|
|
320 |
|
|
321 |
const TUint8 * bufStart = GetListLC(request).Ptr();
|
|
322 |
TUint nextObjOffset = 0;
|
|
323 |
for(TInt i = 0 ; i < request.iRemaining; i++)
|
|
324 |
{
|
|
325 |
TPtrC8 nextObj( (bufStart + nextObjOffset), TCrashInfo::MaxSize() );
|
|
326 |
TCrashInfo* crashInf = TCrashInfo::NewL( nextObj );
|
|
327 |
|
|
328 |
TInt err = aCrashes.Append(crashInf);
|
|
329 |
if(err != KErrNone)
|
|
330 |
{
|
|
331 |
LOG_MSG2("RCoreDumpSession::ListCrashesInFlash - unable to append plugin info object! err:%d\n", err);
|
|
332 |
delete crashInf;
|
|
333 |
User::Leave(err);
|
|
334 |
}
|
|
335 |
nextObjOffset += crashInf->iSize;
|
|
336 |
}
|
|
337 |
CleanupStack::PopAndDestroy(); //GetListLC
|
|
338 |
}
|
|
339 |
|
|
340 |
/**
|
|
341 |
* Deletes crash log specified from the flash partition
|
|
342 |
* @param aCrashId Identifier of crash to delete
|
|
343 |
* @leave One of the OS wide codes
|
|
344 |
*/
|
|
345 |
EXPORT_C void RCoreDumpSession::DeleteCrashLogL(const TInt aCrashId) const
|
|
346 |
{
|
|
347 |
LOG_MSG2("->RCoreDumpSession::DeleteCrashLogL(ID = [%d])\n", aCrashId);
|
|
348 |
TIpcArgs args(aCrashId);
|
|
349 |
|
|
350 |
TInt err = SendReceive(ECoreDumpDeleteLogRequest, args);
|
|
351 |
if(err != KErrNone)
|
|
352 |
{
|
|
353 |
LOG_MSG2("->RCoreDumpSession::DeleteCrashLogL() - unable to delete log -> err:%d\n", err);
|
|
354 |
User::Leave(err);
|
|
355 |
}
|
|
356 |
}
|
|
357 |
|
|
358 |
/**
|
|
359 |
* Deletes crash partition from the flash partition
|
|
360 |
* @param aCrashId Identifier of crash to delete
|
|
361 |
* @leave One of the OS wide codes
|
|
362 |
*/
|
|
363 |
EXPORT_C void RCoreDumpSession::DeleteCrashPartitionL() const
|
|
364 |
{
|
|
365 |
LOG_MSG("->RCoreDumpSession::DeleteCrashPartitionL");
|
|
366 |
|
|
367 |
TInt err = SendReceive(ECoreDumpDeleteCrashPartitionRequest);
|
|
368 |
if(err != KErrNone)
|
|
369 |
{
|
|
370 |
LOG_MSG2("->RCoreDumpSession::DeleteCrashPartitionL() - unable to delete log -> err:%d\n", err);
|
|
371 |
User::Leave(err);
|
|
372 |
}
|
|
373 |
}
|
|
374 |
|
|
375 |
/**
|
|
376 |
* Processes the crash log in the flash partition corrosponding to the crash ID of this
|
|
377 |
* TCrashInfo object. If this doesnt match a crash in the partition, or the flash cannot be read
|
|
378 |
* this will leave with KErrCorrupted
|
|
379 |
* @param aCrash The crash to be processed
|
|
380 |
* @leave One of the OS wide codes
|
|
381 |
*/
|
|
382 |
EXPORT_C void RCoreDumpSession::ProcessCrashLogL(TInt aCrashId)
|
|
383 |
{
|
|
384 |
LOG_MSG2("->RCoreDumpSession::ProcessCrashLogL(ID = [%d])\n", aCrashId);
|
|
385 |
|
|
386 |
/* TPckgBuf<TCrashInfo> requestPckg(aCrashInfo);
|
|
387 |
TIpcArgs args(&requestPckg);*/
|
|
388 |
TIpcArgs args(aCrashId);
|
|
389 |
|
|
390 |
TInt err = SendReceive(ECoreDumpProcessFlashCrash, args);
|
|
391 |
if(err != KErrNone)
|
|
392 |
{
|
|
393 |
LOG_MSG2("->RCoreDumpSession::ProcessCrashLogL() - unable to process crash log -> err:%d\n", err);
|
|
394 |
User::Leave(err);
|
|
395 |
}
|
|
396 |
}
|
|
397 |
|
|
398 |
/**
|
|
399 |
* Processes the crash log Asynchronously in the flash partition corresponding to the crash ID of this
|
|
400 |
* TCrashInfo object.
|
|
401 |
* @param aCrashId The crash to be processed
|
|
402 |
* @param aStatus asynchronous request status object
|
|
403 |
*/
|
|
404 |
EXPORT_C void RCoreDumpSession::ProcessCrashLog(const TInt aCrashId, TRequestStatus &aStatus)
|
|
405 |
{
|
|
406 |
LOG_MSG2("->RCoreDumpSession::ProcessCrashLog async (ID = [%d])\n", aCrashId);
|
|
407 |
|
|
408 |
TIpcArgs args(aCrashId);
|
|
409 |
SendReceive(ECoreDumpProcessCrashAsync, args, aStatus);
|
|
410 |
|
|
411 |
}
|
|
412 |
|
|
413 |
/**
|
|
414 |
* Cancel a previously issued asynchronous RCoreDumpSession::ProcessCrashLog call
|
|
415 |
* @param aCrash The crash to be processed
|
|
416 |
* @return Any error which may be returned by RSessionBase::SendReceive()
|
|
417 |
*/
|
|
418 |
EXPORT_C TInt RCoreDumpSession::CancelProcessCrashLog(TInt aCrashId)
|
|
419 |
{
|
|
420 |
LOG_MSG2("->RCoreDumpSession::CancelProcessCrashLog async (ID = [%d])\n", aCrashId);
|
|
421 |
|
|
422 |
TIpcArgs args(aCrashId);
|
|
423 |
return SendReceive(ECoreDumpCancelProcessCrashAsync, args);
|
|
424 |
|
|
425 |
}
|
|
426 |
|
|
427 |
|
|
428 |
/**
|
|
429 |
@param aFormatterList Reference to the pointer list that is going to be filled
|
|
430 |
with CPluginInfo objects. The caller takes ownership of the content.
|
|
431 |
@see RPluginPointerList
|
|
432 |
*/
|
|
433 |
EXPORT_C void RCoreDumpSession::GetWritersL( RPluginPointerList &aWriterList ) const
|
|
434 |
{
|
|
435 |
LOG_MSG("->RCoreDumpSession::GetWritersL()\n");
|
|
436 |
|
|
437 |
aWriterList.ResetAndDestroy();
|
|
438 |
|
|
439 |
TListRequest request;
|
|
440 |
request.iListType = TListRequest::EWriterList;
|
|
441 |
request.iSubId1 = 0;
|
|
442 |
request.iSubId2 = 0;
|
|
443 |
request.iRequiredDescriptorSize = 0;
|
|
444 |
|
|
445 |
const TUint8 * bufStart = GetListLC(request).Ptr();
|
|
446 |
TUint nextObjOffset = 0;
|
|
447 |
for(TInt i = 0 ; i < request.iRemaining; i++)
|
|
448 |
{
|
|
449 |
TPtrC8 nextObj( (bufStart + nextObjOffset), CPluginInfo::MaxSize() );
|
|
450 |
CPluginInfo * pluginInfoPtr = CPluginInfo::NewL( nextObj );
|
|
451 |
|
|
452 |
TInt err = aWriterList.Append(pluginInfoPtr);
|
|
453 |
if(err != KErrNone)
|
|
454 |
{
|
|
455 |
LOG_MSG2("RCoreDumpSession::GetPluginsL - unable to append plugin info object! err:%d\n", err);
|
|
456 |
delete pluginInfoPtr;
|
|
457 |
User::Leave(err);
|
|
458 |
}
|
|
459 |
nextObjOffset += pluginInfoPtr->Size();
|
|
460 |
}
|
|
461 |
CleanupStack::PopAndDestroy(); //GetListLC
|
|
462 |
}
|
|
463 |
|
|
464 |
/**
|
|
465 |
Called by GetProcessesL and GetThreadsL methods to get list information from the CoreDumpServer.
|
|
466 |
@param aRequest structure defining list request
|
|
467 |
@return descriptor holding serialized list content or null descriptor if unable to get any data.
|
|
468 |
*/
|
|
469 |
const TDesC8 &RCoreDumpSession::GetListLC(const TListRequest &aRequest) const
|
|
470 |
{
|
|
471 |
LOG_MSG2("->RCoreDumpSession::GetListLC(iType=%d)\n", aRequest.iListType);
|
|
472 |
TPckg<TListRequest> requestPckgPtr( aRequest );
|
|
473 |
TIpcArgs reqArgs( &requestPckgPtr );
|
|
474 |
|
|
475 |
TInt err = SendReceive( ECoreDumpGetListInfo, reqArgs );
|
|
476 |
|
|
477 |
if(err != KErrNone)
|
|
478 |
{
|
|
479 |
LOG_MSG2( "RCoreDumpSession::GetListL() - unable to get list info! err:%d\n", err );
|
|
480 |
User::Leave(err);
|
|
481 |
}
|
|
482 |
|
|
483 |
HBufC8 *buf = HBufC8::NewMaxL( aRequest.iRequiredDescriptorSize );
|
|
484 |
CleanupStack::PushL( buf );
|
|
485 |
|
|
486 |
if( ( aRequest.iRemaining == 0) || ( aRequest.iRequiredDescriptorSize == 0 ) )
|
|
487 |
{
|
|
488 |
LOG_MSG("RCoreDumpSession::GetListL() - no data to transfer\n");
|
|
489 |
return *buf;
|
|
490 |
}
|
|
491 |
|
|
492 |
TPtr8 ptr(buf->Des());
|
|
493 |
TIpcArgs listArgs( &requestPckgPtr, &ptr );
|
|
494 |
err = SendReceive( ECoreDumpGetListData, listArgs );
|
|
495 |
|
|
496 |
if(err != KErrNone)
|
|
497 |
{
|
|
498 |
LOG_MSG2("RCoreDumpSession::GetListL() - unable to get list data! err:%d\n", err);
|
|
499 |
User::Leave(err);
|
|
500 |
}
|
|
501 |
|
|
502 |
return *buf;
|
|
503 |
}
|
|
504 |
|
|
505 |
/**
|
|
506 |
Provides the caller with a list of currently available formatter and
|
|
507 |
writer plugins.
|
|
508 |
@param aPluginList reference to list to be filled with TPluginInfo structs.
|
|
509 |
The caller takes ownership of the content.
|
|
510 |
@see RPluginList
|
|
511 |
*/
|
|
512 |
EXPORT_C void RCoreDumpSession::GetPluginListL(RPluginList &aPluginList) const
|
|
513 |
{
|
|
514 |
LOG_MSG("RCoreDumpSession::GetPluginListL()\n");
|
|
515 |
aPluginList.Reset();
|
|
516 |
|
|
517 |
TPluginInfoBlock *pluginArr = new(ELeave) TPluginInfoBlock;
|
|
518 |
CleanupStack::PushL(pluginArr);
|
|
519 |
TPtr8 pluginArrPtr( (TUint8*)pluginArr, sizeof(TPluginInfoBlock) );
|
|
520 |
|
|
521 |
TListRequest request;
|
|
522 |
request.iIndex = 0; //the one that really matters on the server side
|
|
523 |
do
|
|
524 |
{
|
|
525 |
TPckgBuf<TListRequest> requestPckg(request);
|
|
526 |
TIpcArgs reqArgs( &requestPckg , &pluginArrPtr );
|
|
527 |
TInt err = SendReceive( ECoreDumpServGetPluginList, reqArgs );
|
|
528 |
|
|
529 |
if(err != KErrNone)
|
|
530 |
{
|
|
531 |
LOG_MSG2("RCoreDumpSession::GetPluginListL - unable to get plugin list! err:%d\n", err);
|
|
532 |
User::Leave(err);
|
|
533 |
}
|
|
534 |
|
|
535 |
request = requestPckg();
|
|
536 |
if(request.iIndex == 0)
|
|
537 |
{
|
|
538 |
LOG_MSG3("RCoreDumpSession::GetPluginListL - first call got:%d from %d\n",
|
|
539 |
request.iSupplied, request.iSupplied + request.iRemaining);
|
|
540 |
request.iIndex = request.iSupplied;
|
|
541 |
}
|
|
542 |
else
|
|
543 |
{
|
|
544 |
LOG_MSG3("RCoreDumpSession::GetPluginListL - following call got:%d from %d\n",
|
|
545 |
request.iSupplied, request.iSupplied + request.iRemaining);
|
|
546 |
request.iIndex += request.iSupplied;
|
|
547 |
}
|
|
548 |
|
|
549 |
for(TInt i = 0; i < request.iSupplied; i++)
|
|
550 |
{
|
|
551 |
TPluginInfo pluginData;
|
|
552 |
pluginData.iVersion = pluginArr->plugins[i].iVersion;
|
|
553 |
pluginData.iName = pluginArr->plugins[i].iName;
|
|
554 |
pluginData.iUid = pluginArr->plugins[i].iUid;
|
|
555 |
pluginData.iType = pluginArr->plugins[i].iType;
|
|
556 |
pluginData.iDescription = pluginArr->plugins[i].iDescription;
|
|
557 |
pluginData.iLoaded = pluginArr->plugins[i].iLoaded;
|
|
558 |
aPluginList.AppendL( pluginData );
|
|
559 |
}
|
|
560 |
}
|
|
561 |
while(request.iRemaining > 0);
|
|
562 |
CleanupStack::PopAndDestroy(pluginArr);
|
|
563 |
}
|
|
564 |
|
|
565 |
/**
|
|
566 |
Make a request to load/unload a plugin.
|
|
567 |
@param aPluginRequest Structure defining the plugin request
|
|
568 |
@see TPluginRequest
|
|
569 |
*/
|
|
570 |
EXPORT_C void RCoreDumpSession::PluginRequestL(const TPluginRequest &aPluginRequest ) const
|
|
571 |
{
|
|
572 |
LOG_MSG("->RCoreDumpSession::PluginRequestL()\n");
|
|
573 |
|
|
574 |
TPckgBuf<TPluginRequest> requestPckg(aPluginRequest);
|
|
575 |
TIpcArgs reqArgs( &requestPckg );
|
|
576 |
|
|
577 |
LOG_MSG4("RCoreDumpSession::PluginRequestL(): iPluginType=%d, iIndex=%d, iUid=0x%X\n",
|
|
578 |
aPluginRequest.iPluginType, aPluginRequest.iIndex, aPluginRequest.iUid );
|
|
579 |
|
|
580 |
TInt err = SendReceive( ECoreDumpPluginRequest, reqArgs );
|
|
581 |
if(err != KErrNone)
|
|
582 |
{
|
|
583 |
LOG_MSG2("->RCoreDumpSession::PluginRequestL() - unable to load plugin! err:%d\n", err);
|
|
584 |
User::Leave(err);
|
|
585 |
}
|
|
586 |
}
|
|
587 |
|
|
588 |
/**
|
|
589 |
Request the observation of a thread or process. To observe a process, aTargetName and
|
|
590 |
aTargetOwnerName must be the same and be the name of the process.
|
|
591 |
To observe a thread, aTargetOwnerName is the name of the process and aTargetName is the name
|
|
592 |
To observe an executable, aTargetOwnerName is the full path to the exe and aTargetName is also the full path to the exe
|
|
593 |
of the thread.
|
|
594 |
@param aTargetName Name of process or thread
|
|
595 |
@param aTargetOwnerName Name of process
|
|
596 |
@param aObserve Set to ETrue to request the observation of the target. EFalse to stop observing the target.
|
|
597 |
@see GetProcessesL
|
|
598 |
@see GetThreadsL
|
|
599 |
*/
|
|
600 |
EXPORT_C void RCoreDumpSession::ObservationRequestL(const TDesC &aTargetName, const TDesC &aTargetOwnerName, TBool aObserve) const
|
|
601 |
{
|
|
602 |
LOG_MSG("->RCoreDumpSession::ObservationRequestL()\n");
|
|
603 |
TIpcArgs args(&aTargetName, &aTargetOwnerName, static_cast<TInt>(aObserve));
|
|
604 |
|
|
605 |
TInt err = SendReceive(ECoreDumpObservationRequest, args);
|
|
606 |
if(err != KErrNone)
|
|
607 |
{
|
|
608 |
LOG_MSG2("->RCoreDumpSession::ObservationRequestL() - unable to [un]observe target! err:%d\n", err);
|
|
609 |
User::Leave(err);
|
|
610 |
}
|
|
611 |
}
|
|
612 |
|
|
613 |
|
|
614 |
/**
|
|
615 |
Return the total list of configuration parameters currently available.
|
|
616 |
The list is made up of the parameters from the Core Dump Server and any loaded plugins.
|
|
617 |
@see COptionConfig
|
|
618 |
*/
|
|
619 |
EXPORT_C TInt RCoreDumpSession::GetNumberConfigParametersL() const
|
|
620 |
{
|
|
621 |
LOG_MSG("->RCoreDumpSession::GetNumberConfigParameters()\n" );
|
|
622 |
TInt numParams;
|
|
623 |
TPtr8 numParamPtr( (TUint8*) &numParams, sizeof(TInt) );
|
|
624 |
|
|
625 |
TPtr8 maxConfigParamSizePtr( (TUint8*) &iMaxConfigParamSize, sizeof(TInt) );
|
|
626 |
TIpcArgs reqArgs( &numParamPtr, &maxConfigParamSizePtr );
|
|
627 |
|
|
628 |
TInt err = SendReceive( ECoreDumpGetNumberConfigParams, reqArgs );
|
|
629 |
|
|
630 |
if(err != KErrNone)
|
|
631 |
{
|
|
632 |
LOG_MSG2( "RCoreDumpSession::GetNumberConfigParams() - unable to get params number! err:%d \n", err);
|
|
633 |
User::Leave(err);
|
|
634 |
}
|
|
635 |
|
|
636 |
return numParams;
|
|
637 |
}
|
|
638 |
|
|
639 |
|
|
640 |
/**
|
|
641 |
Obtain the configuration parameter indexed by aIndex.
|
|
642 |
@param aIndex This must be less than the value returned by GetNumberConfigParametersL().
|
|
643 |
@see COptionConfig
|
|
644 |
*/
|
|
645 |
EXPORT_C COptionConfig * RCoreDumpSession::GetConfigParameterL( const TInt aIndex ) const
|
|
646 |
{
|
|
647 |
LOG_MSG("->RCoreDumpSession::GetConfigParameterL()\n" );
|
|
648 |
|
|
649 |
// Allocate the max, rounded up, plus 4 bytes for safety
|
|
650 |
HBufC8 *buf = HBufC8::NewMaxL( Align4(iMaxConfigParamSize) );
|
|
651 |
CleanupStack::PushL(buf);
|
|
652 |
TPtr8 ptr( buf->Des() );
|
|
653 |
ptr.FillZ();
|
|
654 |
|
|
655 |
TIpcArgs configArgs( aIndex, &ptr );
|
|
656 |
|
|
657 |
TInt err = SendReceive( ECoreDumpGetConfigParam, configArgs );
|
|
658 |
|
|
659 |
if(err != KErrNone)
|
|
660 |
{
|
|
661 |
LOG_MSG3("RCoreDumpSession::GetConfigParameter() - unable to get parameter:%d! err:%d\n", aIndex, err );
|
|
662 |
User::Leave(err);
|
|
663 |
}
|
|
664 |
|
|
665 |
COptionConfig *option = COptionConfig::NewL(*buf);
|
|
666 |
CleanupStack::PopAndDestroy(buf);
|
|
667 |
return option;
|
|
668 |
}
|
|
669 |
|
|
670 |
|
|
671 |
/**
|
|
672 |
Change a configuration parameter.
|
|
673 |
@param aConfig The modified parameter that will be changed. The index and source are
|
|
674 |
checked against those held by the server.
|
|
675 |
*/
|
|
676 |
EXPORT_C void RCoreDumpSession::SetConfigParameterL( const COptionConfig &aConfig) const
|
|
677 |
{
|
|
678 |
LOG_MSG4("->RCoreDumpSession::SetConfigParameterL( aSource=%d, aIndex=%d, aInstance=%d)\n",
|
|
679 |
aConfig.Source(), aConfig.Index(), aConfig.Index() );
|
|
680 |
|
|
681 |
TConfigRequest request;
|
|
682 |
request.iSource = aConfig.Source();
|
|
683 |
request.iIndex = aConfig.Index();
|
|
684 |
request.iInstance = aConfig.Instance();
|
|
685 |
|
|
686 |
TPckg<TConfigRequest> requestPckgPtr( request );
|
|
687 |
|
|
688 |
TIpcArgs configArgs( &requestPckgPtr, aConfig.Value(), &aConfig.ValueAsDesc() );
|
|
689 |
TInt err = SendReceive( ECoreDumpSetConfigParam, configArgs );
|
|
690 |
|
|
691 |
if(err != KErrNone)
|
|
692 |
{
|
|
693 |
LOG_MSG3("RCoreDumpSession::SetConfigParameterL() - unable to set parameter:%d! err:%d\n", aConfig.Index(), err );
|
|
694 |
User::Leave(err);
|
|
695 |
}
|
|
696 |
}
|
|
697 |
|
|
698 |
|
|
699 |
/**
|
|
700 |
Restore a configuration. Configuration files are created by the Core dump server
|
|
701 |
when it exits and when the call SaveConfigL is made. The format is private and should be
|
|
702 |
considered binary. When the Core dump server exits it stores the current configuration
|
|
703 |
in its private directory with the name coredumpserver.ini.
|
|
704 |
@param aLoadPath File that will be read and restored
|
|
705 |
*/
|
|
706 |
EXPORT_C void RCoreDumpSession::LoadConfigL( const TDesC & aLoadPath ) const
|
|
707 |
{
|
|
708 |
LOG_MSG("->RCoreDumpSession::LoadConfig()\n" );
|
|
709 |
|
|
710 |
TIpcArgs configArgs( &aLoadPath );
|
|
711 |
TInt err = SendReceive( ECoreDumpLoadConfig, configArgs );
|
|
712 |
if(err != KErrNone)
|
|
713 |
{
|
|
714 |
LOG_MSG2("RCoreDumpSession::LoadConfigL() - unable to load config! err:%d\n", err );
|
|
715 |
User::Leave(err);
|
|
716 |
}
|
|
717 |
}
|
|
718 |
|
|
719 |
|
|
720 |
/**
|
|
721 |
Save the current configuration to file.
|
|
722 |
@param aSavePath File that will be saved
|
|
723 |
*/
|
|
724 |
EXPORT_C void RCoreDumpSession::SaveConfigL( const TDesC & aSavePath ) const
|
|
725 |
{
|
|
726 |
LOG_MSG("->RCoreDumpSession::SaveConfig()\n" );
|
|
727 |
TIpcArgs configArgs( &aSavePath );
|
|
728 |
|
|
729 |
TInt err = SendReceive( ECoreDumpSaveConfig, configArgs );
|
|
730 |
if(err != KErrNone)
|
|
731 |
{
|
|
732 |
LOG_MSG2("RCoreDumpSession::SaveConfigL() - unable to save config! err:%d\n", err );
|
|
733 |
User::Leave(err);
|
|
734 |
}
|
|
735 |
}
|
|
736 |
|