Changeset 104892 in vbox for trunk/src/VBox/Runtime
- Timestamp:
- Jun 12, 2024 1:51:26 PM (8 months ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/tools/RTTraceLogTool.cpp
r98103 r104892 40 40 *********************************************************************************************************************************/ 41 41 #include <iprt/tracelog.h> 42 #include <iprt/tracelog-decoder-plugin.h> 42 43 43 44 #include <iprt/assert.h> … … 45 46 #include <iprt/getopt.h> 46 47 #include <iprt/initterm.h> 48 #include <iprt/ldr.h> 47 49 #include <iprt/message.h> 48 50 #include <iprt/mem.h> … … 51 53 #include <iprt/string.h> 52 54 #include <iprt/tcp.h> 55 56 57 /** 58 * Loaded tracelog decoders. 59 */ 60 typedef struct RTTRACELOGDECODERS 61 { 62 /** Pointer to the array of registered decoders. */ 63 PRTTRACELOGDECODERDECODEEVENT paDecodeEvts; 64 /** Number of entries in the decoder array. */ 65 uint32_t cDecoders; 66 /** Allocation size of the decoder array. */ 67 uint32_t cDecodersAlloc; 68 } RTTRACELOGDECODERS; 69 typedef RTTRACELOGDECODERS *PRTTRACELOGDECODERS; 53 70 54 71 … … 174 191 175 192 193 static DECLCALLBACK(int) rtTraceLogToolRegisterDecoders(void *pvUser, PCRTTRACELOGDECODERDECODEEVENT paDecoders, uint32_t cDecoders) 194 { 195 PRTTRACELOGDECODERS pDecoderState = (PRTTRACELOGDECODERS)pvUser; 196 197 if (pDecoderState->cDecodersAlloc - pDecoderState->cDecoders <= cDecoders) 198 { 199 PRTTRACELOGDECODERDECODEEVENT paNew = (PRTTRACELOGDECODERDECODEEVENT)RTMemRealloc(pDecoderState->paDecodeEvts, 200 (pDecoderState->cDecodersAlloc + cDecoders) * sizeof(*paDecoders)); 201 if (!paNew) 202 return VERR_NO_MEMORY; 203 204 pDecoderState->paDecodeEvts = paNew; 205 pDecoderState->cDecodersAlloc += cDecoders; 206 } 207 208 memcpy(&pDecoderState->paDecodeEvts[pDecoderState->cDecoders], paDecoders, cDecoders * sizeof(*paDecoders)); 209 pDecoderState->cDecoders += cDecoders; 210 return VINF_SUCCESS; 211 } 212 213 176 214 int main(int argc, char **argv) 177 215 { … … 185 223 static const RTGETOPTDEF s_aOptions[] = 186 224 { 187 { "--input", 'i', RTGETOPT_REQ_STRING }, 188 { "--save", 's', RTGETOPT_REQ_STRING }, 189 { "--help", 'h', RTGETOPT_REQ_NOTHING }, 190 { "--version", 'V', RTGETOPT_REQ_NOTHING }, 225 { "--input", 'i', RTGETOPT_REQ_STRING }, 226 { "--save", 's', RTGETOPT_REQ_STRING }, 227 { "--load-decoder", 'l', RTGETOPT_REQ_STRING }, 228 { "--help", 'h', RTGETOPT_REQ_NOTHING }, 229 { "--version", 'V', RTGETOPT_REQ_NOTHING }, 191 230 }; 192 231 193 RTEXITCODE rcExit = RTEXITCODE_SUCCESS; 194 const char *pszInput = NULL; 195 const char *pszSave = NULL; 232 RTEXITCODE rcExit = RTEXITCODE_SUCCESS; 233 const char *pszInput = NULL; 234 const char *pszSave = NULL; 235 RTTRACELOGDECODERS Decoders; RT_ZERO(Decoders); 196 236 197 237 RTGETOPTUNION ValueUnion; … … 210 250 " -s,--save=file\n" 211 251 " Save the input to a file for later use\n" 252 " -l,--load-decoder=<plugin path>\n" 253 " Loads the given decoder library used for decoding events\n" 212 254 " -h, -?, --help\n" 213 255 " Display this help text and exit successfully.\n" … … 226 268 pszSave = ValueUnion.psz; 227 269 break; 270 case 'l': 271 { 272 RTLDRMOD hLdrMod; 273 rc = RTLdrLoadEx(ValueUnion.psz, &hLdrMod, RTLDRLOAD_FLAGS_NO_UNLOAD, NULL); 274 if (RT_SUCCESS(rc)) 275 { 276 PFNTRACELOGDECODERPLUGINLOAD pfnLoad = NULL; 277 rc = RTLdrGetSymbol(hLdrMod, RT_TRACELOG_DECODER_PLUGIN_LOAD, (void **)&pfnLoad); 278 if (RT_SUCCESS(rc)) 279 { 280 RTTRACELOGDECODERREGISTER RegCb; 281 282 RegCb.u32Version = RT_TRACELOG_DECODERREG_CB_VERSION; 283 RegCb.pfnRegisterDecoders = rtTraceLogToolRegisterDecoders; 284 285 rc = pfnLoad(&Decoders, &RegCb); 286 if (RT_FAILURE(rc)) 287 return RTMsgErrorExit(RTEXITCODE_FAILURE, "Failed to register decoders %Rrc\n", rc); 288 } 289 else 290 return RTMsgErrorExit(RTEXITCODE_FAILURE, "Failed to lretrieve entry point '%s' %Rrc\n", 291 RT_TRACELOG_DECODER_PLUGIN_LOAD, rc); 292 293 RTLdrClose(hLdrMod); 294 } 295 else 296 return RTMsgErrorExit(RTEXITCODE_FAILURE, "Failed to load decoder library %Rrc\n", rc); 297 break; 298 } 228 299 default: 229 300 return RTGetOptPrintError(rc, &ValueUnion); … … 266 337 RTTraceLogRdrEvtGetTs(hTraceLogEvt), 267 338 pEvtDesc->pszId); 268 for (unsigned i = 0; i < pEvtDesc->cEvtItems; i++) 339 340 /* 341 * Look through our registered decoders and pass the decoding on to it. 342 * If there is no decoder registered just dump the raw values. 343 */ 344 PCRTTRACELOGDECODERDECODEEVENT pDecodeEvt = NULL; 345 for (uint32_t i = 0; i < Decoders.cDecoders; i++) 346 if (!strcmp(Decoders.paDecodeEvts[i].pszId, pEvtDesc->pszId)) 347 { 348 pDecodeEvt = &Decoders.paDecodeEvts[i]; 349 break; 350 } 351 352 if (pDecodeEvt) 269 353 { 270 RTTRACELOGEVTVAL Val; 271 unsigned cVals = 0; 272 rc = RTTraceLogRdrEvtFillVals(hTraceLogEvt, i, &Val, 1, &cVals); 273 if (RT_SUCCESS(rc)) 354 /** @todo Dynamic value allocation (too lazy right now). */ 355 RTTRACELOGEVTVAL aVals[32]; 356 uint32_t cVals = 0; 357 rc = RTTraceLogRdrEvtFillVals(hTraceLogEvt, 0, &aVals[0], RT_ELEMENTS(aVals), 358 &cVals); 359 if ( RT_SUCCESS(rc) 360 || cVals != pEvtDesc->cEvtItems) 274 361 { 275 switch (Val.pItemDesc->enmType) 276 { 277 case RTTRACELOGTYPE_BOOL: 278 RTMsgInfo(" %s: %s\n", Val.pItemDesc->pszName, Val.u.f ? "true" : "false"); 279 break; 280 case RTTRACELOGTYPE_UINT8: 281 RTMsgInfo(" %s: %u\n", Val.pItemDesc->pszName, Val.u.u8); 282 break; 283 case RTTRACELOGTYPE_INT8: 284 RTMsgInfo(" %s: %d\n", Val.pItemDesc->pszName, Val.u.i8); 285 break; 286 case RTTRACELOGTYPE_UINT16: 287 RTMsgInfo(" %s: %u\n", Val.pItemDesc->pszName, Val.u.u16); 288 break; 289 case RTTRACELOGTYPE_INT16: 290 RTMsgInfo(" %s: %d\n", Val.pItemDesc->pszName, Val.u.i16); 291 break; 292 case RTTRACELOGTYPE_UINT32: 293 RTMsgInfo(" %s: %u\n", Val.pItemDesc->pszName, Val.u.u32); 294 break; 295 case RTTRACELOGTYPE_INT32: 296 RTMsgInfo(" %s: %d\n", Val.pItemDesc->pszName, Val.u.i32); 297 break; 298 case RTTRACELOGTYPE_UINT64: 299 RTMsgInfo(" %s: %llu\n", Val.pItemDesc->pszName, Val.u.u64); 300 break; 301 case RTTRACELOGTYPE_INT64: 302 RTMsgInfo(" %s: %lld\n", Val.pItemDesc->pszName, Val.u.i64); 303 break; 304 case RTTRACELOGTYPE_RAWDATA: 305 RTMsgInfo(" %s:\n" 306 "%.*Rhxd\n", Val.pItemDesc->pszName, Val.u.RawData.cb, Val.u.RawData.pb); 307 break; 308 case RTTRACELOGTYPE_FLOAT32: 309 case RTTRACELOGTYPE_FLOAT64: 310 RTMsgInfo(" %s: Float32 and Float64 data not supported yet\n", Val.pItemDesc->pszName); 311 break; 312 case RTTRACELOGTYPE_POINTER: 313 RTMsgInfo(" %s: %#llx\n", Val.pItemDesc->pszName, Val.u.uPtr); 314 break; 315 case RTTRACELOGTYPE_SIZE: 316 RTMsgInfo(" %s: %llu\n", Val.pItemDesc->pszName, Val.u.sz); 317 break; 318 default: 319 RTMsgError(" %s: Invalid type given %d\n", Val.pItemDesc->pszName, Val.pItemDesc->enmType); 320 } 362 rc = pDecodeEvt->pfnDecode(hTraceLogEvt, pEvtDesc, &aVals[0], cVals); 363 if (RT_FAILURE(rc)) 364 RTMsgError("Failed to decode event with ID '%s' -> %Rrc\n", pEvtDesc->pszId, rc); 321 365 } 322 366 else 323 RTMsgInfo(" Failed to retrieve event data with %Rrc\n", rc); 367 RTMsgError("Failed to fill values for event with ID '%s' -> %Rrc (cVals=%u vs. cEvtItems=%u)\n", 368 pEvtDesc->pszId, rc, cVals, pEvtDesc->cEvtItems); 324 369 } 370 else 371 for (unsigned i = 0; i < pEvtDesc->cEvtItems; i++) 372 { 373 RTTRACELOGEVTVAL Val; 374 unsigned cVals = 0; 375 rc = RTTraceLogRdrEvtFillVals(hTraceLogEvt, i, &Val, 1, &cVals); 376 if (RT_SUCCESS(rc)) 377 { 378 switch (Val.pItemDesc->enmType) 379 { 380 case RTTRACELOGTYPE_BOOL: 381 RTMsgInfo(" %s: %s\n", Val.pItemDesc->pszName, Val.u.f ? "true" : "false"); 382 break; 383 case RTTRACELOGTYPE_UINT8: 384 RTMsgInfo(" %s: %u\n", Val.pItemDesc->pszName, Val.u.u8); 385 break; 386 case RTTRACELOGTYPE_INT8: 387 RTMsgInfo(" %s: %d\n", Val.pItemDesc->pszName, Val.u.i8); 388 break; 389 case RTTRACELOGTYPE_UINT16: 390 RTMsgInfo(" %s: %u\n", Val.pItemDesc->pszName, Val.u.u16); 391 break; 392 case RTTRACELOGTYPE_INT16: 393 RTMsgInfo(" %s: %d\n", Val.pItemDesc->pszName, Val.u.i16); 394 break; 395 case RTTRACELOGTYPE_UINT32: 396 RTMsgInfo(" %s: %u\n", Val.pItemDesc->pszName, Val.u.u32); 397 break; 398 case RTTRACELOGTYPE_INT32: 399 RTMsgInfo(" %s: %d\n", Val.pItemDesc->pszName, Val.u.i32); 400 break; 401 case RTTRACELOGTYPE_UINT64: 402 RTMsgInfo(" %s: %llu\n", Val.pItemDesc->pszName, Val.u.u64); 403 break; 404 case RTTRACELOGTYPE_INT64: 405 RTMsgInfo(" %s: %lld\n", Val.pItemDesc->pszName, Val.u.i64); 406 break; 407 case RTTRACELOGTYPE_RAWDATA: 408 RTMsgInfo(" %s:\n" 409 "%.*Rhxd\n", Val.pItemDesc->pszName, Val.u.RawData.cb, Val.u.RawData.pb); 410 break; 411 case RTTRACELOGTYPE_FLOAT32: 412 case RTTRACELOGTYPE_FLOAT64: 413 RTMsgInfo(" %s: Float32 and Float64 data not supported yet\n", Val.pItemDesc->pszName); 414 break; 415 case RTTRACELOGTYPE_POINTER: 416 RTMsgInfo(" %s: %#llx\n", Val.pItemDesc->pszName, Val.u.uPtr); 417 break; 418 case RTTRACELOGTYPE_SIZE: 419 RTMsgInfo(" %s: %llu\n", Val.pItemDesc->pszName, Val.u.sz); 420 break; 421 default: 422 RTMsgError(" %s: Invalid type given %d\n", Val.pItemDesc->pszName, Val.pItemDesc->enmType); 423 } 424 } 425 else 426 RTMsgInfo(" Failed to retrieve event data with %Rrc\n", rc); 427 } 325 428 } 326 429 break;
Note:
See TracChangeset
for help on using the changeset viewer.