Skip to content

Commit c556a3f

Browse files
committed
Finish write of trace.
1 parent 512a13a commit c556a3f

File tree

7 files changed

+67
-15
lines changed

7 files changed

+67
-15
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ the BAP-frames repository.
4444
| 0x8 | uint64_t | trace version number | |
4545
| 0x10 | uint64_t | frame_architecture | |
4646
| 0x18 | uint64_t | frame_machine, 0 for unspecified. | |
47-
| 0x20 | uint64_t | n = number of frames per TOC entry. | |
47+
| 0x20 | uint64_t | n = total number of frames in trace. | |
4848
| 0x28 | uint64_t | T = offset to TOC index. | |
4949
| 0x30 | uint64_t | sizeof(frame_0) | TOC begin |
5050
| 0x38 | meta_frame | frame_0 | |

contrib/plugins/bap-tracing/frame_buffer.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,8 @@ bool frame_buffer_is_empty(const FrameBuffer *buf) {
160160
}
161161

162162
/// @brief Dumps the file buffer as TOC entry into the file.
163-
void frame_buffer_flush_to_file(FrameBuffer *buf, WLOCKED FILE *file) {
163+
uint64_t frame_buffer_flush_to_file(FrameBuffer *buf, WLOCKED FILE *file) {
164+
uint64_t n = 0;
164165
for (size_t i = 0; i <= buf->idx && i < frames_per_toc_entry; ++i) {
165166
Frame *frame = buf->fbuf[i];
166167
size_t msg_size = frame__get_packed_size(frame);
@@ -169,9 +170,11 @@ void frame_buffer_flush_to_file(FrameBuffer *buf, WLOCKED FILE *file) {
169170
WRITE(packed_size);
170171
WRITE_BUF(packed_buffer, packed_size);
171172
frame_free(frame);
173+
n++;
172174
}
173175
memset(buf->fbuf, 0, sizeof(buf->fbuf));
174176
buf->idx = 0;
177+
return n;
175178
}
176179

177180
bool frame_buffer_new_frame_std(FrameBuffer *buf, unsigned int thread_id,

contrib/plugins/bap-tracing/frame_buffer.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ typedef struct {
2828
*/
2929
FrameBuffer *frame_buffer_new(void);
3030

31-
void frame_buffer_flush_to_file(FrameBuffer *buf, WLOCKED FILE *file);
31+
uint64_t frame_buffer_flush_to_file(FrameBuffer *buf, WLOCKED FILE *file);
3232
bool frame_buffer_is_full(const FrameBuffer *buf);
3333
bool frame_buffer_is_empty(const FrameBuffer *buf);
3434
void frame_buffer_close_frame(FrameBuffer *buf);

contrib/plugins/bap-tracing/trace_consts.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ static const uint64_t offset_magic_number = 0LL;
1111
static const uint64_t offset_trace_version = 8LL;
1212
static const uint64_t offset_target_arch = 16LL;
1313
static const uint64_t offset_target_machine = 24LL;
14-
static const uint64_t offset_frames_per_toc_entry = 32LL;
14+
static const uint64_t offset_total_num_frames = 32LL;
1515
static const uint64_t offset_toc_index_offset = 40LL;
1616
static const uint64_t offset_toc_start = 48LL;
1717
static const uint64_t offset_first_frame = 48LL;

contrib/plugins/bap-tracing/trace_meta.h

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
#ifndef BAP_TRACE_META_H
55
#define BAP_TRACE_META_H
66

7+
#include <err.h>
8+
79
/**
810
* \brief Empty macros indicate the argument, variable etc.
911
* must be locked for writing.
@@ -13,13 +15,19 @@
1315
#define WRITE(x) \
1416
do { \
1517
if (fwrite(&(x), sizeof(x), 1, file) != 1) \
16-
qemu_plugin_outs("fwrite failed"); \
18+
err(1, "fwrite failed"); \
1719
} while (0)
1820

1921
#define WRITE_BUF(x, n) \
2022
do { \
2123
if (fwrite((x), 1, (n), file) != n) \
22-
qemu_plugin_outs("fwrite failed"); \
24+
err(1, "fwrite failed"); \
25+
} while (0)
26+
27+
#define SEEK(off) \
28+
do { \
29+
if (fseek(file, (off), SEEK_SET) < 0) \
30+
err(1, "stream not seekable"); \
2331
} while (0)
2432

2533
#endif

contrib/plugins/bap-tracing/tracing.c

Lines changed: 47 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,15 @@
22
// SPDX-License-Identifier: GPL-2.0-only
33

44
#include <glib.h>
5+
#include <stdio.h>
56

67
#include "frame_arch.h"
78
#include "frame_buffer.h"
89
#include "qemu-plugin.h"
10+
#include "trace_consts.h"
911
#include "tracing.h"
1012

11-
static TraceState state;
13+
static TraceState state = {0};
1214

1315
static void add_mem_op(VCPU *vcpu, unsigned int vcpu_index, FrameBuffer *fbuf,
1416
uint64_t vaddr, qemu_plugin_mem_value *mval,
@@ -100,9 +102,13 @@ static GPtrArray *registers_init(void) {
100102
static void write_toc_entry(FrameBuffer *fbuf) {
101103
g_rw_lock_writer_lock(&state.file_lock);
102104
g_rw_lock_writer_lock(&state.toc_entries_offsets_lock);
103-
frame_buffer_flush_to_file(fbuf, state.file);
105+
g_rw_lock_writer_lock(&state.total_num_frames_lock);
106+
107+
state.total_num_frames += frame_buffer_flush_to_file(fbuf, state.file);
104108
uint64_t next_toc_entry = ftell(state.file);
105109
g_array_append_val(state.toc_entries_offsets, next_toc_entry);
110+
111+
g_rw_lock_writer_unlock(&state.total_num_frames_lock);
106112
g_rw_lock_writer_unlock(&state.toc_entries_offsets_lock);
107113
g_rw_lock_writer_unlock(&state.file_lock);
108114
}
@@ -155,9 +161,7 @@ static void vcpu_init(qemu_plugin_id_t id, unsigned int vcpu_index) {
155161

156162
VCPU *vcpu = g_malloc0(sizeof(VCPU));
157163
vcpu->registers = registers_init();
158-
if (!vcpu->registers) {
159-
g_assert(false);
160-
}
164+
g_assert(vcpu->registers);
161165
g_ptr_array_insert(state.vcpus, vcpu_index, vcpu);
162166

163167
FrameBuffer *vcpu_frame_buffer = frame_buffer_new();
@@ -191,12 +195,46 @@ static void cb_trans(qemu_plugin_id_t id, struct qemu_plugin_tb *tb) {
191195
}
192196

193197
static void plugin_exit(qemu_plugin_id_t id, void *udata) {
194-
// Dump rest of frames to file.
198+
g_rw_lock_writer_lock(&state.frame_buffer_lock);
199+
for (size_t i = 0; i < state.vcpus->len; ++i) {
200+
FrameBuffer *fbuf = g_ptr_array_index(state.frame_buffer, i);
201+
write_toc_entry(fbuf);
202+
}
203+
g_rw_lock_writer_unlock(&state.frame_buffer_lock);
204+
205+
g_rw_lock_writer_lock(&state.file_lock);
206+
g_rw_lock_reader_lock(&state.toc_entries_offsets_lock);
207+
g_rw_lock_reader_lock(&state.total_num_frames_lock);
208+
209+
FILE *file = state.file;
210+
211+
// Update fields in the header
212+
uint64_t toc_index_offset = ftell(file);
213+
SEEK(offset_toc_index_offset);
214+
WRITE(toc_index_offset);
215+
SEEK(offset_total_num_frames);
216+
WRITE(state.total_num_frames);
217+
218+
// Write the TOC index
219+
SEEK(toc_index_offset);
220+
uint64_t m = state.toc_entries_offsets->len;
221+
WRITE(m);
222+
223+
for (size_t i = 0; i < m; ++i) {
224+
uint64_t toc_entry_off =
225+
g_array_index(state.toc_entries_offsets, uint64_t, i);
226+
WRITE(toc_entry_off);
227+
}
228+
fclose(file);
229+
230+
g_rw_lock_reader_unlock(&state.total_num_frames_lock);
231+
g_rw_lock_reader_unlock(&state.toc_entries_offsets_lock);
232+
g_rw_lock_writer_unlock(&state.file_lock);
195233
}
196234

197235
static bool get_frame_arch_mach(const char *target_name, uint64_t *arch,
198236
uint64_t *mach) {
199-
*arch = 0;
237+
*mach = 0;
200238
*arch = frame_arch_last;
201239
const char *aname = arch_map[0].name;
202240
for (size_t i = 0; arch_map[i].name; ++i) {
@@ -216,13 +254,13 @@ static bool write_header(FILE *file, const char *target_name) {
216254
qemu_plugin_outs("Failed to get arch/mach.\n");
217255
return false;
218256
}
219-
uint64_t num_toc_entries = 0ULL;
257+
uint64_t total_num_frames = 0ULL;
220258
uint64_t toc_index_offset = 0ULL;
221259
WRITE(magic_number);
222260
WRITE(trace_version);
223261
WRITE(frame_arch);
224262
WRITE(frame_mach);
225-
WRITE(num_toc_entries); // Gets updated later
263+
WRITE(total_num_frames); // Gets updated later
226264
WRITE(toc_index_offset); // Gets updated later
227265
return true;
228266
}

contrib/plugins/bap-tracing/tracing.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,9 @@ typedef struct {
137137
GRWLock toc_entries_offsets_lock;
138138
GArray /*<uint64_t>*/ *toc_entries_offsets;
139139

140+
GRWLock total_num_frames_lock;
141+
uint64_t total_num_frames;
142+
140143
GRWLock file_lock;
141144
FILE *file;
142145
} TraceState;

0 commit comments

Comments
 (0)