xref: /aosp_15_r20/external/google-breakpad/src/client/minidump_file_writer_unittest.cc (revision 9712c20fc9bbfbac4935993a2ca0b3958c5adad2)
1 // Copyright 2006 Google LLC
2 //
3 // Redistribution and use in source and binary forms, with or without
4 // modification, are permitted provided that the following conditions are
5 // met:
6 //
7 //     * Redistributions of source code must retain the above copyright
8 // notice, this list of conditions and the following disclaimer.
9 //     * Redistributions in binary form must reproduce the above
10 // copyright notice, this list of conditions and the following disclaimer
11 // in the documentation and/or other materials provided with the
12 // distribution.
13 //     * Neither the name of Google LLC nor the names of its
14 // contributors may be used to endorse or promote products derived from
15 // this software without specific prior written permission.
16 //
17 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 
29 // Author: [email protected] (Dan Waylonis)
30 
31 /*
32  g++ -I../ ../common/convert_UTF.cc \
33  ../common/string_conversion.cc \
34  minidump_file_writer.cc \
35  minidump_file_writer_unittest.cc \
36  -o minidump_file_writer_unittest
37  */
38 
39 #ifdef HAVE_CONFIG_H
40 #include <config.h>  // Must come first
41 #endif
42 
43 #include <fcntl.h>
44 #include <unistd.h>
45 
46 #include "minidump_file_writer-inl.h"
47 
48 using google_breakpad::MinidumpFileWriter;
49 
50 #define ASSERT_TRUE(cond) \
51 if (!(cond)) { \
52   fprintf(stderr, "FAILED: %s at %s:%d\n", #cond, __FILE__, __LINE__); \
53     return false; \
54 }
55 
56 #define ASSERT_EQ(e1, e2) ASSERT_TRUE((e1) == (e2))
57 #define ASSERT_NE(e1, e2) ASSERT_TRUE((e1) != (e2))
58 
59 struct StringStructure {
60   unsigned long integer_value;
61   MDLocationDescriptor first_string;
62   MDLocationDescriptor second_string;
63 };
64 
65 struct ArrayStructure {
66   unsigned char char_value;
67   unsigned short short_value;
68   unsigned long long_value;
69 };
70 
71 typedef struct {
72   unsigned long count;
73   ArrayStructure array[0];
74 } ObjectAndArrayStructure;
75 
WriteFile(const char * path)76 static bool WriteFile(const char* path) {
77   MinidumpFileWriter writer;
78   if (writer.Open(path)) {
79     // Test a single structure
80     google_breakpad::TypedMDRVA<StringStructure> strings(&writer);
81     ASSERT_TRUE(strings.Allocate());
82     strings.get()->integer_value = 0xBEEF;
83     const char* first = "First String";
84     ASSERT_TRUE(writer.WriteString(first, 0, &strings.get()->first_string));
85     const wchar_t* second = L"Second String";
86     ASSERT_TRUE(writer.WriteString(second, 0, &strings.get()->second_string));
87 
88     // Test an array structure
89     google_breakpad::TypedMDRVA<ArrayStructure> array(&writer);
90     unsigned int count = 10;
91     ASSERT_TRUE(array.AllocateArray(count));
92     for (unsigned char i = 0; i < count; ++i) {
93       ArrayStructure local;
94       local.char_value = i;
95       local.short_value = i + 1;
96       local.long_value = i + 2;
97       ASSERT_TRUE(array.CopyIndex(i, &local));
98     }
99 
100     // Test an object followed by an array
101     google_breakpad::TypedMDRVA<ObjectAndArrayStructure> obj_array(&writer);
102     ASSERT_TRUE(obj_array.AllocateObjectAndArray(count,
103                                                  sizeof(ArrayStructure)));
104     obj_array.get()->count = count;
105     for (unsigned char i = 0; i < count; ++i) {
106       ArrayStructure local;
107       local.char_value = i;
108       local.short_value = i + 1;
109       local.long_value = i + 2;
110       ASSERT_TRUE(obj_array.CopyIndexAfterObject(i, &local, sizeof(local)));
111     }
112   }
113 
114   return writer.Close();
115 }
116 
CompareFile(const char * path)117 static bool CompareFile(const char* path) {
118   unsigned long expected[] = {
119 #if defined(__BIG_ENDIAN__)
120     0x0000beef, 0x0000001e, 0x00000018, 0x00000020, 0x00000038, 0x00000000,
121     0x00000018, 0x00460069, 0x00720073, 0x00740020, 0x00530074, 0x00720069,
122     0x006e0067, 0x00000000, 0x0000001a, 0x00530065, 0x0063006f, 0x006e0064,
123     0x00200053, 0x00740072, 0x0069006e, 0x00670000, 0x00000001, 0x00000002,
124     0x01000002, 0x00000003, 0x02000003, 0x00000004, 0x03000004, 0x00000005,
125     0x04000005, 0x00000006, 0x05000006, 0x00000007, 0x06000007, 0x00000008,
126     0x07000008, 0x00000009, 0x08000009, 0x0000000a, 0x0900000a, 0x0000000b,
127     0x0000000a, 0x00000001, 0x00000002, 0x01000002, 0x00000003, 0x02000003,
128     0x00000004, 0x03000004, 0x00000005, 0x04000005, 0x00000006, 0x05000006,
129     0x00000007, 0x06000007, 0x00000008, 0x07000008, 0x00000009, 0x08000009,
130     0x0000000a, 0x0900000a, 0x0000000b, 0x00000000
131 #else
132     0x0000beef, 0x0000001e, 0x00000018, 0x00000020,
133     0x00000038, 0x00000000, 0x00000018, 0x00690046,
134     0x00730072, 0x00200074, 0x00740053, 0x00690072,
135     0x0067006e, 0x00000000, 0x0000001a, 0x00650053,
136     0x006f0063, 0x0064006e, 0x00530020, 0x00720074,
137     0x006e0069, 0x00000067, 0x00011e00, 0x00000002,
138     0x00021e01, 0x00000003, 0x00031e02, 0x00000004,
139     0x00041e03, 0x00000005, 0x00051e04, 0x00000006,
140     0x00061e05, 0x00000007, 0x00071e06, 0x00000008,
141     0x00081e07, 0x00000009, 0x00091e08, 0x0000000a,
142     0x000a1e09, 0x0000000b, 0x0000000a, 0x00011c00,
143     0x00000002, 0x00021c01, 0x00000003, 0x00031c02,
144     0x00000004, 0x00041c03, 0x00000005, 0x00051c04,
145     0x00000006, 0x00061c05, 0x00000007, 0x00071c06,
146     0x00000008, 0x00081c07, 0x00000009, 0x00091c08,
147     0x0000000a, 0x000a1c09, 0x0000000b, 0x00000000,
148 #endif
149   };
150   size_t expected_byte_count = sizeof(expected);
151   int fd = open(path, O_RDONLY, 0600);
152   void* buffer = malloc(expected_byte_count);
153   ASSERT_NE(fd, -1);
154   ASSERT_TRUE(buffer);
155   ASSERT_EQ(read(fd, buffer, expected_byte_count),
156             static_cast<ssize_t>(expected_byte_count));
157 
158   char* b1;
159   char* b2;
160   b1 = reinterpret_cast<char*>(buffer);
161   b2 = reinterpret_cast<char*>(expected);
162   while (*b1 == *b2) {
163     b1++;
164     b2++;
165   }
166 
167   printf("%p\n", reinterpret_cast<void*>(b1 - (char*)buffer));
168 
169   ASSERT_EQ(memcmp(buffer, expected, expected_byte_count), 0);
170   return true;
171 }
172 
RunTests()173 static bool RunTests() {
174   const char* path = "/tmp/minidump_file_writer_unittest.dmp";
175   ASSERT_TRUE(WriteFile(path));
176   ASSERT_TRUE(CompareFile(path));
177   unlink(path);
178   return true;
179 }
180 
main(int argc,const char * argv[])181 extern "C" int main(int argc, const char* argv[]) {
182   return RunTests() ? 0 : 1;
183 }
184