1use crate::streaming::event::*;
2use crate::streaming::{EntryTable, Error, HeaderInfo};
3use crate::time::{Frequency, Ticks};
4use crate::types::{
5 format_symbol_string, Endianness, FormatString, FormattedString, Heap, ObjectClass,
6 ObjectHandle, ObjectName, Priority, Protocol, SymbolString, TimerCounter, TrimmedString,
7 UserEventChannel,
8};
9use byteordered::ByteOrdered;
10use std::io::{self, Read};
11use tracing::error;
12
13#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)]
14pub struct EventParser {
15 endianness: byteordered::Endianness,
17
18 heap: Heap,
20
21 custom_printf_event_id: Option<EventId>,
23
24 buf: Vec<u8>,
26
27 arg_buf: Vec<u8>,
29}
30
31impl EventParser {
32 pub fn new(endianness: Endianness, heap: Heap) -> Self {
33 Self {
34 endianness: byteordered::Endianness::from(endianness),
35 heap,
36 custom_printf_event_id: None,
37 buf: Vec::with_capacity(256),
38 arg_buf: Vec::with_capacity(256),
39 }
40 }
41
42 pub fn set_custom_printf_event_id(&mut self, custom_printf_event_id: EventId) {
43 self.custom_printf_event_id = Some(custom_printf_event_id);
44 }
45
46 pub fn system_heap(&self) -> &Heap {
47 &self.heap
48 }
49
50 pub fn next_event<R: Read>(
51 &mut self,
52 mut r: &mut R,
53 entry_table: &mut EntryTable,
54 ) -> Result<Option<(EventCode, Event)>, Error> {
55 let first_word = {
56 let mut r = ByteOrdered::le(&mut r);
57 let word = match r.read_u32() {
58 Ok(w) => w,
59 Err(e) if e.kind() == io::ErrorKind::UnexpectedEof => return Ok(None),
60 Err(e) => return Err(e.into()),
61 };
62 match word {
63 HeaderInfo::PSF_LITTLE_ENDIAN => {
64 return Err(Error::TraceRestarted(Endianness::Little))
65 }
66 HeaderInfo::PSF_BIG_ENDIAN => return Err(Error::TraceRestarted(Endianness::Big)),
67 _ => word.to_le_bytes(),
68 }
69 };
70
71 let mut first_word_reader = ByteOrdered::new(first_word.as_slice(), self.endianness);
72 let mut r = ByteOrdered::new(r, self.endianness);
73
74 let event_code = match first_word_reader.read_u16() {
75 Ok(ec) => EventCode(ec),
76 Err(e) if e.kind() == io::ErrorKind::UnexpectedEof => return Ok(None),
77 Err(e) => return Err(e.into()),
78 };
79
80 let event_type = event_code.event_type();
81 let event_id = event_code.event_id();
82 let event_count = EventCount(first_word_reader.read_u16()?);
83 let timestamp = Timestamp(r.read_u32()?.into());
84 let num_params = event_code.parameter_count();
85
86 if let Some(expected_parameter_count) = event_type.expected_parameter_count() {
87 if usize::from(num_params) != expected_parameter_count {
88 return Err(Error::InvalidEventParameterCount(
89 event_code.event_id(),
90 expected_parameter_count,
91 num_params,
92 ));
93 }
94 }
95
96 Ok(match event_type {
97 EventType::TraceStart => {
98 let handle = object_handle(&mut r, event_id)?;
99 let sym = entry_table
100 .symbol(handle)
101 .ok_or(Error::ObjectLookup(handle))?;
102 let event = TraceStartEvent {
103 event_count,
104 timestamp,
105 current_task_handle: handle,
106 current_task: sym.clone().into(),
107 };
108 Some((event_code, Event::TraceStart(event)))
109 }
110
111 EventType::TsConfig => {
112 let uses_custom_timer = match num_params.0 {
113 4 => false,
114 5 => true,
116 _ => {
117 return Err(Error::InvalidEventParameterCount(
118 event_code.event_id(),
119 4, num_params,
121 ));
122 }
123 };
124 let frequency = Frequency(r.read_u32()?);
125 let tick_rate_hz = r.read_u32()?;
126 let hwtc_type = r.read_u32()?;
127 let isr_chaining_threshold = r.read_u32()?;
128 let htc_period = if uses_custom_timer {
129 r.read_u32()?.into()
130 } else {
131 None
132 };
133 let event = TsConfigEvent {
134 event_count,
135 timestamp,
136 frequency,
137 tick_rate_hz,
138 hwtc_type: TimerCounter::from_hwtc_type(hwtc_type)
139 .ok_or(Error::InvalidTimerCounter(hwtc_type))?,
140 isr_chaining_threshold,
141 htc_period,
142 };
143 Some((event_code, Event::TsConfig(event)))
144 }
145
146 EventType::ObjectName => {
147 if num_params.0 < 1 {
149 return Err(Error::InvalidEventParameterCount(
150 event_code.event_id(),
151 1,
152 num_params,
153 ));
154 }
155 let handle = object_handle(&mut r, event_id)?;
156 let symbol: SymbolString = self
157 .read_string(&mut r, (usize::from(num_params) - 1) * 4)?
158 .into();
159 entry_table.entry(handle).set_symbol(symbol.clone());
160 let event = ObjectNameEvent {
161 event_count,
162 timestamp,
163 handle,
164 name: symbol,
165 };
166 Some((event_code, Event::ObjectName(event)))
167 }
168
169 EventType::TaskPriority
170 | EventType::TaskPriorityInherit
171 | EventType::TaskPriorityDisinherit => {
172 let handle = object_handle(&mut r, event_id)?;
173 let priority = Priority(r.read_u32()?);
174 let entry = entry_table.entry(handle);
175 entry.states.set_priority(priority);
176 let sym = entry.symbol.as_ref().ok_or(Error::ObjectLookup(handle))?;
177 let event = TaskEvent {
178 event_count,
179 timestamp,
180 handle,
181 name: sym.clone().into(),
182 priority,
183 };
184 Some((
185 event_code,
186 match event_type {
187 EventType::TaskPriority => Event::TaskPriority(event),
188 EventType::TaskPriorityInherit => Event::TaskPriorityInherit(event),
189 _ => Event::TaskPriorityDisinherit(event),
190 },
191 ))
192 }
193
194 EventType::DefineIsr => {
195 if num_params.0 < 1 {
197 return Err(Error::InvalidEventParameterCount(
198 event_code.event_id(),
199 1,
200 num_params,
201 ));
202 }
203 let handle = object_handle(&mut r, event_id)?;
204 let priority = Priority(r.read_u32()?);
205 let symbol: SymbolString = self
206 .read_string(&mut r, (usize::from(num_params) - 2) * 4)?
207 .into();
208 let entry = entry_table.entry(handle);
209 entry.states.set_priority(priority);
210 entry.set_symbol(symbol.clone());
211 entry.set_class(ObjectClass::Isr);
212 let event = IsrEvent {
213 event_count,
214 timestamp,
215 handle,
216 name: symbol.into(),
217 priority,
218 };
219 Some((event_code, Event::IsrDefine(event)))
220 }
221
222 EventType::TaskCreate => {
223 let handle = object_handle(&mut r, event_id)?;
224 let priority = Priority(r.read_u32()?);
225 let entry = entry_table.entry(handle);
226 entry.states.set_priority(priority);
227 entry.set_class(ObjectClass::Task);
228 let sym = entry.symbol.as_ref().ok_or(Error::ObjectLookup(handle))?;
229 let event = TaskEvent {
230 event_count,
231 timestamp,
232 handle,
233 name: sym.clone().into(),
234 priority,
235 };
236 Some((event_code, Event::TaskCreate(event)))
237 }
238
239 EventType::TaskReady => {
240 let handle = object_handle(&mut r, event_id)?;
241 let entry = entry_table.entry(handle);
242 let sym = entry.symbol.as_ref().ok_or(Error::ObjectLookup(handle))?;
243 let event = TaskEvent {
244 event_count,
245 timestamp,
246 handle,
247 name: sym.clone().into(),
248 priority: entry.states.priority(),
249 };
250 Some((event_code, Event::TaskReady(event)))
251 }
252
253 EventType::TaskSwitchIsrBegin => {
254 let handle = object_handle(&mut r, event_id)?;
255 let entry = entry_table.entry(handle);
256 let sym = entry.symbol.as_ref().ok_or(Error::ObjectLookup(handle))?;
257 let event = IsrEvent {
258 event_count,
259 timestamp,
260 handle,
261 name: sym.clone().into(),
262 priority: entry.states.priority(),
263 };
264 Some((event_code, Event::IsrBegin(event)))
265 }
266
267 EventType::TaskSwitchIsrResume => {
268 let handle = object_handle(&mut r, event_id)?;
269 let entry = entry_table.entry(handle);
270 let sym = entry.symbol.as_ref().ok_or(Error::ObjectLookup(handle))?;
271 let event = IsrEvent {
272 event_count,
273 timestamp,
274 handle,
275 name: sym.clone().into(),
276 priority: entry.states.priority(),
277 };
278 Some((event_code, Event::IsrResume(event)))
279 }
280
281 EventType::TaskSwitchTaskResume => {
282 let handle = object_handle(&mut r, event_id)?;
283 let entry = entry_table.entry(handle);
284 let sym = entry.symbol.as_ref().ok_or(Error::ObjectLookup(handle))?;
285 let event = TaskEvent {
286 event_count,
287 timestamp,
288 handle,
289 name: sym.clone().into(),
290 priority: entry.states.priority(),
291 };
292 Some((event_code, Event::TaskResume(event)))
293 }
294
295 EventType::TaskActivate => {
296 if (num_params.0 != 1) && (num_params.0 != 2) {
297 return Err(Error::InvalidEventParameterCount(
298 event_code.event_id(),
299 1,
300 num_params,
301 ));
302 }
303 let handle = object_handle(&mut r, event_id)?;
304 let entry = entry_table.entry(handle);
305
306 if num_params.0 == 2 {
307 let priority = Priority(r.read_u32()?);
308 entry.states.set_priority(priority);
309 }
310
311 let sym = entry.symbol.as_ref().ok_or(Error::ObjectLookup(handle))?;
312 let event = TaskEvent {
313 event_count,
314 timestamp,
315 handle,
316 name: sym.clone().into(),
317 priority: entry.states.priority(),
318 };
319 Some((event_code, Event::TaskActivate(event)))
320 }
321
322 EventType::TaskNotify | EventType::TaskNotifyFromIsr => {
323 let handle: ObjectHandle = object_handle(&mut r, event_id)?;
324 let entry = entry_table.entry(handle);
325 let event = TaskNotifyEvent {
326 event_count,
327 timestamp,
328 handle,
329 task_name: entry.symbol.clone().map(ObjectName::from),
330 ticks_to_wait: None,
331 };
332 Some((
333 event_code,
334 match event_type {
335 EventType::TaskNotify => Event::TaskNotify(event),
336 _ => Event::TaskNotifyFromIsr(event),
337 },
338 ))
339 }
340
341 EventType::TaskNotifyWait | EventType::TaskNotifyWaitBlock => {
342 let handle: ObjectHandle = object_handle(&mut r, event_id)?;
343 let ticks_to_wait = Some(Ticks(r.read_u32()?));
344 let entry = entry_table.entry(handle);
345 let event = TaskNotifyEvent {
346 event_count,
347 timestamp,
348 handle,
349 task_name: entry.symbol.clone().map(ObjectName::from),
350 ticks_to_wait,
351 };
352 Some((
353 event_code,
354 match event_type {
355 EventType::TaskNotifyWait => Event::TaskNotifyWait(event),
356 _ => Event::TaskNotifyWaitBlock(event),
357 },
358 ))
359 }
360
361 EventType::MemoryAlloc | EventType::MemoryFree => {
362 let address = r.read_u32()?;
363 let size = r.read_u32()?;
364 if matches!(event_type, EventType::MemoryAlloc) {
365 self.heap.handle_alloc(size);
366 } else {
367 self.heap.handle_free(size);
368 }
369 let event = MemoryEvent {
370 event_count,
371 timestamp,
372 address,
373 size,
374 heap: self.heap,
375 };
376 Some((
377 event_code,
378 if matches!(event_type, EventType::MemoryAlloc) {
379 Event::MemoryAlloc(event)
380 } else {
381 Event::MemoryFree(event)
382 },
383 ))
384 }
385
386 EventType::QueueCreate => {
387 let handle = object_handle(&mut r, event_id)?;
388 let queue_length = r.read_u32()?;
389 let entry = entry_table.entry(handle);
390 entry.set_class(ObjectClass::Queue);
391 let event = QueueCreateEvent {
392 event_count,
393 timestamp,
394 handle,
395 name: entry.symbol.clone().map(ObjectName::from),
396 queue_length,
397 };
398 Some((event_code, Event::QueueCreate(event)))
399 }
400
401 EventType::QueueSend
402 | EventType::QueueSendBlock
403 | EventType::QueueSendFromIsr
404 | EventType::QueueReceiveFromIsr
405 | EventType::QueueSendFront
406 | EventType::QueueSendFrontBlock
407 | EventType::QueueSendFrontFromIsr => {
408 let handle: ObjectHandle = object_handle(&mut r, event_id)?;
409 let messages_waiting = r.read_u32()?;
410 let event = QueueEvent {
411 event_count,
412 timestamp,
413 handle,
414 name: entry_table.symbol(handle).cloned().map(ObjectName::from),
415 ticks_to_wait: None,
416 messages_waiting,
417 };
418 Some((
419 event_code,
420 match event_type {
421 EventType::QueueSend => Event::QueueSend(event),
422 EventType::QueueSendBlock => Event::QueueSendBlock(event),
423 EventType::QueueSendFromIsr => Event::QueueSendFromIsr(event),
424 EventType::QueueReceiveFromIsr => Event::QueueReceiveFromIsr(event),
425 EventType::QueueSendFront => Event::QueueSendFront(event),
426 EventType::QueueSendFrontBlock => Event::QueueSendFrontBlock(event),
427 _ => Event::QueueSendFrontFromIsr(event),
428 },
429 ))
430 }
431
432 EventType::QueueReceive
433 | EventType::QueueReceiveBlock
434 | EventType::QueuePeek
435 | EventType::QueuePeekBlock => {
436 let handle: ObjectHandle = object_handle(&mut r, event_id)?;
437 let ticks_to_wait = Some(Ticks(r.read_u32()?));
438 let messages_waiting = r.read_u32()?;
439 let event = QueueEvent {
440 event_count,
441 timestamp,
442 handle,
443 name: entry_table.symbol(handle).cloned().map(ObjectName::from),
444 ticks_to_wait,
445 messages_waiting,
446 };
447 Some((
448 event_code,
449 match event_type {
450 EventType::QueueReceive => Event::QueueReceive(event),
451 EventType::QueueReceiveBlock => Event::QueueReceiveBlock(event),
452 EventType::QueuePeek => Event::QueuePeek(event),
453 _ => Event::QueuePeekBlock(event),
454 },
455 ))
456 }
457
458 EventType::MutexCreate => {
459 let handle: ObjectHandle = object_handle(&mut r, event_id)?;
460 let _unused = r.read_u32()?;
461 let entry = entry_table.entry(handle);
462 entry.set_class(ObjectClass::Mutex);
463 let event = MutexCreateEvent {
464 event_count,
465 timestamp,
466 handle,
467 name: entry.symbol.clone().map(ObjectName::from),
468 };
469 Some((event_code, Event::MutexCreate(event)))
470 }
471
472 EventType::MutexGive | EventType::MutexGiveBlock | EventType::MutexGiveRecursive => {
473 let handle: ObjectHandle = object_handle(&mut r, event_id)?;
474 let entry = entry_table.entry(handle);
475 entry.set_class(ObjectClass::Mutex);
476 let event = MutexEvent {
477 event_count,
478 timestamp,
479 handle,
480 name: entry.symbol.clone().map(ObjectName::from),
481 ticks_to_wait: None,
482 };
483 Some((
484 event_code,
485 match event_type {
486 EventType::MutexGive => Event::MutexGive(event),
487 EventType::MutexGiveBlock => Event::MutexGiveBlock(event),
488 _ => Event::MutexGiveRecursive(event),
489 },
490 ))
491 }
492
493 EventType::MutexTake
494 | EventType::MutexTakeBlock
495 | EventType::MutexTakeRecursive
496 | EventType::MutexTakeRecursiveBlock => {
497 let handle: ObjectHandle = object_handle(&mut r, event_id)?;
498 let ticks_to_wait = Some(Ticks(r.read_u32()?));
499 let entry = entry_table.entry(handle);
500 entry.set_class(ObjectClass::Mutex);
501 let event = MutexEvent {
502 event_count,
503 timestamp,
504 handle,
505 name: entry.symbol.clone().map(ObjectName::from),
506 ticks_to_wait,
507 };
508 Some((
509 event_code,
510 match event_type {
511 EventType::MutexTake => Event::MutexTake(event),
512 EventType::MutexTakeBlock => Event::MutexTakeBlock(event),
513 EventType::MutexTakeRecursive => Event::MutexTakeRecursive(event),
514 _ => Event::MutexTakeRecursiveBlock(event),
515 },
516 ))
517 }
518
519 EventType::SemaphoreBinaryCreate => {
520 let handle: ObjectHandle = object_handle(&mut r, event_id)?;
521 let _unused = r.read_u32()?;
522 let entry = entry_table.entry(handle);
523 entry.set_class(ObjectClass::Semaphore);
524 let event = SemaphoreCreateEvent {
525 event_count,
526 timestamp,
527 handle,
528 name: entry.symbol.clone().map(ObjectName::from),
529 count: None,
530 };
531 Some((event_code, Event::SemaphoreBinaryCreate(event)))
532 }
533
534 EventType::SemaphoreCountingCreate => {
535 let handle = object_handle(&mut r, event_id)?;
536 let count = Some(r.read_u32()?);
537 let entry = entry_table.entry(handle);
538 entry.set_class(ObjectClass::Semaphore);
539 let event = SemaphoreCreateEvent {
540 event_count,
541 timestamp,
542 handle,
543 name: entry.symbol.clone().map(ObjectName::from),
544 count,
545 };
546 Some((event_code, Event::SemaphoreCountingCreate(event)))
547 }
548
549 EventType::SemaphoreGive
550 | EventType::SemaphoreGiveBlock
551 | EventType::SemaphoreGiveFromIsr
552 | EventType::SemaphoreTakeFromIsr => {
553 let handle: ObjectHandle = object_handle(&mut r, event_id)?;
554 let count = r.read_u32()?;
555 let event = SemaphoreEvent {
556 event_count,
557 timestamp,
558 handle,
559 name: entry_table.symbol(handle).cloned().map(ObjectName::from),
560 ticks_to_wait: None,
561 count,
562 };
563 Some((
564 event_code,
565 match event_type {
566 EventType::SemaphoreGive => Event::SemaphoreGive(event),
567 EventType::SemaphoreGiveBlock => Event::SemaphoreGiveBlock(event),
568 EventType::SemaphoreGiveFromIsr => Event::SemaphoreGiveFromIsr(event),
569 _ => Event::SemaphoreTakeFromIsr(event),
570 },
571 ))
572 }
573
574 EventType::SemaphoreTake
575 | EventType::SemaphoreTakeBlock
576 | EventType::SemaphorePeek
577 | EventType::SemaphorePeekBlock => {
578 let handle: ObjectHandle = object_handle(&mut r, event_id)?;
579 let ticks_to_wait = Some(Ticks(r.read_u32()?));
580 let count = r.read_u32()?;
581 let event = SemaphoreEvent {
582 event_count,
583 timestamp,
584 handle,
585 name: entry_table.symbol(handle).cloned().map(ObjectName::from),
586 ticks_to_wait,
587 count,
588 };
589 Some((
590 event_code,
591 match event_type {
592 EventType::SemaphoreTake => Event::SemaphoreTake(event),
593 EventType::SemaphoreTakeBlock => Event::SemaphoreTakeBlock(event),
594 EventType::SemaphorePeek => Event::SemaphorePeek(event),
595 _ => Event::SemaphorePeekBlock(event),
596 },
597 ))
598 }
599
600 EventType::EventGroupCreate => {
601 let handle: ObjectHandle = object_handle(&mut r, event_id)?;
602 let event_bits = r.read_u32()?;
603 let entry = entry_table.entry(handle);
604 entry.set_class(ObjectClass::EventGroup);
605 let event = EventGroupCreateEvent {
606 event_count,
607 timestamp,
608 handle,
609 name: entry.symbol.clone().map(ObjectName::from),
610 event_bits,
611 };
612 Some((event_code, Event::EventGroupCreate(event)))
613 }
614
615 EventType::EventGroupSync
616 | EventType::EventGroupWaitBits
617 | EventType::EventGroupClearBits
618 | EventType::EventGroupClearBitsFromIsr
619 | EventType::EventGroupSetBits
620 | EventType::EventGroupSetBitsFromIsr
621 | EventType::EventGroupSyncBlock
622 | EventType::EventGroupWaitBitsBlock => {
623 let handle = object_handle(&mut r, event_id)?;
624 let bits = r.read_u32()?;
625 let event = EventGroupEvent {
626 event_count,
627 timestamp,
628 handle,
629 name: entry_table.symbol(handle).cloned().map(ObjectName::from),
630 bits,
631 };
632 Some((
633 event_code,
634 match event_type {
635 EventType::EventGroupSync => Event::EventGroupSync(event),
636 EventType::EventGroupWaitBits => Event::EventGroupWaitBits(event),
637 EventType::EventGroupClearBits => Event::EventGroupClearBits(event),
638 EventType::EventGroupClearBitsFromIsr => Event::EventGroupClearBitsFromIsr(event),
639 EventType::EventGroupSetBits => Event::EventGroupSetBits(event),
640 EventType::EventGroupSetBitsFromIsr => Event::EventGroupSetBitsFromIsr(event),
641 EventType::EventGroupSyncBlock => Event::EventGroupSyncBlock(event),
642 _ => Event::EventGroupWaitBitsBlock(event),
643 },
644 ))
645 }
646
647 EventType::MessageBufferCreate => {
648 let handle: ObjectHandle = object_handle(&mut r, event_id)?;
649 let buffer_size = r.read_u32()?;
650 let entry = entry_table.entry(handle);
651 entry.set_class(ObjectClass::MessageBuffer);
652 let event = MessageBufferCreateEvent {
653 event_count,
654 timestamp,
655 handle,
656 name: entry.symbol.clone().map(ObjectName::from),
657 buffer_size,
658 };
659 Some((event_code, Event::MessageBufferCreate(event)))
660 }
661
662 EventType::MessageBufferSend
663 | EventType::MessageBufferReceive
664 | EventType::MessageBufferSendFromIsr
665 | EventType::MessageBufferReceiveFromIsr
666 | EventType::MessageBufferReset => {
667 let handle = object_handle(&mut r, event_id)?;
668 let bytes_in_buffer = r.read_u32()?;
669 let event = MessageBufferEvent {
670 event_count,
671 timestamp,
672 handle,
673 name: entry_table.symbol(handle).cloned().map(ObjectName::from),
674 bytes_in_buffer,
675 };
676 Some((
677 event_code,
678 match event_type {
679 EventType::MessageBufferSend => Event::MessageBufferSend(event),
680 EventType::MessageBufferReceive => Event::MessageBufferReceive(event),
681 EventType::MessageBufferSendFromIsr => Event::MessageBufferSendFromIsr(event),
682 EventType::MessageBufferReceiveFromIsr => Event::MessageBufferReceiveFromIsr(event),
683 _ => Event::MessageBufferReset(event),
684 },
685 ))
686 }
687
688 EventType::MessageBufferSendBlock | EventType::MessageBufferReceiveBlock => {
689 let handle = object_handle(&mut r, event_id)?;
690 let event = MessageBufferBlockEvent {
691 event_count,
692 timestamp,
693 handle,
694 name: entry_table.symbol(handle).cloned().map(ObjectName::from),
695 };
696 Some((
697 event_code,
698 match event_type {
699 EventType::MessageBufferSendBlock => Event::MessageBufferSendBlock(event),
700 _ => Event::MessageBufferReceiveBlock(event),
701 },
702 ))
703 }
704
705 EventType::StateMachineCreate => {
706 let handle = object_handle(&mut r, event_id)?;
707 let _unused = r.read_u32()?;
708 let entry = entry_table.entry(handle);
709 entry.set_class(ObjectClass::StateMachine);
710 let sym = entry.symbol.as_ref().ok_or(Error::ObjectLookup(handle))?;
711 let event = StateMachineCreateEvent {
712 event_count,
713 timestamp,
714 handle,
715 name: sym.clone().into(),
716 };
717 Some((event_code, Event::StateMachineCreate(event)))
718 }
719
720 EventType::StateMachineStateCreate => {
721 let state_handle = object_handle(&mut r, event_id)?;
722 let state_machine_handle = object_handle(&mut r, event_id)?;
723 let entry = entry_table.entry(state_handle);
724 entry.set_class(ObjectClass::StateMachine);
725 let state_machine_sym = entry_table
726 .entry(state_machine_handle)
727 .symbol
728 .as_ref()
729 .map(|s| ObjectName::from(s.clone()))
730 .ok_or(Error::ObjectLookup(state_machine_handle))?;
731 let state_sym = entry_table
732 .entry(state_handle)
733 .symbol
734 .as_ref()
735 .map(|s| ObjectName::from(s.clone()))
736 .ok_or(Error::ObjectLookup(state_handle))?;
737 let event = StateMachineStateEvent {
738 event_count,
739 timestamp,
740 handle: state_machine_handle,
741 name: state_machine_sym,
742 state_handle,
743 state: state_sym,
744 };
745 Some((event_code, Event::StateMachineStateCreate(event)))
746 }
747
748 EventType::StateMachineStateChange => {
749 let state_machine_handle = object_handle(&mut r, event_id)?;
750 let state_handle = object_handle(&mut r, event_id)?;
751 let state_machine_sym = entry_table
752 .entry(state_machine_handle)
753 .symbol
754 .as_ref()
755 .map(|s| ObjectName::from(s.clone()))
756 .ok_or(Error::ObjectLookup(state_machine_handle))?;
757 let state_sym = entry_table
758 .entry(state_handle)
759 .symbol
760 .as_ref()
761 .map(|s| ObjectName::from(s.clone()))
762 .ok_or(Error::ObjectLookup(state_handle))?;
763 let event = StateMachineStateChangeEvent {
764 event_count,
765 timestamp,
766 handle: state_machine_handle,
767 name: state_machine_sym,
768 state_handle,
769 state: state_sym,
770 };
771 Some((event_code, Event::StateMachineStateChange(event)))
772 }
773
774 EventType::UnusedStack => {
775 let handle = object_handle(&mut r, event_id)?;
776 let low_mark = r.read_u32()?;
777 let sym = entry_table
778 .symbol(handle)
779 .ok_or(Error::ObjectLookup(handle))?;
780 let event = UnusedStackEvent {
781 event_count,
782 timestamp,
783 handle,
784 task: sym.clone().into(),
785 low_mark,
786 };
787 Some((event_code, Event::UnusedStack(event)))
788 }
789
790 EventType::UserEvent(raw_arg_count) => {
791 if num_params.0 < 1 {
793 return Err(Error::InvalidEventParameterCount(
794 event_code.event_id(),
795 1,
796 num_params,
797 ));
798 }
799
800 let (is_fixed, arg_count) = if event_id.0 >= FIXED_USER_EVENT_ID
802 && usize::from(raw_arg_count) >= usize::from(num_params)
803 {
804 (
805 true,
806 UserEventArgRecordCount((event_id.0 - FIXED_USER_EVENT_ID) as u8),
807 )
808 } else {
809 (false, raw_arg_count)
810 };
811
812 if usize::from(arg_count) >= usize::from(num_params) {
813 return Err(Error::InvalidEventParameterCount(
814 event_code.event_id(),
815 usize::from(arg_count),
816 num_params,
817 ));
818 }
819
820 let channel_handle = object_handle(&mut r, event_id)?;
822 let channel = entry_table
823 .symbol(channel_handle)
824 .map(|sym| UserEventChannel::Custom(sym.clone().into()))
825 .unwrap_or(UserEventChannel::Default);
826
827 self.arg_buf.clear();
828
829 let format_string = if is_fixed {
830 let fmt_string_handle = object_handle(&mut r, event_id)?;
831
832 let num_arg_bytes = usize::from(arg_count.0) * 4;
833 if num_arg_bytes != 0 {
834 self.arg_buf.resize(num_arg_bytes, 0);
835 r.read_exact(&mut self.arg_buf)?;
836 }
837
838 let res = entry_table
839 .symbol(fmt_string_handle)
840 .map(|s| TrimmedString::from_str(s))
841 .ok_or(Error::FixedUserEventFmtStringLookup(fmt_string_handle));
842 match res {
843 Ok(fmt_string) => fmt_string,
844 Err(e) => {
845 let remaining_param_words =
849 num_params.0.saturating_sub(arg_count.0 + 2);
850 if remaining_param_words != 0 {
851 let mut parameters = [0; EventParameterCount::MAX];
852 r.read_u32_into(
853 &mut parameters[..usize::from(remaining_param_words)],
854 )?;
855 }
856 return Err(e);
857 }
858 }
859 } else {
860 let not_fmt_str_arg_count = if arg_count.0 != 0 {
862 usize::from(arg_count) - 1
863 } else {
864 0
865 };
866 let num_arg_bytes = not_fmt_str_arg_count * 4;
867 if num_arg_bytes != 0 {
868 self.arg_buf.resize(num_arg_bytes, 0);
869 r.read_exact(&mut self.arg_buf)?;
870 }
871
872 let num_fmt_str_bytes =
873 (usize::from(num_params) - 1 - not_fmt_str_arg_count) * 4;
874 self.read_string(&mut r, num_fmt_str_bytes)?
875 };
876
877 let (formatted_string, args) = match format_symbol_string(
878 entry_table,
879 Protocol::Streaming,
880 self.endianness.into(),
881 &format_string,
882 &self.arg_buf,
883 ) {
884 Ok((fs, args)) => (fs, args),
885 Err(e) => {
886 error!("Failed to parse user event format string arguments, using the raw symbol instead. {e}");
887 (
888 FormattedString(format_string.clone().into()),
889 Default::default(),
890 )
891 }
892 };
893
894 let event = UserEvent {
895 event_count,
896 timestamp,
897 channel,
898 format_string: FormatString(format_string.0),
899 formatted_string,
900 args,
901 };
902 Some((event_code, Event::User(event)))
903 }
904
905 EventType::Unknown(_)
906 if self
907 .custom_printf_event_id
908 .map(|id| id == event_id)
909 .unwrap_or(false) =>
910 {
911 if num_params.0 != 0 {
912 return Err(Error::InvalidEventParameterCount(
913 event_code.event_id(),
914 0,
915 num_params,
916 ));
917 }
918
919 let channel_handle = object_handle(&mut r, event_id)?;
920 let channel = entry_table
921 .symbol(channel_handle)
922 .map(|sym| UserEventChannel::Custom(sym.clone().into()))
923 .unwrap_or(UserEventChannel::Default);
924
925 let args_len = r.read_u16()?;
926 let fmt_len = r.read_u16()?;
927
928 self.arg_buf.clear();
929 let num_arg_bytes = usize::from(args_len) * 4;
930 if num_arg_bytes != 0 {
931 self.arg_buf.resize(num_arg_bytes, 0);
932 r.read_exact(&mut self.arg_buf)?;
933 }
934
935 let format_string = self.read_string(&mut r, fmt_len.into())?;
936
937 let (formatted_string, args) = match format_symbol_string(
938 entry_table,
939 Protocol::Streaming,
940 self.endianness.into(),
941 &format_string,
942 &self.arg_buf,
943 ) {
944 Ok((fs, args)) => (fs, args),
945 Err(e) => {
946 error!("Failed to parse custom printf event format string arguments, using the raw symbol instead. {e}");
947 (
948 FormattedString(format_string.clone().into()),
949 Default::default(),
950 )
951 }
952 };
953
954 let event = UserEvent {
955 event_count,
956 timestamp,
957 channel,
958 format_string: FormatString(format_string.0),
959 formatted_string,
960 args,
961 };
962 Some((event_code, Event::User(event)))
963 }
964
965 _ => {
967 let mut parameters = [0; EventParameterCount::MAX];
968 r.read_u32_into(&mut parameters[..usize::from(num_params)])?;
969 let event = BaseEvent {
970 code: event_code,
971 event_count,
972 timestamp,
973 parameters,
974 };
975 Some((event_code, Event::Unknown(event)))
976 }
977 })
978 }
979
980 fn read_string<R: Read>(&mut self, r: &mut R, max_len: usize) -> Result<TrimmedString, Error> {
981 self.buf.clear();
982 self.buf.resize(max_len, 0);
983 r.read_exact(&mut self.buf)?;
984 Ok(TrimmedString::from_raw(&self.buf))
985 }
986}
987
988fn object_handle<T: byteordered::byteorder::ReadBytesExt, E: byteordered::Endian>(
989 r: &mut ByteOrdered<T, E>,
990 event_id: EventId,
991) -> Result<ObjectHandle, Error> {
992 let oh = r.read_u32()?;
993 ObjectHandle::new(oh).ok_or(Error::InvalidObjectHandle(event_id))
994}