mem_viewer/lib.rs
1//! # Overview
2//!
3//! `mem_viewer` is a Rust crate that provides a macro `view_mem!` to view the memory content of an arbitrary variable. It supports viewing memory content of different data types including integers, floating-point numbers, strings, pointers, vectors, boxed variables, and structs.
4//!
5//! ## Usage
6//!
7//! Add the following line to your `Cargo.toml` file:
8//!
9//! ```toml
10//! [dependencies]
11//! mem_viewer = "0.3.0"
12//! ```
13//!
14//! Then, in your Rust code, you can use the `view_mem!` macro to view the memory content of a variable. Here's an example:
15//!
16//! ```rust
17//! use mem_viewer::*;
18//!
19//! let my_str: &str = "π¦Helloπ";
20//! view_mem!(*my_str);
21//! ```
22//!
23//! This will print the memory content of `my_var` to the console.
24//!
25//! ## Example Output
26//!
27//! ```none
28//! Name: *my_str
29//! Type: str
30//! Addr: 00007ff7f23fa4b8
31//! Size: 13 bytes
32//! Aloc: Likely Stack
33//! Address | Hex | Dec | Bin | ASCII | UTF-8
34//! ----------------------Memory Content--------------------
35//! 00007ff7f23fa4b8 | f0 | 240 | 11110000 | ... | π¦
36//! 00007ff7f23fa4b9 | 9f | 159 | 10011111 | ... | ...
37//! 00007ff7f23fa4ba | a6 | 166 | 10100110 | ... | ...
38//! 00007ff7f23fa4bb | 80 | 128 | 10000000 | ... | ...
39//! 00007ff7f23fa4bc | 48 | 072 | 01001000 | H | Hell
40//! 00007ff7f23fa4bd | 65 | 101 | 01100101 | e | ello
41//! 00007ff7f23fa4be | 6c | 108 | 01101100 | l | ...
42//! 00007ff7f23fa4bf | 6c | 108 | 01101100 | l | ...
43//! 00007ff7f23fa4c0 | 6f | 111 | 01101111 | o | ...
44//! 00007ff7f23fa4c1 | f0 | 240 | 11110000 | ... | π
45//! 00007ff7f23fa4c2 | 9f | 159 | 10011111 | ... | XXX
46//! 00007ff7f23fa4c3 | 98 | 152 | 10011000 | ... | XXX
47//! 00007ff7f23fa4c4 | 83 | 131 | 10000011 | ... | XXX
48//! ```
49//!
50//! Read more for the macro usage: [https://docs.rs/mem_viewer/latest/mem_viewer/macro.view_mem.html](https://docs.rs/mem_viewer/latest/mem_viewer/macro.view_mem.html)
51//!
52//! ## Safe Usage
53//! For safe mode, you can use the `safe_view_mem!` macro to view the memory content of a variable. Here's an example:
54//! ```rust
55//! use mem_viewer::*;
56//!
57//! let my_str: &str = "π¦Helloπ";
58//! view_mem!(my_str);
59//! ```
60//!
61//! ## Example Safe Output
62//! ```none
63//! Name : my_str
64//! Type : &str
65//! Addr : 00007ff7f23fa4b8
66//! Size : 16 bytes
67//! Aloc : Likely Stack
68//! Container Ptr: 00000203f55753c0
69//! Container Len: 13
70//! Address | Hex | Dec | Bin | ASCII | UTF-8
71//! ---------------------Container Content-------------------
72//! 00000203f55753c0 | f0 | 240 | 11110000 | ... | π¦
73//! 00000203f55753c1 | 9f | 159 | 10011111 | ... | ...
74//! 00000203f55753c2 | a6 | 166 | 10100110 | ... | ...
75//! 00000203f55753c3 | 80 | 128 | 10000000 | ... | ...
76//! 00000203f55753c4 | 48 | 072 | 01001000 | H | Hell
77//! 00000203f55753c5 | 65 | 101 | 01100101 | e | ello
78//! 00000203f55753c6 | 6c | 108 | 01101100 | l | ...
79//! 00000203f55753c7 | 6c | 108 | 01101100 | l | ...
80//! 00000203f55753c8 | 6f | 111 | 01101111 | o | ...
81//! 00000203f55753c9 | f0 | 240 | 11110000 | ... | π
82//! 00000203f55753ca | 9f | 159 | 10011111 | ... | XXX
83//! 00000203f55753cb | 98 | 152 | 10011000 | ... | XXX
84//! 00000203f55753cc | 83 | 131 | 10000011 | ... | XXX
85//! ```
86//!
87//! Read more for safe usage: [https://docs.rs/mem_viewer/latest/mem_viewer/macro.safe_view_mem.html](https://docs.rs/mem_viewer/latest/mem_viewer/macro.safe_view_mem.html)
88//!
89//! ## License
90//!
91//! This crate is licensed under the MIT License.
92//!
93//! ## Contributing
94//!
95//! Contributions are welcome! If you find any issues or have any suggestions, please open an issue or submit a pull request on [GitHub](https://github.com/ikhwanperwira/mem_viewer).
96//!
97//! # Unit Test Report
98//!
99//! ## Code Test:
100//! ```rust
101//!
102//! #[cfg(test)]
103//! mod tests {
104//! use super::*;
105//!
106//! /// Display the memopry content of a u16 variable.
107//! fn view_mem_u16(my_u16: u16) -> () {
108//! // Unsafe test
109//! view_mem!(my_u16);
110//!
111//! // Safe test
112//! safe_view_mem!(&my_u16);
113//! }
114//!
115//! /// Displays the memory content of a u64 variable.
116//! fn view_mem_u64(my_u64: u64) -> () {
117//! // Unsafe test
118//! view_mem!(my_u64);
119//!
120//! // Safe test
121//! safe_view_mem!(&my_u64);
122//! }
123//!
124//! /// Displays the memory content of a f32 variable.
125//! fn view_mem_f32(my_f32: f32) -> () {
126//! // Unsafe test
127//! view_mem!(my_f32);
128//!
129//! // Safe test
130//! safe_view_mem!(&my_f32);
131//! }
132//!
133//! /// Displays the memory content of a string variable.
134//! fn view_mem_str(my_str: &str) -> () {
135//! // Unsafe test
136//! view_mem!(my_str); // Print address of the first character of the my_str
137//! view_mem!(*my_str); // Print actual content of my_str
138//!
139//! // Safe test
140//! safe_view_mem!(&my_str);
141//! safe_view_mem!(my_str);
142//! }
143//!
144//! /// Displays the memory content of a pointer.
145//! fn view_mem_ptr<T>(my_ptr: *const T) -> () {
146//! // Unsafe test
147//! view_mem!(my_ptr);
148//! unsafe { view_mem!(*my_ptr); }
149//!
150//! // Safe test
151//! // Parameterized type is not supported for safe view.
152//! }
153//!
154//! /// Displays the memory content of a vector variable.
155//! fn view_mem_vec<T>(my_vec: Vec<T>) -> () {
156//! // Unsafe test
157//! view_mem!(my_vec);
158//! view_mem!(*my_vec);
159//!
160//! // Safe test
161//! // Parameterized type is not supported for safe view.
162//! }
163//!
164//! /// Displays the memory content of a boxed variable.
165//! fn view_mem_box<T>(my_box: Box<T>) -> () {
166//! // Unsafe test
167//! view_mem!(&my_box);
168//! view_mem!(my_box);
169//! view_mem!(*my_box);
170//!
171//! // Safe test
172//! // Parameterized type is not supported for safe view.
173//! }
174//!
175//! /// Displays the memory content of a vector of boxed variables.
176//! fn view_mem_vec_of_box<T>(my_vec_of_box: Vec<Box<T>>) -> () {
177//! // Unsafe test
178//! view_mem!(my_vec_of_box);
179//! view_mem!(*my_vec_of_box);
180//! view_mem!(*my_vec_of_box[0]);
181//!
182//! // Safe test
183//! // Parameterized type is not supported for safe view.
184//! }
185//!
186//! /// Displays the memory content of a struct variable.
187//! fn view_mem_struct<T>(my_struct: T) -> () {
188//! // Unsafe test
189//! view_mem!(&my_struct);
190//! view_mem!(my_struct);
191//!
192//! // Parameterized type is not supported for safe view.
193//! }
194//!
195//! fn view_mem_utf8(my_str: &str) -> () {
196//! // Unsafe test
197//! view_mem!(*my_str);
198//!
199//! // Safe test
200//! safe_view_mem!(my_str);
201//! }
202//!
203//! fn myfunc() {
204//! println!("This is a function pointer.");
205//! }
206//!
207//! struct MyStruct {
208//! a: u8,
209//! b: u16,
210//! c: u32,
211//! }
212//!
213//! #[derive(Serialize)]
214//! struct MySerializedStruct {
215//! a: u8,
216//! b: u16,
217//! c: u32,
218//! }
219//!
220//! #[test]
221//! fn u16_viewer() {
222//! println!("This should print the memory of the holy number 69.\n");
223//! assert_eq!(view_mem_u16(69), ());
224//! }
225//!
226//! fn u64_viewer() {
227//! println!("This should print the memory of the holy number 69.\n");
228//! assert_eq!(view_mem_u64(69), ());
229//! }
230//!
231//! #[test]
232//! fn f32_viewer() {
233//! println!("This should print the memory of pi in IEEE 754 representation, which is 0x4048f5c3.\n");
234//! assert_eq!(view_mem_f32(3.14), ());
235//! }
236//!
237//! #[test]
238//! fn str_viewer() {
239//! println!("This should print the memory of 'Hello' and its address.\n");
240//! assert_eq!(view_mem_str("Hello"), ());
241//! }
242//!
243//! #[test]
244//! fn ptr_viewer() {
245//! println!("This should print the memory of a pointer.\n");
246//! let my_ptr: *const u8 = &69;
247//!
248//! // Safe test
249//! println!("Currently pointer type is not supported by safe view memory.\n");
250//!
251//! // Unsafe test
252//! assert_eq!(view_mem_ptr(my_ptr), ());
253//! }
254//!
255//! #[test]
256//! fn vec_viewer() {
257//! println!("This should print the memory address of the vector and the memory of its elements.\n");
258//! let my_vec: Vec<u8> = vec![69, 255, 254, 253, 70];
259//!
260//! // Safe test
261//! safe_view_mem!(&my_vec);
262//!
263//! // Unsafe test
264//! assert_eq!(view_mem_vec(my_vec), ());
265//! }
266//!
267//! #[test]
268//! fn box_viewer() {
269//! println!("This should print the memory address of the box and the memory of its value.\n");
270//! let my_box: Box<u8> = Box::new(69);
271//!
272//! // Safe test
273//! safe_view_mem!(&my_box);
274//!
275//!
276//! // Unsafe test
277//! assert_eq!(view_mem_box(my_box), ());
278//! }
279//!
280//! #[test]
281//! fn vec_of_box_viewer() {
282//! println!("This should print the memory address of the vector of boxes and the memory of its elements.\n");
283//! let my_vec_of_box: Vec<Box<u8>> = vec![Box::new(69), Box::new(255), Box::new(254), Box::new(253), Box::new(70)];
284//!
285//! // Safe test
286//! safe_view_mem!(&my_vec_of_box);
287//!
288//! // Unsafe test
289//! assert_eq!(view_mem_vec_of_box(my_vec_of_box), ());
290//! }
291//!
292//! #[test]
293//! fn struct_viewer() {
294//! println!("This should print the memory address of the struct and the memory of its fields.\n");
295//! let my_struct = MyStruct {
296//! a: 69,
297//! b: 255,
298//! c: 70,
299//! };
300//!
301//! let my_serialized_struct = MySerializedStruct {
302//! a: 69,
303//! b: 255,
304//! c: 70,
305//! };
306//!
307//! // Safe test
308//! safe_view_mem!(&my_serialized_struct);
309//!
310//! // Unsafe test
311//! assert_eq!(view_mem_struct(my_struct), ());
312//! }
313//!
314//! #[test]
315//! fn utf8_viewer() {
316//! println!("This should print the memory of fixed content of string between holy number in ASCII and UTF-8 emoji.\n");
317//! assert_eq!(view_mem_utf8("π6π¦9π"), ());
318//! }
319//!
320//! #[test]
321//! fn functype_viewer() {
322//! println!("This should print the memory of function pointer.\n");
323//!
324//! // Safe test
325//! // Currently function pointer is not supported by safe view memory.
326//!
327//! // Unsafe test
328//! view_mem!(&myfunc);
329//! }
330//!
331//! }
332//! ```
333//!
334//! ## Output Test:
335//! ```none
336//! running 10 tests
337//! test tests::box_viewer ... ok
338//! test tests::f32_viewer ... ok
339//! test tests::functype_viewer ... ok
340//! test tests::ptr_viewer ... ok
341//! test tests::str_viewer ... ok
342//! test tests::struct_viewer ... ok
343//! test tests::u16_viewer ... ok
344//! test tests::utf8_viewer ... ok
345//! test tests::vec_of_box_viewer ... ok
346//! test tests::vec_viewer ... ok
347//!
348//! successes:
349//!
350//! ---- tests::box_viewer stdout ----
351//! This should print the memory address of the box and the memory of its value.
352//!
353//! Name : &my_box
354//! Type : &alloc::boxed::Box<u8>
355//! Addr : 00000038570fe198
356//! Size : 8 bytes
357//! Aloc : Likely Heap
358//! Container Ptr: 000001d943845210
359//! Container Len: 1
360//! Address | Hex | Dec | Bin | ASCII | UTF-8
361//! ---------------------Container Content-------------------
362//! 000001d943845210 | 45 | 069 | 01000101 | E | XXX
363//!
364//! Name: &my_box
365//! Type: &alloc::boxed::Box<u8>
366//! Addr: 00000038570fd548
367//! Size: 8 bytes
368//! Aloc: Likely Heap
369//! Address | Hex | Dec | Bin | ASCII | UTF-8
370//! ----------------------Memory Content--------------------
371//! 00000038570fd7c0 | b8 | 184 | 10111000 | ... | ...
372//! 00000038570fd7c1 | d4 | 212 | 11010100 | ... | ...
373//! 00000038570fd7c2 | 0f | 015 | 00001111 | SI | W8
374//! 00000038570fd7c3 | 57 | 087 | 01010111 | W | W8
375//! 00000038570fd7c4 | 38 | 056 | 00111000 | 8 | 8
376//! 00000038570fd7c5 | 00 | 000 | 00000000 | NUL | XXX
377//! 00000038570fd7c6 | 00 | 000 | 00000000 | NUL | XXX
378//! 00000038570fd7c7 | 00 | 000 | 00000000 | NUL | XXX
379//!
380//! Name: my_box
381//! Type: alloc::boxed::Box<u8>
382//! Addr: 00000038570fd4b8
383//! Size: 8 bytes
384//! Aloc: Likely Heap
385//! Address | Hex | Dec | Bin | ASCII | UTF-8
386//! ----------------------Memory Content--------------------
387//! 00000038570fd4b8 | c0 | 192 | 11000000 | ... | ...
388//! 00000038570fd4b9 | 52 | 082 | 01010010 | R | ...
389//! 00000038570fd4ba | 84 | 132 | 10000100 | ... | ...
390//! 00000038570fd4bb | 43 | 067 | 01000011 | C | ...
391//! 00000038570fd4bc | d9 | 217 | 11011001 | ... | ...
392//! 00000038570fd4bd | 01 | 001 | 00000001 | SOH | XXX
393//! 00000038570fd4be | 00 | 000 | 00000000 | NUL | XXX
394//! 00000038570fd4bf | 00 | 000 | 00000000 | NUL | XXX
395//!
396//! Name: *my_box
397//! Type: u8
398//! Addr: 000001d9438452c0
399//! Size: 1 bytes
400//! Aloc: Likely Heap
401//! Address | Hex | Dec | Bin | ASCII | UTF-8
402//! ----------------------Memory Content--------------------
403//! 000001d9438452c0 | 45 | 069 | 01000101 | E | XXX
404//!
405//!
406//! ---- tests::f32_viewer stdout ----
407//! This should print the memory of pi in IEEE 754 representation, which is 0x4048f5c3.
408//!
409//! Name: my_f32
410//! Type: f32
411//! Addr: 00000038572fd6fc
412//! Size: 4 bytes
413//! Aloc: Likely Heap
414//! Address | Hex | Dec | Bin | ASCII | UTF-8
415//! ----------------------Memory Content--------------------
416//! 00000038572fd6fc | c3 | 195 | 11000011 | ... | ...
417//! 00000038572fd6fd | f5 | 245 | 11110101 | ... | XXX
418//! 00000038572fd6fe | 48 | 072 | 01001000 | H | XXX
419//! 00000038572fd6ff | 40 | 064 | 01000000 | @ | XXX
420//!
421//! Name : &my_f32
422//! Type : &f32
423//! Addr : 00000038572fd6fc
424//! Size : 8 bytes
425//! Aloc : Likely Heap
426//! Container Ptr: 000001d9438452c0
427//! Container Len: 4
428//! Address | Hex | Dec | Bin | ASCII | UTF-8
429//! ---------------------Container Content-------------------
430//! 000001d9438452c0 | c3 | 195 | 11000011 | ... | ...
431//! 000001d9438452c1 | f5 | 245 | 11110101 | ... | XXX
432//! 000001d9438452c2 | 48 | 072 | 01001000 | H | XXX
433//! 000001d9438452c3 | 40 | 064 | 01000000 | @ | XXX
434//!
435//!
436//! ---- tests::functype_viewer stdout ----
437//! This should print the memory of function pointer.
438//!
439//! Name: &myfunc
440//! Type: &mem_viewer::tests::myfunc
441//! Addr: 00007ff62661f5b0
442//! Size: 8 bytes
443//! Aloc: Likely Stack
444//! Address | Hex | Dec | Bin | ASCII | UTF-8
445//! ----------------------Memory Content--------------------
446//! 00007ff62661f5b0 | 38 | 056 | 00111000 | 8 | ...
447//! 00007ff62661f5b1 | ea | 234 | 11101010 | ... | ...
448//! 00007ff62661f5b2 | 61 | 097 | 01100001 | a | ...
449//! 00007ff62661f5b3 | 26 | 038 | 00100110 | & | ...
450//! 00007ff62661f5b4 | f6 | 246 | 11110110 | ... | ...
451//! 00007ff62661f5b5 | 7f | 127 | 01111111 | DEL | XXX
452//! 00007ff62661f5b6 | 00 | 000 | 00000000 | NUL | XXX
453//! 00007ff62661f5b7 | 00 | 000 | 00000000 | NUL | XXX
454//!
455//!
456//! ---- tests::ptr_viewer stdout ----
457//! This should print the memory of a pointer.
458//!
459//! Currently pointer type is not supported by safe view memory.
460//!
461//! Name: my_ptr
462//! Type: *const u8
463//! Addr: 00000038576fe8f8
464//! Size: 8 bytes
465//! Aloc: Likely Heap
466//! Address | Hex | Dec | Bin | ASCII | UTF-8
467//! ----------------------Memory Content--------------------
468//! 00000038576fe8f8 | 10 | 016 | 00010000 | DLE | ...
469//! 00000038576fe8f9 | f1 | 241 | 11110001 | ... | ...
470//! 00000038576fe8fa | 61 | 097 | 01100001 | a | ...
471//! 00000038576fe8fb | 26 | 038 | 00100110 | & | ...
472//! 00000038576fe8fc | f6 | 246 | 11110110 | ... | ...
473//! 00000038576fe8fd | 7f | 127 | 01111111 | DEL | XXX
474//! 00000038576fe8fe | 00 | 000 | 00000000 | NUL | XXX
475//! 00000038576fe8ff | 00 | 000 | 00000000 | NUL | XXX
476//!
477//! Name: *my_ptr
478//! Type: u8
479//! Addr: 00007ff62661f110
480//! Size: 1 bytes
481//! Aloc: Likely Stack
482//! Address | Hex | Dec | Bin | ASCII | UTF-8
483//! ----------------------Memory Content--------------------
484//! 00007ff62661f110 | 45 | 069 | 01000101 | E | XXX
485//!
486//!
487//! ---- tests::str_viewer stdout ----
488//! This should print the memory of 'Hello' and its address.
489//!
490//! Name: my_str
491//! Type: &str
492//! Addr: 00000038578fc0b0
493//! Size: 16 bytes
494//! Aloc: Likely Heap
495//! Address | Hex | Dec | Bin | ASCII | UTF-8
496//! ----------------------Memory Content--------------------
497//! 00000038578fc0b0 | b0 | 176 | 10110000 | ... | ...
498//! 00000038578fc0b1 | f0 | 240 | 11110000 | ... | ...
499//! 00000038578fc0b2 | 61 | 097 | 01100001 | a | ...
500//! 00000038578fc0b3 | 26 | 038 | 00100110 | & | ...
501//! 00000038578fc0b4 | f6 | 246 | 11110110 | ... | ...
502//! 00000038578fc0b5 | 7f | 127 | 01111111 | DEL | β£
503//! 00000038578fc0b6 | 00 | 000 | 00000000 | NUL | β£
504//! 00000038578fc0b7 | 00 | 000 | 00000000 | NUL | β£
505//! 00000038578fc0b8 | 05 | 005 | 00000101 | ENQ | β£
506//! 00000038578fc0b9 | 00 | 000 | 00000000 | NUL |
507//! 00000038578fc0ba | 00 | 000 | 00000000 | NUL |
508//! 00000038578fc0bb | 00 | 000 | 00000000 | NUL |
509//! 00000038578fc0bc | 00 | 000 | 00000000 | NUL |
510//! 00000038578fc0bd | 00 | 000 | 00000000 | NUL | XXX
511//! 00000038578fc0be | 00 | 000 | 00000000 | NUL | XXX
512//! 00000038578fc0bf | 00 | 000 | 00000000 | NUL | XXX
513//!
514//! Name: *my_str
515//! Type: str
516//! Addr: 00007ff62661f0b0
517//! Size: 5 bytes
518//! Aloc: Likely Stack
519//! Address | Hex | Dec | Bin | ASCII | UTF-8
520//! ----------------------Memory Content--------------------
521//! 00007ff62661f0b0 | 48 | 072 | 01001000 | H | Hell
522//! 00007ff62661f0b1 | 65 | 101 | 01100101 | e | ello
523//! 00007ff62661f0b2 | 6c | 108 | 01101100 | l | XXX
524//! 00007ff62661f0b3 | 6c | 108 | 01101100 | l | XXX
525//! 00007ff62661f0b4 | 6f | 111 | 01101111 | o | XXX
526//!
527//! Name : &my_str
528//! Type : &&str
529//! Addr : 00000038578fc0b0
530//! Size : 8 bytes
531//! Aloc : Likely Heap
532//! Container Ptr: 000001d943845390
533//! Container Len: 5
534//! Address | Hex | Dec | Bin | ASCII | UTF-8
535//! ---------------------Container Content-------------------
536//! 000001d943845390 | 48 | 072 | 01001000 | H | Hell
537//! 000001d943845391 | 65 | 101 | 01100101 | e | ello
538//! 000001d943845392 | 6c | 108 | 01101100 | l | XXX
539//! 000001d943845393 | 6c | 108 | 01101100 | l | XXX
540//! 000001d943845394 | 6f | 111 | 01101111 | o | XXX
541//!
542//! Name : my_str
543//! Type : &str
544//! Addr : 00007ff62661f0b0
545//! Size : 16 bytes
546//! Aloc : Likely Stack
547//! Container Ptr: 000001d9438451f0
548//! Container Len: 5
549//! Address | Hex | Dec | Bin | ASCII | UTF-8
550//! ---------------------Container Content-------------------
551//! 000001d9438451f0 | 48 | 072 | 01001000 | H | Hell
552//! 000001d9438451f1 | 65 | 101 | 01100101 | e | ello
553//! 000001d9438451f2 | 6c | 108 | 01101100 | l | XXX
554//! 000001d9438451f3 | 6c | 108 | 01101100 | l | XXX
555//! 000001d9438451f4 | 6f | 111 | 01101111 | o | XXX
556//!
557//!
558//! ---- tests::struct_viewer stdout ----
559//! This should print the memory address of the struct and the memory of its fields.
560//!
561//! Name : &my_serialized_struct
562//! Type : &mem_viewer::tests::MySerializedStruct
563//! Addr : 0000003857afe018
564//! Size : 8 bytes
565//! Aloc : Likely Heap
566//! Container Ptr: 000001d9438452d0
567//! Container Len: 7
568//! Address | Hex | Dec | Bin | ASCII | UTF-8
569//! ---------------------Container Content-------------------
570//! 000001d9438452d0 | 45 | 069 | 01000101 | E | ...
571//! 000001d9438452d1 | ff | 255 | 11111111 | ... | ...
572//! 000001d9438452d2 | 00 | 000 | 00000000 | NUL | F
573//! 000001d9438452d3 | 46 | 070 | 01000110 | F | F
574//! 000001d9438452d4 | 00 | 000 | 00000000 | NUL | XXX
575//! 000001d9438452d5 | 00 | 000 | 00000000 | NUL | XXX
576//! 000001d9438452d6 | 00 | 000 | 00000000 | NUL | XXX
577//!
578//! Name: &my_struct
579//! Type: &mem_viewer::tests::MyStruct
580//! Addr: 0000003857afd748
581//! Size: 8 bytes
582//! Aloc: Likely Heap
583//! Address | Hex | Dec | Bin | ASCII | UTF-8
584//! ----------------------Memory Content--------------------
585//! 0000003857afd9c0 | b0 | 176 | 10110000 | ... | ...
586//! 0000003857afd9c1 | d6 | 214 | 11010110 | ... | Φ―W8
587//! 0000003857afd9c2 | af | 175 | 10101111 | ... | ...
588//! 0000003857afd9c3 | 57 | 087 | 01010111 | W | W8
589//! 0000003857afd9c4 | 38 | 056 | 00111000 | 8 | 8
590//! 0000003857afd9c5 | 00 | 000 | 00000000 | NUL | XXX
591//! 0000003857afd9c6 | 00 | 000 | 00000000 | NUL | XXX
592//! 0000003857afd9c7 | 00 | 000 | 00000000 | NUL | XXX
593//!
594//! Name: my_struct
595//! Type: mem_viewer::tests::MyStruct
596//! Addr: 0000003857afd6b0
597//! Size: 8 bytes
598//! Aloc: Likely Heap
599//! Address | Hex | Dec | Bin | ASCII | UTF-8
600//! ----------------------Memory Content--------------------
601//! 0000003857afd6b0 | 46 | 070 | 01000110 | F | F
602//! 0000003857afd6b1 | 00 | 000 | 00000000 | NUL | ...
603//! 0000003857afd6b2 | 00 | 000 | 00000000 | NUL | ...
604//! 0000003857afd6b3 | 00 | 000 | 00000000 | NUL | ...
605//! 0000003857afd6b4 | ff | 255 | 11111111 | ... | ...
606//! 0000003857afd6b5 | 00 | 000 | 00000000 | NUL | XXX
607//! 0000003857afd6b6 | 45 | 069 | 01000101 | E | XXX
608//! 0000003857afd6b7 | 00 | 000 | 00000000 | NUL | XXX
609//!
610//!
611//! ---- tests::u16_viewer stdout ----
612//! This should print the memory of the holy number 69.
613//!
614//! Name: my_u16
615//! Type: u16
616//! Addr: 00000038570fdb9e
617//! Size: 2 bytes
618//! Aloc: Likely Heap
619//! Address | Hex | Dec | Bin | ASCII | UTF-8
620//! ----------------------Memory Content--------------------
621//! 00000038570fdb9e | 45 | 069 | 01000101 | E | XXX
622//! 00000038570fdb9f | 00 | 000 | 00000000 | NUL | XXX
623//!
624//! Name : &my_u16
625//! Type : &u16
626//! Addr : 00000038570fdb9e
627//! Size : 8 bytes
628//! Aloc : Likely Heap
629//! Container Ptr: 000001d943845380
630//! Container Len: 2
631//! Address | Hex | Dec | Bin | ASCII | UTF-8
632//! ---------------------Container Content-------------------
633//! 000001d943845380 | 45 | 069 | 01000101 | E | XXX
634//! 000001d943845381 | 00 | 000 | 00000000 | NUL | XXX
635//!
636//!
637//! ---- tests::utf8_viewer stdout ----
638//! This should print the memory of fixed content of string between holy number in ASCII and UTF-8 emoji.
639//!
640//! Name: *my_str
641//! Type: str
642//! Addr: 00007ff62661f520
643//! Size: 14 bytes
644//! Aloc: Likely Stack
645//! Address | Hex | Dec | Bin | ASCII | UTF-8
646//! ----------------------Memory Content--------------------
647//! 00007ff62661f520 | f0 | 240 | 11110000 | ... | π
648//! 00007ff62661f521 | 9f | 159 | 10011111 | ... | ...
649//! 00007ff62661f522 | 98 | 152 | 10011000 | ... | ...
650//! 00007ff62661f523 | 83 | 131 | 10000011 | ... | ...
651//! 00007ff62661f524 | 36 | 054 | 00110110 | 6 | ...
652//! 00007ff62661f525 | f0 | 240 | 11110000 | ... | π¦
653//! 00007ff62661f526 | 9f | 159 | 10011111 | ... | ...
654//! 00007ff62661f527 | a6 | 166 | 10100110 | ... | ...
655//! 00007ff62661f528 | 80 | 128 | 10000000 | ... | ...
656//! 00007ff62661f529 | 39 | 057 | 00111001 | 9 | ...
657//! 00007ff62661f52a | f0 | 240 | 11110000 | ... | π
658//! 00007ff62661f52b | 9f | 159 | 10011111 | ... | XXX
659//! 00007ff62661f52c | 98 | 152 | 10011000 | ... | XXX
660//! 00007ff62661f52d | 83 | 131 | 10000011 | ... | XXX
661//!
662//! Name : my_str
663//! Type : &str
664//! Addr : 00007ff62661f520
665//! Size : 16 bytes
666//! Aloc : Likely Stack
667//! Container Ptr: 000001d943848570
668//! Container Len: 14
669//! Address | Hex | Dec | Bin | ASCII | UTF-8
670//! ---------------------Container Content-------------------
671//! 000001d943848570 | f0 | 240 | 11110000 | ... | π
672//! 000001d943848571 | 9f | 159 | 10011111 | ... | ...
673//! 000001d943848572 | 98 | 152 | 10011000 | ... | ...
674//! 000001d943848573 | 83 | 131 | 10000011 | ... | ...
675//! 000001d943848574 | 36 | 054 | 00110110 | 6 | ...
676//! 000001d943848575 | f0 | 240 | 11110000 | ... | π¦
677//! 000001d943848576 | 9f | 159 | 10011111 | ... | ...
678//! 000001d943848577 | a6 | 166 | 10100110 | ... | ...
679//! 000001d943848578 | 80 | 128 | 10000000 | ... | ...
680//! 000001d943848579 | 39 | 057 | 00111001 | 9 | ...
681//! 000001d94384857a | f0 | 240 | 11110000 | ... | π
682//! 000001d94384857b | 9f | 159 | 10011111 | ... | XXX
683//! 000001d94384857c | 98 | 152 | 10011000 | ... | XXX
684//! 000001d94384857d | 83 | 131 | 10000011 | ... | XXX
685//!
686//!
687//! ---- tests::vec_of_box_viewer stdout ----
688//! This should print the memory address of the vector of boxes and the memory of its elements.
689//!
690//! Name : &my_vec_of_box
691//! Type : &alloc::vec::Vec<alloc::boxed::Box<u8>>
692//! Addr : 00000038570fdae0
693//! Size : 8 bytes
694//! Aloc : Likely Heap
695//! Container Ptr: 000001d943845360
696//! Container Len: 5
697//! Address | Hex | Dec | Bin | ASCII | UTF-8
698//! ---------------------Container Content-------------------
699//! 000001d943845360 | 45 | 069 | 01000101 | E | ...
700//! 000001d943845361 | ff | 255 | 11111111 | ... | ...
701//! 000001d943845362 | fe | 254 | 11111110 | ... | XXX
702//! 000001d943845363 | fd | 253 | 11111101 | ... | XXX
703//! 000001d943845364 | 46 | 070 | 01000110 | F | XXX
704//!
705//! Name: my_vec_of_box
706//! Type: alloc::vec::Vec<alloc::boxed::Box<u8>>
707//! Addr: 00000038570fe910
708//! Size: 24 bytes
709//! Aloc: Likely Heap
710//! Address | Hex | Dec | Bin | ASCII | UTF-8
711//! ----------------------Memory Content--------------------
712//! 00000038570fe910 | 05 | 005 | 00000101 | ENQ | β£
713//! 00000038570fe911 | 00 | 000 | 00000000 | NUL |
714//! 00000038570fe912 | 00 | 000 | 00000000 | NUL |
715//! 00000038570fe913 | 00 | 000 | 00000000 | NUL |
716//! 00000038570fe914 | 00 | 000 | 00000000 | NUL |
717//! 00000038570fe915 | 00 | 000 | 00000000 | NUL | ...
718//! 00000038570fe916 | 00 | 000 | 00000000 | NUL | ...
719//! 00000038570fe917 | 00 | 000 | 00000000 | NUL | ...
720//! 00000038570fe918 | a0 | 160 | 10100000 | ... | ...
721//! 00000038570fe919 | 26 | 038 | 00100110 | & | ...
722//! 00000038570fe91a | 84 | 132 | 10000100 | ... | ...
723//! 00000038570fe91b | 43 | 067 | 01000011 | C | ...
724//! 00000038570fe91c | d9 | 217 | 11011001 | ... | ...
725//! 00000038570fe91d | 01 | 001 | 00000001 | SOH | βΊβ£
726//! 00000038570fe91e | 00 | 000 | 00000000 | NUL | β£
727//! 00000038570fe91f | 00 | 000 | 00000000 | NUL | β£
728//! 00000038570fe920 | 05 | 005 | 00000101 | ENQ | β£
729//! 00000038570fe921 | 00 | 000 | 00000000 | NUL |
730//! 00000038570fe922 | 00 | 000 | 00000000 | NUL |
731//! 00000038570fe923 | 00 | 000 | 00000000 | NUL |
732//! 00000038570fe924 | 00 | 000 | 00000000 | NUL |
733//! 00000038570fe925 | 00 | 000 | 00000000 | NUL | XXX
734//! 00000038570fe926 | 00 | 000 | 00000000 | NUL | XXX
735//! 00000038570fe927 | 00 | 000 | 00000000 | NUL | XXX
736//!
737//! Name: *my_vec_of_box
738//! Type: [alloc::boxed::Box<u8>]
739//! Addr: 000001d9438426a0
740//! Size: 40 bytes
741//! Aloc: Likely Heap
742//! Address | Hex | Dec | Bin | ASCII | UTF-8
743//! ----------------------Memory Content--------------------
744//! 000001d9438426a0 | 90 | 144 | 10010000 | ... | ...
745//! 000001d9438426a1 | 52 | 082 | 01010010 | R | ...
746//! 000001d9438426a2 | 84 | 132 | 10000100 | ... | ...
747//! 000001d9438426a3 | 43 | 067 | 01000011 | C | ...
748//! 000001d9438426a4 | d9 | 217 | 11011001 | ... | ...
749//! 000001d9438426a5 | 01 | 001 | 00000001 | SOH | βΊ0
750//! 000001d9438426a6 | 00 | 000 | 00000000 | NUL | 0R
751//! 000001d9438426a7 | 00 | 000 | 00000000 | NUL | ...
752//! 000001d9438426a8 | 30 | 048 | 00110000 | 0 | ...
753//! 000001d9438426a9 | 52 | 082 | 01010010 | R | ...
754//! 000001d9438426aa | 84 | 132 | 10000100 | ... | ...
755//! 000001d9438426ab | 43 | 067 | 01000011 | C | ...
756//! 000001d9438426ac | d9 | 217 | 11011001 | ... | ...
757//! 000001d9438426ad | 01 | 001 | 00000001 | SOH | ...
758//! 000001d9438426ae | 00 | 000 | 00000000 | NUL | ...
759//! 000001d9438426af | 00 | 000 | 00000000 | NUL | ...
760//! 000001d9438426b0 | a0 | 160 | 10100000 | ... | ...
761//! 000001d9438426b1 | 52 | 082 | 01010010 | R | ...
762//! 000001d9438426b2 | 84 | 132 | 10000100 | ... | ...
763//! 000001d9438426b3 | 43 | 067 | 01000011 | C | ...
764//! 000001d9438426b4 | d9 | 217 | 11011001 | ... | ...
765//! 000001d9438426b5 | 01 | 001 | 00000001 | SOH | βΊβΊ
766//! 000001d9438426b6 | 00 | 000 | 00000000 | NUL | βΊS
767//! 000001d9438426b7 | 00 | 000 | 00000000 | NUL | ...
768//! 000001d9438426b8 | 10 | 016 | 00010000 | DLE | ...
769//! 000001d9438426b9 | 53 | 083 | 01010011 | S | ...
770//! 000001d9438426ba | 84 | 132 | 10000100 | ... | ...
771//! 000001d9438426bb | 43 | 067 | 01000011 | C | ...
772//! 000001d9438426bc | d9 | 217 | 11011001 | ... | ...
773//! 000001d9438426bd | 01 | 001 | 00000001 | SOH | ...
774//! 000001d9438426be | 00 | 000 | 00000000 | NUL | ...
775//! 000001d9438426bf | 00 | 000 | 00000000 | NUL | ...
776//! 000001d9438426c0 | f0 | 240 | 11110000 | ... | ...
777//! 000001d9438426c1 | 51 | 081 | 01010001 | Q | ...
778//! 000001d9438426c2 | 84 | 132 | 10000100 | ... | ...
779//! 000001d9438426c3 | 43 | 067 | 01000011 | C | ...
780//! 000001d9438426c4 | d9 | 217 | 11011001 | ... | ...
781//! 000001d9438426c5 | 01 | 001 | 00000001 | SOH | XXX
782//! 000001d9438426c6 | 00 | 000 | 00000000 | NUL | XXX
783//! 000001d9438426c7 | 00 | 000 | 00000000 | NUL | XXX
784//!
785//! Name: *my_vec_of_box[0]
786//! Type: u8
787//! Addr: 000001d943845290
788//! Size: 1 bytes
789//! Aloc: Likely Heap
790//! Address | Hex | Dec | Bin | ASCII | UTF-8
791//! ----------------------Memory Content--------------------
792//! 000001d943845290 | 45 | 069 | 01000101 | E | XXX
793//!
794//!
795//! ---- tests::vec_viewer stdout ----
796//! This should print the memory address of the vector and the memory of its elements.
797//!
798//! Name : &my_vec
799//! Type : &alloc::vec::Vec<u8>
800//! Addr : 00000038570fe028
801//! Size : 8 bytes
802//! Aloc : Likely Heap
803//! Container Ptr: 000001d943845290
804//! Container Len: 5
805//! Address | Hex | Dec | Bin | ASCII | UTF-8
806//! ---------------------Container Content-------------------
807//! 000001d943845290 | 45 | 069 | 01000101 | E | ...
808//! 000001d943845291 | ff | 255 | 11111111 | ... | ...
809//! 000001d943845292 | fe | 254 | 11111110 | ... | XXX
810//! 000001d943845293 | fd | 253 | 11111101 | ... | XXX
811//! 000001d943845294 | 46 | 070 | 01000110 | F | XXX
812//!
813//! Name: my_vec
814//! Type: alloc::vec::Vec<u8>
815//! Addr: 00000038570fee30
816//! Size: 24 bytes
817//! Aloc: Likely Heap
818//! Address | Hex | Dec | Bin | ASCII | UTF-8
819//! ----------------------Memory Content--------------------
820//! 00000038570fee30 | 05 | 005 | 00000101 | ENQ | β£
821//! 00000038570fee31 | 00 | 000 | 00000000 | NUL |
822//! 00000038570fee32 | 00 | 000 | 00000000 | NUL |
823//! 00000038570fee33 | 00 | 000 | 00000000 | NUL |
824//! 00000038570fee34 | 00 | 000 | 00000000 | NUL |
825//! 00000038570fee35 | 00 | 000 | 00000000 | NUL | βΊ
826//! 00000038570fee36 | 00 | 000 | 00000000 | NUL | βΊR
827//! 00000038570fee37 | 00 | 000 | 00000000 | NUL | ...
828//! 00000038570fee38 | 10 | 016 | 00010000 | DLE | ...
829//! 00000038570fee39 | 52 | 082 | 01010010 | R | ...
830//! 00000038570fee3a | 84 | 132 | 10000100 | ... | ...
831//! 00000038570fee3b | 43 | 067 | 01000011 | C | ...
832//! 00000038570fee3c | d9 | 217 | 11011001 | ... | ...
833//! 00000038570fee3d | 01 | 001 | 00000001 | SOH | βΊβ£
834//! 00000038570fee3e | 00 | 000 | 00000000 | NUL | β£
835//! 00000038570fee3f | 00 | 000 | 00000000 | NUL | β£
836//! 00000038570fee40 | 05 | 005 | 00000101 | ENQ | β£
837//! 00000038570fee41 | 00 | 000 | 00000000 | NUL |
838//! 00000038570fee42 | 00 | 000 | 00000000 | NUL |
839//! 00000038570fee43 | 00 | 000 | 00000000 | NUL |
840//! 00000038570fee44 | 00 | 000 | 00000000 | NUL |
841//! 00000038570fee45 | 00 | 000 | 00000000 | NUL | XXX
842//! 00000038570fee46 | 00 | 000 | 00000000 | NUL | XXX
843//! 00000038570fee47 | 00 | 000 | 00000000 | NUL | XXX
844//!
845//! Name: *my_vec
846//! Type: [u8]
847//! Addr: 000001d943845210
848//! Size: 5 bytes
849//! Aloc: Likely Heap
850//! Address | Hex | Dec | Bin | ASCII | UTF-8
851//! ----------------------Memory Content--------------------
852//! 000001d943845210 | 45 | 069 | 01000101 | E | ...
853//! 000001d943845211 | ff | 255 | 11111111 | ... | ...
854//! 000001d943845212 | fe | 254 | 11111110 | ... | XXX
855//! 000001d943845213 | fd | 253 | 11111101 | ... | XXX
856//! 000001d943845214 | 46 | 070 | 01000110 | F | XXX
857//!
858//!
859//!
860//! successes:
861//! tests::box_viewer
862//! tests::f32_viewer
863//! tests::functype_viewer
864//! tests::ptr_viewer
865//! tests::str_viewer
866//! tests::struct_viewer
867//! tests::u16_viewer
868//! tests::utf8_viewer
869//! tests::vec_of_box_viewer
870//! tests::vec_viewer
871//!
872//! test result: ok. 10 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
873//! ```
874//!
875
876#![allow(dead_code)]
877
878pub use bincode::serialize_into;
879pub use serde::Serialize;
880
881#[macro_export]
882/// Macro to view the memory content of almost any arbitrary variable in safe way
883///
884/// It's safe because it's isolated on container with serializing into `Vec<u8>` by `serde`. Hence, the address and size displayed is not accurate and actually it's virtual address of the container instead of reported by OS.
885///
886/// It supports viewing memory content of different data types including integers, floating-point numbers, strings, vectors, boxed variables, and structs. Except pointer.
887///
888/// For struct, it's mandatory to add `#[derive(Serialize)]` to the struct definition.
889///
890/// For example:
891/// ```rust
892/// #[derive(Serialize)]
893/// struct MyStruct {
894/// a: i32,
895/// b: f32,
896/// }
897/// ```
898///
899/// # Argument
900///
901/// * `&var` - The variable whose memory content needs to be viewed.
902///
903/// # Example
904///
905/// ```rust
906/// use mem_viewer::*;
907///
908/// let my_str: &str = "π¦Helloπ";
909/// view_mem!(my_str);
910/// ```
911///
912/// # Output
913///
914/// ```none
915/// Name : my_str
916/// Type : &str
917/// Addr : 00007ff7f23fa4b8
918/// Size : 16 bytes
919/// Aloc : Likely Stack
920/// Container Ptr: 00000203f55753c0
921/// Container Len: 13
922/// Address | Hex | Dec | Bin | ASCII | UTF-8
923/// ---------------------Container Content-------------------
924/// 00000203f55753c0 | f0 | 240 | 11110000 | ... | π¦
925/// 00000203f55753c1 | 9f | 159 | 10011111 | ... | ...
926/// 00000203f55753c2 | a6 | 166 | 10100110 | ... | ...
927/// 00000203f55753c3 | 80 | 128 | 10000000 | ... | ...
928/// 00000203f55753c4 | 48 | 072 | 01001000 | H | Hell
929/// 00000203f55753c5 | 65 | 101 | 01100101 | e | ello
930/// 00000203f55753c6 | 6c | 108 | 01101100 | l | ...
931/// 00000203f55753c7 | 6c | 108 | 01101100 | l | ...
932/// 00000203f55753c8 | 6f | 111 | 01101111 | o | ...
933/// 00000203f55753c9 | f0 | 240 | 11110000 | ... | π
934/// 00000203f55753ca | 9f | 159 | 10011111 | ... | XXX
935/// 00000203f55753cb | 98 | 152 | 10011000 | ... | XXX
936/// 00000203f55753cc | 83 | 131 | 10000011 | ... | XXX
937/// ```
938macro_rules! safe_view_mem {
939 ($var: expr) => {
940 let size = std::mem::size_of_val(&$var);
941
942 // Print variable metadata
943 println!("Name : {}", stringify!($var));
944 println!("Type : {}", _get_type_of($var));
945 println!("Addr : {:016x}", $var as *const _ as *const u8 as usize);
946 println!("Size : {} bytes", size);
947
948 if format!("{:016x}", $var as *const _ as *const u8 as usize).contains("07f") {
949 // tell user that this addres probably in stack
950 println!("Aloc : Likely Stack");
951 } else {
952 println!("Aloc : Likely Heap");
953 }
954
955 // Isolate on container
956 let mut container: Vec<u8> = Vec::new();
957 serialize_into(&mut container, $var).unwrap();
958 // println!("Container Raw : {:?}", container);
959 if container.len() >= 8 && container.len() != size {
960 // If not same, then there is header of serializer with size 8 bytes, exclude it!
961 container = (&container[8..]).to_vec();
962 }
963
964 // Print container metadata
965 // println!("Container Val : {:?}", container);
966 println!("Container Ptr: {:016x}", container.as_ptr() as usize);
967 println!("Container Len: {}", container.len());
968
969 // Print container content
970 println!(" Address | Hex | Dec | Bin | ASCII | UTF-8");
971 println!("---------------------Container Content-------------------");
972 // Iterate over Vec<u8>
973 for (index, byte) in container.iter().enumerate() {
974 let addr = byte as *const u8 as usize;
975 let hex = format!("{:02x}", byte);
976 let dec = format!("{:03}", byte);
977 let bin = format!("{:08b}", byte);
978 let ascii = if byte.is_ascii_graphic() {
979 format!(" {} ", *byte as char)
980 } else {
981 match byte {
982 0 => "NUL",
983 1 => "SOH",
984 2 => "STX",
985 3 => "ETX",
986 4 => "EOT",
987 5 => "ENQ",
988 6 => "ACK",
989 7 => "BEL",
990 8 => "BS ",
991 9 => "HT ",
992 10 => "LF ",
993 11 => "VT ",
994 12 => "FF ",
995 13 => "CR ",
996 14 => "SO ",
997 15 => "SI ",
998 16 => "DLE",
999 17 => "DC1",
1000 18 => "DC2",
1001 19 => "DC3",
1002 20 => "DC4",
1003 21 => "NAK",
1004 22 => "SYN",
1005 23 => "ETB",
1006 24 => "CAN",
1007 25 => "EM ",
1008 26 => "SUB",
1009 27 => "ESC",
1010 28 => "FS ",
1011 29 => "GS ",
1012 30 => "RS ",
1013 31 => "US ",
1014 32 => "SPC",
1015 127 => "DEL",
1016 _ => "...",
1017 }.to_string()
1018 };
1019 // Get forward 4 byte for utf8 read from byte
1020 let diff = (container.len() - index) as isize;
1021 let utf8 = if diff >= 4 {
1022 let utf8 = std::str::from_utf8(&container[index..index+4]);
1023 if utf8.is_ok() {
1024 utf8.unwrap().to_string()
1025 } else {
1026 "...".to_string()
1027 }
1028 } else {
1029 "XXX".to_string()
1030 };
1031
1032 println!(" {:016x} | {} | {} | {} | {} | {}", addr, hex, dec, bin, ascii, utf8);
1033 };
1034
1035 println!();
1036 }
1037 }
1038
1039
1040#[macro_export]
1041/// Macro to view the memory content of an arbitrary variable.
1042///
1043/// It supports viewing memory content of different data types including integers, floating-point numbers, strings, pointers, vectors, boxed variables, and structs.
1044///
1045/// This is more **unsafe** than safe_view_mem! macro, because it directly reads the memory content of the variable.
1046///
1047/// As a result, it can be used to view the memory content of a pointer.
1048///
1049/// You can dereference a variable as many as you want as long compiler allows it, of course this is **unsafe** operation.
1050///
1051/// # Argument
1052///
1053/// * `var` - The variable whose memory content needs to be viewed.
1054///
1055/// # Example
1056///
1057/// ```rust
1058/// use mem_viewer::*;
1059///
1060/// let my_str: &str = "π¦Helloπ";
1061/// view_mem!(*my_str);
1062/// ```
1063///
1064/// # Output
1065///
1066/// ```none
1067/// Name: *my_str
1068/// Type: str
1069/// Addr: 00007ff7f23fa4b8
1070/// Size: 13 bytes
1071/// Aloc: Likely Stack
1072/// Address | Hex | Dec | Bin | ASCII | UTF-8
1073/// ----------------------Memory Content--------------------
1074/// 00007ff7f23fa4b8 | f0 | 240 | 11110000 | ... | π¦
1075/// 00007ff7f23fa4b9 | 9f | 159 | 10011111 | ... | ...
1076/// 00007ff7f23fa4ba | a6 | 166 | 10100110 | ... | ...
1077/// 00007ff7f23fa4bb | 80 | 128 | 10000000 | ... | ...
1078/// 00007ff7f23fa4bc | 48 | 072 | 01001000 | H | Hell
1079/// 00007ff7f23fa4bd | 65 | 101 | 01100101 | e | ello
1080/// 00007ff7f23fa4be | 6c | 108 | 01101100 | l | ...
1081/// 00007ff7f23fa4bf | 6c | 108 | 01101100 | l | ...
1082/// 00007ff7f23fa4c0 | 6f | 111 | 01101111 | o | ...
1083/// 00007ff7f23fa4c1 | f0 | 240 | 11110000 | ... | π
1084/// 00007ff7f23fa4c2 | 9f | 159 | 10011111 | ... | XXX
1085/// 00007ff7f23fa4c3 | 98 | 152 | 10011000 | ... | XXX
1086/// 00007ff7f23fa4c4 | 83 | 131 | 10000011 | ... | XXX
1087/// ```
1088macro_rules! view_mem {
1089 ($var: expr) => {
1090 // Get the size of the variable
1091 // let size = std::mem::size_of_val(&$var);
1092
1093 // Print metadata of var: var_name, size, type, separated by a new line for each meta
1094 println!("Name: {}", stringify!($var));
1095 _print_type_of(&$var);
1096 println!("Addr: {:016x}", &$var as *const _ as *const u8 as usize);
1097 println!("Size: {} bytes", std::mem::size_of_val(&$var));
1098
1099 if format!("{:016x}", &$var as *const _ as *const u8 as usize).contains("007f") {
1100 // tell user that this addres probably in stack
1101 println!("Aloc: Likely Stack");
1102 } else {
1103 println!("Aloc: Likely Heap");
1104 }
1105
1106
1107 _show_memory_content(&$var as *const _ as *const u8, std::mem::size_of_val(&$var));
1108 };
1109}
1110
1111/// Returns the type of a variable as a string.
1112///
1113/// (This is supposed to be private usage of safe_view_mem! macro usage.)
1114///
1115/// # Argument
1116///
1117/// * `_: T` - The variable whose type needs to be returned.
1118pub fn _get_type_of<T>(_: T) -> &'static str {
1119 std::any::type_name::<T>()
1120}
1121
1122/// Prints the type of a variable.
1123///
1124/// (This is supposed to be private usage for unsafe view_mem! macro usage.)
1125///
1126/// # Argument
1127///
1128/// * `_: T` - The variable whose type needs to be printed.
1129pub fn _print_type_of<T>(_: T) {
1130 let type_name = &std::any::type_name::<T>()[1..]; // Remove `&` at first character
1131 println!("Type: {}", type_name);
1132}
1133
1134/// Displays the memory content of a given memory address.
1135///
1136///
1137/// (This is supposed to be private usage for unsafe view_mem! macro usage.)
1138///
1139/// # Arguments
1140///
1141/// * `src_ptr` - The memory address to start displaying from.
1142/// * `len` - The number of bytes to display.
1143pub fn _show_memory_content(src_ptr: *const u8, len: usize) { // This supposed to be private usage.
1144 // Display the memory and its value for every byte from src_ptr to src_ptr + len
1145
1146 let mut ptr: *const u8 = src_ptr;
1147 let end: *const u8 = unsafe { src_ptr.add(len) };
1148
1149 println!(" Address | Hex | Dec | Bin | ASCII | UTF-8");
1150 println!("----------------------Memory Content--------------------");
1151 while ptr < end {
1152 let byte = unsafe {*ptr};
1153
1154 let ascii = if byte.is_ascii_graphic() {
1155 format!(" {} ", byte as char)
1156 } else {
1157 match byte {
1158 0 => "NUL",
1159 1 => "SOH",
1160 2 => "STX",
1161 3 => "ETX",
1162 4 => "EOT",
1163 5 => "ENQ",
1164 6 => "ACK",
1165 7 => "BEL",
1166 8 => "BS ",
1167 9 => "HT ",
1168 10 => "LF ",
1169 11 => "VT ",
1170 12 => "FF ",
1171 13 => "CR ",
1172 14 => "SO ",
1173 15 => "SI ",
1174 16 => "DLE",
1175 17 => "DC1",
1176 18 => "DC2",
1177 19 => "DC3",
1178 20 => "DC4",
1179 21 => "NAK",
1180 22 => "SYN",
1181 23 => "ETB",
1182 24 => "CAN",
1183 25 => "EM ",
1184 26 => "SUB",
1185 27 => "ESC",
1186 28 => "FS ",
1187 29 => "GS ",
1188 30 => "RS ",
1189 31 => "US ",
1190 32 => "SPC",
1191 127 => "DEL",
1192 _ => "...",
1193 }.to_string()
1194 };
1195
1196 // Get current difference between ptr and len
1197 let diff: isize = (end as usize - ptr as usize) as isize;
1198
1199 let utf8 = if diff >= 4 {
1200 let slice = unsafe { std::slice::from_raw_parts(ptr, 4) };
1201 match std::str::from_utf8(slice) {
1202 Ok(s) => format!("{}", s),
1203 Err(_) => "...".to_string(),
1204 }
1205 } else {
1206 "XXX".to_string()
1207 };
1208
1209 println!(" {:016x} | {:02x} | {:03} | {:08b} | {} | {} ", ptr as usize, byte as u8, byte as u8, byte as u8, ascii, utf8);
1210
1211 ptr = unsafe { ptr.add(1) };
1212 }
1213
1214 println!();
1215}
1216
1217#[cfg(test)]
1218mod tests {
1219 use super::*;
1220
1221 /// Display the memopry content of a u16 variable.
1222 fn view_mem_u16(my_u16: u16) -> () {
1223 // Unsafe test
1224 view_mem!(my_u16);
1225
1226 // Safe test
1227 safe_view_mem!(&my_u16);
1228 }
1229
1230 /// Displays the memory content of a u64 variable.
1231 fn view_mem_u64(my_u64: u64) -> () {
1232 // Unsafe test
1233 view_mem!(my_u64);
1234
1235 // Safe test
1236 safe_view_mem!(&my_u64);
1237 }
1238
1239 /// Displays the memory content of a f32 variable.
1240 fn view_mem_f32(my_f32: f32) -> () {
1241 // Unsafe test
1242 view_mem!(my_f32);
1243
1244 // Safe test
1245 safe_view_mem!(&my_f32);
1246 }
1247
1248 /// Displays the memory content of a string variable.
1249 fn view_mem_str(my_str: &str) -> () {
1250 // Unsafe test
1251 view_mem!(my_str); // Print address of the first character of the my_str
1252 view_mem!(*my_str); // Print actual content of my_str
1253
1254 // Safe test
1255 safe_view_mem!(&my_str);
1256 safe_view_mem!(my_str);
1257 }
1258
1259 /// Displays the memory content of a pointer.
1260 fn view_mem_ptr<T>(my_ptr: *const T) -> () {
1261 // Unsafe test
1262 view_mem!(my_ptr);
1263 unsafe { view_mem!(*my_ptr); }
1264
1265 // Safe test
1266 // Parameterized type is not supported for safe view.
1267 }
1268
1269 /// Displays the memory content of a vector variable.
1270 fn view_mem_vec<T>(my_vec: Vec<T>) -> () {
1271 // Unsafe test
1272 view_mem!(my_vec);
1273 view_mem!(*my_vec);
1274
1275 // Safe test
1276 // Parameterized type is not supported for safe view.
1277 }
1278
1279 /// Displays the memory content of a boxed variable.
1280 fn view_mem_box<T>(my_box: Box<T>) -> () {
1281 // Unsafe test
1282 view_mem!(&my_box);
1283 view_mem!(my_box);
1284 view_mem!(*my_box);
1285
1286 // Safe test
1287 // Parameterized type is not supported for safe view.
1288 }
1289
1290 /// Displays the memory content of a vector of boxed variables.
1291 fn view_mem_vec_of_box<T>(my_vec_of_box: Vec<Box<T>>) -> () {
1292 // Unsafe test
1293 view_mem!(my_vec_of_box);
1294 view_mem!(*my_vec_of_box);
1295 view_mem!(*my_vec_of_box[0]);
1296
1297 // Safe test
1298 // Parameterized type is not supported for safe view.
1299 }
1300
1301 /// Displays the memory content of a struct variable.
1302 fn view_mem_struct<T>(my_struct: T) -> () {
1303 // Unsafe test
1304 view_mem!(&my_struct);
1305 view_mem!(my_struct);
1306
1307 // Parameterized type is not supported for safe view.
1308 }
1309
1310 fn view_mem_utf8(my_str: &str) -> () {
1311 // Unsafe test
1312 view_mem!(*my_str);
1313
1314 // Safe test
1315 safe_view_mem!(my_str);
1316 }
1317
1318 fn myfunc() {
1319 println!("This is a function pointer.");
1320 }
1321
1322 struct MyStruct {
1323 a: u8,
1324 b: u16,
1325 c: u32,
1326 }
1327
1328 #[derive(Serialize)]
1329 struct MySerializedStruct {
1330 a: u8,
1331 b: u16,
1332 c: u32,
1333 }
1334
1335 #[test]
1336 fn u16_viewer() {
1337 println!("This should print the memory of the holy number 69.\n");
1338 assert_eq!(view_mem_u16(69), ());
1339 }
1340
1341 fn u64_viewer() {
1342 println!("This should print the memory of the holy number 69.\n");
1343 assert_eq!(view_mem_u64(69), ());
1344 }
1345
1346 #[test]
1347 fn f32_viewer() {
1348 println!("This should print the memory of pi in IEEE 754 representation, which is 0x4048f5c3.\n");
1349 assert_eq!(view_mem_f32(3.14), ());
1350 }
1351
1352 #[test]
1353 fn str_viewer() {
1354 println!("This should print the memory of 'Hello' and its address.\n");
1355 assert_eq!(view_mem_str("Hello"), ());
1356 }
1357
1358 #[test]
1359 fn ptr_viewer() {
1360 println!("This should print the memory of a pointer.\n");
1361 let my_ptr: *const u8 = &69;
1362
1363 // Safe test
1364 println!("Currently pointer type is not supported by safe view memory.\n");
1365
1366 // Unsafe test
1367 assert_eq!(view_mem_ptr(my_ptr), ());
1368 }
1369
1370 #[test]
1371 fn vec_viewer() {
1372 println!("This should print the memory address of the vector and the memory of its elements.\n");
1373 let my_vec: Vec<u8> = vec![69, 255, 254, 253, 70];
1374
1375 // Safe test
1376 safe_view_mem!(&my_vec);
1377
1378 // Unsafe test
1379 assert_eq!(view_mem_vec(my_vec), ());
1380 }
1381
1382 #[test]
1383 fn box_viewer() {
1384 println!("This should print the memory address of the box and the memory of its value.\n");
1385 let my_box: Box<u8> = Box::new(69);
1386
1387 // Safe test
1388 safe_view_mem!(&my_box);
1389
1390
1391 // Unsafe test
1392 assert_eq!(view_mem_box(my_box), ());
1393 }
1394
1395 #[test]
1396 fn vec_of_box_viewer() {
1397 println!("This should print the memory address of the vector of boxes and the memory of its elements.\n");
1398 let my_vec_of_box: Vec<Box<u8>> = vec![Box::new(69), Box::new(255), Box::new(254), Box::new(253), Box::new(70)];
1399
1400 // Safe test
1401 safe_view_mem!(&my_vec_of_box);
1402
1403 // Unsafe test
1404 assert_eq!(view_mem_vec_of_box(my_vec_of_box), ());
1405 }
1406
1407 #[test]
1408 fn struct_viewer() {
1409 println!("This should print the memory address of the struct and the memory of its fields.\n");
1410 let my_struct = MyStruct {
1411 a: 69,
1412 b: 255,
1413 c: 70,
1414 };
1415
1416 let my_serialized_struct = MySerializedStruct {
1417 a: 69,
1418 b: 255,
1419 c: 70,
1420 };
1421
1422 // Safe test
1423 safe_view_mem!(&my_serialized_struct);
1424
1425 // Unsafe test
1426 assert_eq!(view_mem_struct(my_struct), ());
1427 }
1428
1429 #[test]
1430 fn utf8_viewer() {
1431 println!("This should print the memory of fixed content of string between holy number in ASCII and UTF-8 emoji.\n");
1432 assert_eq!(view_mem_utf8("π6π¦9π"), ());
1433 }
1434
1435 #[test]
1436 fn functype_viewer() {
1437 println!("This should print the memory of function pointer.\n");
1438
1439 // Safe test
1440 // Currently function pointer is not supported by safe view memory.
1441
1442 // Unsafe test
1443 view_mem!(&myfunc);
1444 }
1445
1446}
1447