@@ -77,7 +77,8 @@ static void add_pre_reg_state(VCPU *vcpu, unsigned int vcpu_index,
7777 & g_array_index (current_regs , qemu_plugin_reg_descriptor , i );
7878 size_t s = qemu_plugin_read_register (reg -> handle , rdata );
7979 Register * prev_reg = g_ptr_array_index (vcpu -> registers , i );
80- g_assert (!strcmp (prev_reg -> name , reg -> name ) && prev_reg -> handle == reg -> handle );
80+ g_assert (!strcmp (prev_reg -> name , reg -> name ) &&
81+ prev_reg -> handle == reg -> handle );
8182 memcpy (prev_reg -> content -> data , rdata -> data , prev_reg -> content -> len );
8283 frame_buffer_append_reg_info (fbuf , reg -> name , rdata , s , OperandRead );
8384 // Flush byte array
@@ -103,13 +104,12 @@ static GPtrArray *registers_init(void) {
103104 return registers -> len ? g_steal_pointer (& registers ) : NULL ;
104105}
105106
106- static void write_toc_entry (FrameBuffer * fbuf , bool add_padding ) {
107+ static void flush_and_write_toc_entry (FrameBuffer * fbuf ) {
107108 g_rw_lock_writer_lock (& state .file_lock );
108109 g_rw_lock_writer_lock (& state .toc_entries_offsets_lock );
109110 g_rw_lock_writer_lock (& state .total_num_frames_lock );
110111
111- state .total_num_frames +=
112- frame_buffer_flush_to_file (fbuf , state .file , add_padding );
112+ state .total_num_frames += frame_buffer_flush_to_file (fbuf , state .file );
113113 uint64_t next_toc_entry = ftell (state .file );
114114 g_array_append_val (state .toc_entries_offsets , next_toc_entry );
115115
@@ -118,6 +118,54 @@ static void write_toc_entry(FrameBuffer *fbuf, bool add_padding) {
118118 g_rw_lock_writer_unlock (& state .file_lock );
119119}
120120
121+ static void flush_all_frame_bufs (void ) {
122+ g_rw_lock_writer_lock (& state .file_lock );
123+ g_rw_lock_writer_lock (& state .toc_entries_offsets_lock );
124+ g_rw_lock_writer_lock (& state .total_num_frames_lock );
125+ g_rw_lock_writer_lock (& state .frame_buffer_lock );
126+
127+ FILE * file = state .file ;
128+
129+ // Dump the rest of the frames but be mindeful about the
130+ // maximum number of frames per TOC entry.
131+
132+ size_t total_to_write = 0 ;
133+ for (size_t i = 0 ; i < state .vcpus -> len ; ++ i ) {
134+ // Add post operands to last instructions.
135+ FrameBuffer * fbuf = g_ptr_array_index (state .frame_buffer , i );
136+ VCPU * vcpu = g_ptr_array_index (state .vcpus , i );
137+ g_assert (vcpu );
138+ GArray * current_regs = qemu_plugin_get_registers ();
139+ g_assert (current_regs -> len == vcpu -> registers -> len );
140+ add_post_reg_state (vcpu , i , current_regs , fbuf );
141+ frame_buffer_close_frame (fbuf );
142+
143+ total_to_write += fbuf -> idx ;
144+ }
145+
146+ size_t entry_count = 0 ;
147+ for (size_t i = 0 ; i < state .vcpus -> len && total_to_write > 0 ; ++ i ) {
148+ if (entry_count == frames_per_toc_entry ) {
149+ entry_count = 0 ;
150+ uint64_t next_toc_entry = ftell (state .file );
151+ g_array_append_val (state .toc_entries_offsets , next_toc_entry );
152+ }
153+
154+ FrameBuffer * fbuf = g_ptr_array_index (state .frame_buffer , i );
155+ for (size_t k = 0 ; k < fbuf -> idx ; ++ k ) {
156+ frame_buffer_write_frame_to_file (fbuf , file , k );
157+ entry_count ++ ;
158+ state .total_num_frames ++ ;
159+ total_to_write -- ;
160+ }
161+ }
162+
163+ g_rw_lock_writer_unlock (& state .frame_buffer_lock );
164+ g_rw_lock_writer_unlock (& state .total_num_frames_lock );
165+ g_rw_lock_writer_unlock (& state .toc_entries_offsets_lock );
166+ g_rw_lock_writer_unlock (& state .file_lock );
167+ }
168+
121169static void log_insn_reg_access (unsigned int vcpu_index , void * udata ) {
122170 g_rw_lock_reader_lock (& state .vcpus_array_lock );
123171 g_rw_lock_writer_lock (& state .frame_buffer_lock );
@@ -134,7 +182,7 @@ static void log_insn_reg_access(unsigned int vcpu_index, void *udata) {
134182 }
135183
136184 if (frame_buffer_is_full (fbuf )) {
137- write_toc_entry (fbuf , false );
185+ flush_and_write_toc_entry (fbuf );
138186 }
139187
140188 // Open new one.
@@ -225,13 +273,7 @@ static void cb_trans(qemu_plugin_id_t id, struct qemu_plugin_tb *tb) {
225273}
226274
227275static void plugin_exit (qemu_plugin_id_t id , void * udata ) {
228- g_rw_lock_writer_lock (& state .frame_buffer_lock );
229- // Dump the rest of the frames.
230- for (size_t i = 0 ; i < state .vcpus -> len ; ++ i ) {
231- FrameBuffer * fbuf = g_ptr_array_index (state .frame_buffer , i );
232- write_toc_entry (fbuf , true);
233- }
234- g_rw_lock_writer_unlock (& state .frame_buffer_lock );
276+ flush_all_frame_bufs ();
235277
236278 g_rw_lock_writer_lock (& state .file_lock );
237279 g_rw_lock_reader_lock (& state .toc_entries_offsets_lock );
0 commit comments