int pandalog_close_write(void) { // finish current chunk then write directory info and header write_current_chunk(); // Not a mistake! // this will add one more dir entry for last instr and file pos add_dir_entry(thePandalog->chunk_num); write_dir(); return 0; }
void pandalog_write_entry(Panda__LogEntry *entry) { // fill in required fields. if (panda_in_main_loop) { entry->pc = panda_current_pc(first_cpu); entry->instr = rr_get_guest_instr_count (); } else { entry->pc = -1; entry->instr = -1; } size_t n = panda__log_entry__get_packed_size(entry); // possibly compress and write current chunk and move on to next chunk // but dont do so if it would spread log entries for same instruction between chunks // invariant: all log entries for an instruction belong in a single chunk if ((instr_last_entry != -1) // first entry written && (instr_last_entry != entry->instr) && (thePandalog->chunk.buf_p + n >= thePandalog->chunk.buf + thePandalog->chunk.size)) { // entry won't fit in current chunk // and new entry is a different instr from last entry written write_current_chunk(); } // sanity check. If this fails, that means a large number of pandalog entries // for same instr went off the end of a chunk, which was already allocated bigger than needed. // possible. but I'd rather assert its not and understand why before adding auto realloc here. // TRL 2016-05-10: Ok here's a time when this legit happens. When you pandalog in uninit_plugin // this can be a lot of entries for the same instr (the very last one in the trace). // So no more assert. if (thePandalog->chunk.buf_p + sizeof(uint32_t) + n >= thePandalog->chunk.buf + ((int)(floor(thePandalog->chunk.size)))) { uint32_t offset = thePandalog->chunk.buf_p - thePandalog->chunk.buf; uint32_t new_size = offset * 2; printf ("reallocing chunk.buf to %d bytes\n", new_size); thePandalog->chunk.buf = (unsigned char *) realloc(thePandalog->chunk.buf, new_size); thePandalog->chunk.buf_p = thePandalog->chunk.buf + offset; assert (thePandalog->chunk.buf != NULL); } // now write the entry itself to the buffer. size then entry itself *((uint32_t *) thePandalog->chunk.buf_p) = n; thePandalog->chunk.buf_p += sizeof(uint32_t); // and then the entry itself (packed) panda__log_entry__pack(entry, thePandalog->chunk.buf_p); thePandalog->chunk.buf_p += n; // remember instr for last entry instr_last_entry = entry->instr; thePandalog->chunk.ind_entry ++; }
void pandalog_write_entry(Panda__LogEntry *entry) { // fill in required fields. if (panda_in_main_loop) { entry->pc = panda_current_pc(cpu_single_env); entry->instr = rr_get_guest_instr_count (); } else { entry->pc = -1; entry->instr = -1; } size_t n = panda__log_entry__get_packed_size(entry); // possibly compress and write current chunk and move on to next chunk // but dont do so if it would spread log entries for same instruction between chunks // invariant: all log entries for an instruction belong in a single chunk if ((instr_last_entry != -1) // first entry written && (instr_last_entry != entry->instr) && (thePandalog->chunk.buf_p + n >= thePandalog->chunk.buf + thePandalog->chunk.size)) { // entry won't fit in current chunk // and new entry is a different instr from last entry written write_current_chunk(); } // sanity check. If this fails, that means a large number of pandalog entries // for same instr went off the end of a chunk, which was already allocated bigger than needed. // possible. but I'd rather assert its not and understand why before adding auto realloc here. assert (thePandalog->chunk.buf_p + sizeof(uint32_t) + n < thePandalog->chunk.buf + ((int)(floor(thePandalog->chunk.size * SLACK_MULT)))); // now write the entry itself to the buffer. size then entry itself *((uint32_t *) thePandalog->chunk.buf_p) = n; thePandalog->chunk.buf_p += sizeof(uint32_t); // and then the entry itself (packed) panda__log_entry__pack(entry, thePandalog->chunk.buf_p); thePandalog->chunk.buf_p += n; // remember instr for last entry instr_last_entry = entry->instr; thePandalog->chunk.ind_entry ++; }