glog 0.1
[platform/upstream/glog.git] / src / stacktrace_framesizes_unittest.cc
1 // Copyright 2007 Google Inc. All Rights Reserved.
2 // Author: Raksit Ashok
3 //
4 // Unit test for the GetStackFrames function in stacktrace.cc.
5
6 #include <stdio.h>
7 #include "glog/logging.h"
8 #include "base/commandlineflags.h"
9 #include "stacktrace.h"
10 #include "config.h"
11 #include "utilities.h"
12
13 using std::min;
14 using namespace GOOGLE_NAMESPACE;
15
16 #ifdef HAVE_STACKTRACE
17
18 // Obtain a backtrace of the stack frame sizes, verify that they look sane.
19
20 //-----------------------------------------------------------------------//
21 int CheckFrameSizesLeaf(int32* i);  // 8KB frame size.
22 int CheckFrameSizes2(int32* i);     // 4KB
23 int CheckFrameSizes1(int32* i);     // 2KB
24 int CheckFrameSizes(int32* i);      // 1KB
25 //-----------------------------------------------------------------------//
26
27 // The expected frame-sizes in the backtrace.
28 const int BACKTRACE_STEPS = 4;
29 int expected_frame_sizes[BACKTRACE_STEPS] = {
30   1 << 13,
31   1 << 12,
32   1 << 11,
33   1 << 10,
34 };
35
36 //-----------------------------------------------------------------------//
37
38 void CheckFrameSizeIsOk(int actual_frame_size, int ref_frame_size) {
39   // Assume upto 512 bytes of miscellaneous stuff in CheckFrameSizes* frames.
40   const int misc_frame_size = 512;
41   CHECK_GE(actual_frame_size, ref_frame_size);
42   CHECK_LE(actual_frame_size, ref_frame_size + misc_frame_size);
43 }
44
45 //-----------------------------------------------------------------------//
46
47 int ATTRIBUTE_NOINLINE CheckFrameSizesLeaf(int32 *i) {
48   const int DEPTH = 10;
49   void* pcs[DEPTH];
50   int frame_sizes[DEPTH];
51   int size;
52   int32 j[2048];  // 8KB.
53   for (int k = 0; k < 2048; k++) j[k] = k + i[k % 1024];
54
55   for (int depth = 0; depth < DEPTH; depth++) {
56     size = GetStackFrames(pcs, frame_sizes, depth, 0);
57     printf("--- GetStackFrames(..., %d, 0) = %d\n", depth, size);
58     CHECK_LE(size, depth);
59     CHECK_GE(size, min(depth, BACKTRACE_STEPS));
60
61     for (int k = 0; k < size; k++) {
62       if (k < BACKTRACE_STEPS)
63     // GetStackFrames doesn't work correctly if we are using glibc's backtrace.
64 #ifndef HAVE_EXECINFO_H
65         CheckFrameSizeIsOk(frame_sizes[k], expected_frame_sizes[k]);
66 #endif
67       printf("frame_sizes[%d] = %d\n", k, frame_sizes[k]);
68     }
69   }
70
71   int sum = 0;
72   for (int k = 0; k < 2048; k++) sum += j[k];
73   return sum;
74 }
75
76 //-----------------------------------------------------------------------//
77
78 /* Dummy functions to make the frame-size backtrace more interesting. */
79 int ATTRIBUTE_NOINLINE CheckFrameSizes2(int32* i) {
80   int32 j[1024];  // 4KB.
81   for (int k = 0; k < 1024; k++) j[k] = k + i[k % 512];
82   return CheckFrameSizesLeaf(j) + j[512];
83 }
84
85 int ATTRIBUTE_NOINLINE CheckFrameSizes1(int32* i) {
86   int32 j[512];  // 2KB.
87   for (int k = 0; k < 512; k++) j[k] = k + i[k % 256];
88   return CheckFrameSizes2(j) + j[256];
89 }
90
91 int ATTRIBUTE_NOINLINE CheckFrameSizes(int32* i)  {
92   int32 j[256];  // 1KB.
93   for (int k = 0; k < 256; k++) j[k] = k + i[k];
94   return CheckFrameSizes1(j) + j[128];
95 }
96
97 //-----------------------------------------------------------------------//
98
99 int main(int argc, char ** argv) {
100   FLAGS_logtostderr = true;
101   InitGoogleLogging(argv[0]);
102
103   int32 i[256];  // 1KB.
104   for (int j = 0; j < 256; j++) i[j] = j;
105   
106   int ret = CheckFrameSizes(i);
107
108   printf("CheckFrameSizes returned: %d\n", ret);
109
110   printf("PASS\n");
111   return 0;
112 }
113
114 #else
115 int main() {
116   printf("PASS (no stacktrace support)\n");
117   return 0;
118 }
119 #endif  // HAVE_STACKTRACE