コード例 #1
0
ファイル: check_trace.cpp プロジェクト: ACSOP/android_sdk
int main(int argc, char **argv) {
    // Parse the options
    ParseOptions(argc, argv);
    if (argc - optind != 2) {
        Usage(argv[0]);
        exit(1);
    }

    char *trace_filename = argv[optind++];
    char *elf_file = argv[optind++];
    TraceReader<> *trace = new TraceReader<>;
    trace->Open(trace_filename);
    trace->ReadKernelSymbols(elf_file);
    trace->SetRoot(root);

    while (1) {
        symbol_type *sym;
        BBEvent event;
        BBEvent ignored;

        if (GetNextValidEvent(trace, &event, &ignored, &sym))
            break;
        if (event.bb_num == 0)
            break;
        //printf("t%llu bb %lld %d\n", event.time, event.bb_num, event.num_insns);
        uint64_t insn_time = trace->ReadInsnTime(event.time);
        if (insn_time != event.time) {
            printf("time: %llu insn time: %llu bb: %llu addr: 0x%x num_insns: %d, pid: %d\n",
                   event.time, insn_time, event.bb_num, event.bb_addr,
                   event.num_insns, event.pid);
            exit(1);
        }
        for (int ii = 1; ii < event.num_insns; ++ii) {
            trace->ReadInsnTime(event.time);
        }
    }

    delete trace;
    return 0;
}
コード例 #2
0
int main(int argc, char **argv)
{
    bool useKernelStack = true;

    ParseOptions(argc, argv);
    if (argc - optind != 3) {
        Usage(argv[0]);
        exit(1);
    }

    char *qemu_trace_file = argv[optind++];
    char *elf_file = argv[optind++];
    char *dmtrace_file = argv[optind++];
    TraceReaderType *trace = new TraceReaderType;
    trace->Open(qemu_trace_file);
    trace->SetDemangle(demangle);
    trace->ReadKernelSymbols(elf_file);
    trace->SetRoot(root);
    TraceHeader *qheader = trace->GetHeader();
    uint64_t startTime = qheader->start_sec;
    startTime = (startTime << 32) | qheader->start_usec;
    int kernelPid = qheader->first_unused_pid;

    dmtrace = new DmTrace;
    dmtrace->open(dmtrace_file, startTime);

    bool inKernel = false;
    CallStackType *kernelStack = NULL;
    if (useKernelStack) {
        // Create a fake kernel thread stack where we will put all the kernel
        // code.
        kernelStack = new CallStackType(kernelPid, kNumStackFrames, trace);
        dmtrace->addThread(kernelPid, "(kernel)");
    }

    CallStackType *prevStack = NULL;
    BBEvent event;
    while (1) {
        BBEvent ignored;
        symbol_type *function;

        if (GetNextValidEvent(trace, &event, &ignored, &function))
            break;
        if (event.bb_num == 0)
            break;
#if 0
        fprintf(stderr, "event t %llu p %d %s\n",
                event.time, event.pid, function->name);
#endif

        CallStackType *pStack;
        if (useKernelStack) {
            uint32_t flags = function->region->flags;
            uint32_t region_mask = region_type::kIsKernelRegion
                    | region_type::kIsUserMappedRegion;
            if ((flags & region_mask) == region_type::kIsKernelRegion) {
                // Use the kernel stack
                pStack = kernelStack;
                inKernel = true;
            } else {
                // If we were just in the kernel then pop off all of the
                // stack frames for the kernel thread.
                if (inKernel == true) {
                    inKernel = false;
                    kernelStack->popAll(event.time);
                }
                
                // Get the stack for the current thread
                pStack = stacks[event.pid];
            }
        } else {
            // Get the stack for the current thread
            pStack = stacks[event.pid];
        }

        // If the stack does not exist, then allocate a new one.
        if (pStack == NULL) {
            pStack = new CallStackType(event.pid, kNumStackFrames, trace);
            stacks[event.pid] = pStack;
            char *name = trace->GetProcessName(event.pid);
            dmtrace->addThread(event.pid, name);
        }

        if (prevStack != pStack) {
            pStack->threadStart(event.time);
            if (prevStack)
                prevStack->threadStop(event.time);
        }
        prevStack = pStack;

        // If we have never seen this function before, then add it to the
        // list of known functions.
        if (function->id == 0) {
            function->id = nextFunctionId;
            nextFunctionId += 4;
            uint32_t flags = function->region->flags;
            const char *name = function->name;
            if (flags & region_type::kIsKernelRegion) {
                // To distinguish kernel function names from user library
                // names, add a marker to the name.
                int len = strlen(name) + strlen(" [kernel]") + 1;
                char *kernelName = new char[len];
                strcpy(kernelName, name);
                strcat(kernelName, " [kernel]");
                name = kernelName;
            }
            dmtrace->parseAndAddFunction(function->id, name);
        }

        // Update the stack
        pStack->updateStack(&event, function);
    }

    if (prevStack == NULL) {
        fprintf(stderr, "Error: no events in trace.\n");
        exit(1);
    }
    prevStack->threadStop(event.time);
    for (int ii = 0; ii < kMaxThreads; ++ii) {
        if (stacks[ii]) {
            stacks[ii]->threadStart(event.time);
            stacks[ii]->popAll(event.time);
        }
    }
    if (useKernelStack) {
        kernelStack->popAll(event.time);
    }

    // Read the pid events to find the names of the processes
    while (1) {
        PidEvent pid_event;
        if (trace->ReadPidEvent(&pid_event))
            break;
        if (pid_event.rec_type == kPidName) {
            dmtrace->updateName(pid_event.pid, pid_event.path);
        }
    }


    dmtrace->close();
    delete dmtrace;
    delete trace;
    return 0;
}
コード例 #3
0
ファイル: read_trace.cpp プロジェクト: ACSOP/android_sdk
int main(int argc, char **argv) {
    // Parse the options
    ParseOptions(argc, argv);
    localParseOptions(argc, argv);
    if (argc - optind != 2) {
        Usage(argv[0]);
        exit(1);
    }

    char *trace_filename = argv[optind++];
    char *elf_file = argv[optind++];
    TraceReader<> *trace = new TraceReader<>;
    trace->Open(trace_filename);
    trace->SetDemangle(demangle);
    trace->ReadKernelSymbols(elf_file);
    trace->SetRoot(root);

    while (1) {
        symbol_type *sym;
        char buf[1024];
        BBEvent event;
        BBEvent ignored;

        if (GetNextValidEvent(trace, &event, &ignored, &sym))
            break;
#if 0
        fprintf(stderr, "t%llu bb %lld %d\n",
                event.time, event.bb_num, event.num_insns);
#endif

        uint32_t *insns = event.insns;
        uint32_t addr = event.bb_addr;
        uint32_t offset = addr - sym->addr - sym->region->base_addr;
        symbol_type *vm_sym = sym->vm_sym;
        const char *vm_name = NULL;
        if (vm_sym != NULL) {
            vm_name = vm_sym->name;
            offset = addr - vm_sym->addr - vm_sym->region->base_addr;
        }
#if 0
        if (strcmp(sym->name, "(unknown)") == 0 || offset > kOffsetThreshold) {
            ProcessState *process = trace->GetCurrentProcess();
            ProcessState *manager = process->addr_manager;
            for (int ii = 0; ii < manager->nregions; ++ii) {
                printf("  %2d: %08x - %08x base: %08x offset: %u nsyms: %4d flags: 0x%x %s\n",
                       ii,
                       manager->regions[ii]->vstart,
                       manager->regions[ii]->vend,
                       manager->regions[ii]->base_addr,
                       manager->regions[ii]->file_offset,
                       manager->regions[ii]->nsymbols,
                       manager->regions[ii]->flags,
                       manager->regions[ii]->path);
                int nsymbols = manager->regions[ii]->nsymbols;
                for (int jj = 0; jj < 10 && jj < nsymbols; ++jj) {
                    printf("    %08x %s\n",
                           manager->regions[ii]->symbols[jj].addr,
                           manager->regions[ii]->symbols[jj].name);
                }
            }
        }
#endif
#if 1
        for (int ii = 0; ii < event.num_insns; ++ii) {
            uint64_t sim_time = trace->ReadInsnTime(event.time);
            if (sim_time < startTime)
                continue;

            uint32_t insn = insns[ii];
            char *disasm;
            int bytes;
            if (vm_name != NULL) {
                sprintf(buf, "%s+%02x: %s", vm_name, offset, sym->name);
            } else {
                sprintf(buf, "%s+%02x", sym->name, offset);
            }

            if (insn_is_thumb(insn)) {
                bytes = 2;
                insn = insn_unwrap_thumb(insn);

                // thumb_pair is true if this is the first of a pair of
                // thumb instructions (BL or BLX).
                bool thumb_pair = ((insn & 0xf800) == 0xf000);

                // Get the next thumb instruction (if any) because we may need
                // it for the case where insn is BL or BLX.
                uint32_t insn2 = 0;
                if (thumb_pair && (ii + 1 < event.num_insns)) {
                    insn2 = insns[ii + 1];
                    insn2 = insn_unwrap_thumb(insn2);
                    bytes = 4;
                    ii += 1;
                }
                disasm = disasm_insn_thumb(addr, insn, insn2, NULL);
                if (thumb_pair) {
                    printf("%llu p%-4d %08x %04x %04x %-30s %s\n",
                           sim_time, event.pid, addr, insn, insn2, buf, disasm);
                } else {
                    printf("%llu p%-4d %08x     %04x %-30s %s\n",
                           sim_time, event.pid, addr, insn, buf, disasm);
                }
            } else {
                bytes = 4;
                disasm = Arm::disasm(addr, insn, NULL);
                printf("%llu p%-4d %08x %08x %-30s %s\n",
                       sim_time, event.pid, addr, insn, buf, disasm);
            }
            //printf("t%llu \t%08x\n", sim_time, addr);
            addr += bytes;
            offset += bytes;
        }
#endif
#if 0
        assert(offset < kOffsetThreshold);
#endif
    }

    delete trace;
    return 0;
}
コード例 #4
0
ファイル: coverage.cpp プロジェクト: ACSOP/android_sdk
int main(int argc, char **argv)
{
    ParseOptions(argc, argv);
    if (argc - optind != 2) {
        Usage(argv[0]);
        exit(1);
    }

    char *trace_filename = argv[optind++];
    char *elf_file = argv[optind++];
    TraceReader<symbol> *trace = new TraceReader<symbol>;
    trace->Open(trace_filename);
    trace->SetDemangle(demangle);
    trace->ReadKernelSymbols(elf_file);
    trace->SetRoot(root);

    BBEvent event;
    while (1) {
        BBEvent ignored;
        symbol_type *function;

        if (GetNextValidEvent(trace, &event, &ignored, &function))
            break;
        if (event.bb_num == 0)
            break;

        // Get the stack for the current thread
        CallStackType *pStack = stacks[event.pid];

        // If the stack does not exist, then allocate a new one.
        if (pStack == NULL) {
            pStack = new CallStackType(event.pid, kNumStackFrames, trace);
            stacks[event.pid] = pStack;
        }

        // Update the stack
        pStack->updateStack(&event, function);
    }

    for (int ii = 0; ii < kMaxThreads; ++ii) {
        if (stacks[ii])
            stacks[ii]->popAll(event.time);
    }

    int nsyms;
    symbol_type *syms = trace->GetSymbols(&nsyms);

    // Sort the symbols into decreasing number of calls
    qsort(syms, nsyms, sizeof(symbol_type), cmp_sym_names);

    symbol_type *psym = syms;
    for (int ii = 0; ii < nsyms; ++ii, ++psym) {
        // Ignore functions with non-zero calls
        if (psym->numCalls)
            continue;

        // Ignore some symbols
        if (strcmp(psym->name, "(end)") == 0)
            continue;
        if (strcmp(psym->name, "(unknown)") == 0)
            continue;
        if (strcmp(psym->name, ".plt") == 0)
            continue;
        const char *ksym = " ";
        if (psym->region->flags & region_type::kIsKernelRegion)
            ksym = "k";
        printf("%s %s %s\n", ksym, psym->name, psym->region->path);
#if 0
        printf("#%d %5d %s %s %s\n", ii + 1, psym->numCalls, ksym, psym->name,
               psym->region->path);
#endif
    }
    delete[] syms;
    delete trace;

    return 0;
}