~evarlast/ubuntu/utopic/mongodb/upstart-workaround-debian-bug-718702

« back to all changes in this revision

Viewing changes to src/third_party/v8/tools/oom_dump/oom_dump.cc

  • Committer: Package Import Robot
  • Author(s): James Page, James Page, Robie Basak
  • Date: 2013-05-29 17:44:42 UTC
  • mfrom: (44.1.7 sid)
  • Revision ID: package-import@ubuntu.com-20130529174442-z0a4qmoww4y0t458
Tags: 1:2.4.3-1ubuntu1
[ James Page ]
* Merge from Debian unstable, remaining changes:
  - Enable SSL support:
    + d/control: Add libssl-dev to BD's.
    + d/rules: Enabled --ssl option.
    + d/mongodb.conf: Add example SSL configuration options.
  - d/mongodb-server.mongodb.upstart: Add upstart configuration.
  - d/rules: Don't strip binaries during scons build for Ubuntu.
  - d/control: Add armhf to target archs.
  - d/p/SConscript.client.patch: fixup install of client libraries.
  - d/p/0010-install-libs-to-usr-lib-not-usr-lib64-Closes-588557.patch:
    Install libraries to lib not lib64.
* Dropped changes:
  - d/p/arm-support.patch: Included in Debian.
  - d/p/double-alignment.patch: Included in Debian.
  - d/rules,control: Debian also builds with avaliable system libraries
    now.
* Fix FTBFS due to gcc and boost upgrades in saucy:
  - d/p/0008-ignore-unused-local-typedefs.patch: Add -Wno-unused-typedefs
    to unbreak building with g++-4.8.
  - d/p/0009-boost-1.53.patch: Fixup signed/unsigned casting issue.

[ Robie Basak ]
* d/p/0011-Use-a-signed-char-to-store-BSONType-enumerations.patch: Fixup
  build failure on ARM due to missing signed'ness of char cast.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// Copyright 2010 the V8 project authors. All rights reserved.
 
2
// Redistribution and use in source and binary forms, with or without
 
3
// modification, are permitted provided that the following conditions are
 
4
// met:
 
5
//
 
6
//     * Redistributions of source code must retain the above copyright
 
7
//       notice, this list of conditions and the following disclaimer.
 
8
//     * Redistributions in binary form must reproduce the above
 
9
//       copyright notice, this list of conditions and the following
 
10
//       disclaimer in the documentation and/or other materials provided
 
11
//       with the distribution.
 
12
//     * Neither the name of Google Inc. nor the names of its
 
13
//       contributors may be used to endorse or promote products derived
 
14
//       from this software without specific prior written permission.
 
15
//
 
16
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 
17
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 
18
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 
19
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 
20
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 
21
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 
22
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 
23
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 
24
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 
25
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 
26
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
27
 
 
28
#include <stdio.h>
 
29
#include <stdlib.h>
 
30
 
 
31
#include <algorithm>
 
32
 
 
33
#include <google_breakpad/processor/minidump.h>
 
34
 
 
35
#define ENABLE_DEBUGGER_SUPPORT
 
36
 
 
37
#include <v8.h>
 
38
 
 
39
namespace {
 
40
 
 
41
using google_breakpad::Minidump;
 
42
using google_breakpad::MinidumpContext;
 
43
using google_breakpad::MinidumpThread;
 
44
using google_breakpad::MinidumpThreadList;
 
45
using google_breakpad::MinidumpException;
 
46
using google_breakpad::MinidumpMemoryRegion;
 
47
 
 
48
const char* InstanceTypeToString(int type) {
 
49
  static char const* names[v8::internal::LAST_TYPE] = {0};
 
50
  if (names[v8::internal::STRING_TYPE] == NULL) {
 
51
    using namespace v8::internal;
 
52
#define SET(type) names[type] = #type;
 
53
    INSTANCE_TYPE_LIST(SET)
 
54
#undef SET
 
55
  }
 
56
  return names[type];
 
57
}
 
58
 
 
59
 
 
60
u_int32_t ReadPointedValue(MinidumpMemoryRegion* region,
 
61
                           u_int64_t base,
 
62
                           int offset) {
 
63
  u_int32_t ptr = 0;
 
64
  CHECK(region->GetMemoryAtAddress(base + 4 * offset, &ptr));
 
65
  u_int32_t value = 0;
 
66
  CHECK(region->GetMemoryAtAddress(ptr, &value));
 
67
  return value;
 
68
}
 
69
 
 
70
 
 
71
void ReadArray(MinidumpMemoryRegion* region,
 
72
               u_int64_t array_ptr,
 
73
               int size,
 
74
               int* output) {
 
75
  for (int i = 0; i < size; i++) {
 
76
    u_int32_t value;
 
77
    CHECK(region->GetMemoryAtAddress(array_ptr + 4 * i, &value));
 
78
    output[i] = value;
 
79
  }
 
80
}
 
81
 
 
82
 
 
83
u_int32_t ReadArrayFrom(MinidumpMemoryRegion* region,
 
84
                        u_int64_t base,
 
85
                        int offset,
 
86
                        int size,
 
87
                        int* output) {
 
88
  u_int32_t ptr = 0;
 
89
  CHECK(region->GetMemoryAtAddress(base + 4 * offset, &ptr));
 
90
  ReadArray(region, ptr, size, output);
 
91
}
 
92
 
 
93
 
 
94
double toM(int size) {
 
95
  return size / (1024. * 1024.);
 
96
}
 
97
 
 
98
 
 
99
class IndirectSorter {
 
100
 public:
 
101
  explicit IndirectSorter(int* a) : a_(a) { }
 
102
 
 
103
  bool operator() (int i0, int i1) {
 
104
    return a_[i0] > a_[i1];
 
105
  }
 
106
 
 
107
 private:
 
108
  int* a_;
 
109
};
 
110
 
 
111
void DumpHeapStats(const char *minidump_file) {
 
112
  Minidump minidump(minidump_file);
 
113
  CHECK(minidump.Read());
 
114
 
 
115
  MinidumpException *exception = minidump.GetException();
 
116
  CHECK(exception);
 
117
 
 
118
  MinidumpContext* crash_context = exception->GetContext();
 
119
  CHECK(crash_context);
 
120
 
 
121
  u_int32_t exception_thread_id = 0;
 
122
  CHECK(exception->GetThreadID(&exception_thread_id));
 
123
 
 
124
  MinidumpThreadList* thread_list = minidump.GetThreadList();
 
125
  CHECK(thread_list);
 
126
 
 
127
  MinidumpThread* exception_thread =
 
128
      thread_list->GetThreadByID(exception_thread_id);
 
129
  CHECK(exception_thread);
 
130
 
 
131
  // Currently only 32-bit Windows minidumps are supported.
 
132
  CHECK_EQ(MD_CONTEXT_X86, crash_context->GetContextCPU());
 
133
 
 
134
  const MDRawContextX86* contextX86 = crash_context->GetContextX86();
 
135
  CHECK(contextX86);
 
136
 
 
137
  const u_int32_t esp = contextX86->esp;
 
138
 
 
139
  MinidumpMemoryRegion* memory_region = exception_thread->GetMemory();
 
140
  CHECK(memory_region);
 
141
 
 
142
  const u_int64_t last = memory_region->GetBase() + memory_region->GetSize();
 
143
 
 
144
  u_int64_t heap_stats_addr = 0;
 
145
  for (u_int64_t addr = esp; addr < last; addr += 4) {
 
146
    u_int32_t value = 0;
 
147
    CHECK(memory_region->GetMemoryAtAddress(addr, &value));
 
148
    if (value >= esp && value < last) {
 
149
      u_int32_t value2 = 0;
 
150
      CHECK(memory_region->GetMemoryAtAddress(value, &value2));
 
151
      if (value2 == v8::internal::HeapStats::kStartMarker) {
 
152
        heap_stats_addr = addr;
 
153
        break;
 
154
      }
 
155
    }
 
156
  }
 
157
  CHECK(heap_stats_addr);
 
158
 
 
159
  // Read heap stats.
 
160
 
 
161
#define READ_FIELD(offset) \
 
162
  ReadPointedValue(memory_region, heap_stats_addr, offset)
 
163
 
 
164
  CHECK(READ_FIELD(0) == v8::internal::HeapStats::kStartMarker);
 
165
  CHECK(READ_FIELD(24) == v8::internal::HeapStats::kEndMarker);
 
166
 
 
167
  const int new_space_size = READ_FIELD(1);
 
168
  const int new_space_capacity = READ_FIELD(2);
 
169
  const int old_pointer_space_size = READ_FIELD(3);
 
170
  const int old_pointer_space_capacity = READ_FIELD(4);
 
171
  const int old_data_space_size = READ_FIELD(5);
 
172
  const int old_data_space_capacity = READ_FIELD(6);
 
173
  const int code_space_size = READ_FIELD(7);
 
174
  const int code_space_capacity = READ_FIELD(8);
 
175
  const int map_space_size = READ_FIELD(9);
 
176
  const int map_space_capacity = READ_FIELD(10);
 
177
  const int cell_space_size = READ_FIELD(11);
 
178
  const int cell_space_capacity = READ_FIELD(12);
 
179
  const int lo_space_size = READ_FIELD(13);
 
180
  const int global_handle_count = READ_FIELD(14);
 
181
  const int weak_global_handle_count = READ_FIELD(15);
 
182
  const int pending_global_handle_count = READ_FIELD(16);
 
183
  const int near_death_global_handle_count = READ_FIELD(17);
 
184
  const int destroyed_global_handle_count = READ_FIELD(18);
 
185
  const int memory_allocator_size = READ_FIELD(19);
 
186
  const int memory_allocator_capacity = READ_FIELD(20);
 
187
  const int os_error = READ_FIELD(23);
 
188
#undef READ_FIELD
 
189
 
 
190
  int objects_per_type[v8::internal::LAST_TYPE + 1] = {0};
 
191
  ReadArrayFrom(memory_region, heap_stats_addr, 21,
 
192
                v8::internal::LAST_TYPE + 1, objects_per_type);
 
193
 
 
194
  int size_per_type[v8::internal::LAST_TYPE + 1] = {0};
 
195
  ReadArrayFrom(memory_region, heap_stats_addr, 22, v8::internal::LAST_TYPE + 1,
 
196
                size_per_type);
 
197
 
 
198
  int js_global_objects =
 
199
      objects_per_type[v8::internal::JS_GLOBAL_OBJECT_TYPE];
 
200
  int js_builtins_objects =
 
201
      objects_per_type[v8::internal::JS_BUILTINS_OBJECT_TYPE];
 
202
  int js_global_proxies =
 
203
      objects_per_type[v8::internal::JS_GLOBAL_PROXY_TYPE];
 
204
 
 
205
  int indices[v8::internal::LAST_TYPE + 1];
 
206
  for (int i = 0; i <= v8::internal::LAST_TYPE; i++) {
 
207
    indices[i] = i;
 
208
  }
 
209
 
 
210
  std::stable_sort(indices, indices + sizeof(indices)/sizeof(indices[0]),
 
211
                  IndirectSorter(size_per_type));
 
212
 
 
213
  int total_size = 0;
 
214
  for (int i = 0; i <= v8::internal::LAST_TYPE; i++) {
 
215
    total_size += size_per_type[i];
 
216
  }
 
217
 
 
218
  // Print heap stats.
 
219
 
 
220
  printf("exception thread ID: %" PRIu32 " (%#" PRIx32 ")\n",
 
221
         exception_thread_id, exception_thread_id);
 
222
  printf("heap stats address: %#" PRIx64 "\n", heap_stats_addr);
 
223
#define PRINT_INT_STAT(stat) \
 
224
    printf("\t%-25s\t% 10d\n", #stat ":", stat);
 
225
#define PRINT_MB_STAT(stat) \
 
226
    printf("\t%-25s\t% 10.3f MB\n", #stat ":", toM(stat));
 
227
  PRINT_MB_STAT(new_space_size);
 
228
  PRINT_MB_STAT(new_space_capacity);
 
229
  PRINT_MB_STAT(old_pointer_space_size);
 
230
  PRINT_MB_STAT(old_pointer_space_capacity);
 
231
  PRINT_MB_STAT(old_data_space_size);
 
232
  PRINT_MB_STAT(old_data_space_capacity);
 
233
  PRINT_MB_STAT(code_space_size);
 
234
  PRINT_MB_STAT(code_space_capacity);
 
235
  PRINT_MB_STAT(map_space_size);
 
236
  PRINT_MB_STAT(map_space_capacity);
 
237
  PRINT_MB_STAT(cell_space_size);
 
238
  PRINT_MB_STAT(cell_space_capacity);
 
239
  PRINT_MB_STAT(lo_space_size);
 
240
  PRINT_INT_STAT(global_handle_count);
 
241
  PRINT_INT_STAT(weak_global_handle_count);
 
242
  PRINT_INT_STAT(pending_global_handle_count);
 
243
  PRINT_INT_STAT(near_death_global_handle_count);
 
244
  PRINT_INT_STAT(destroyed_global_handle_count);
 
245
  PRINT_MB_STAT(memory_allocator_size);
 
246
  PRINT_MB_STAT(memory_allocator_capacity);
 
247
  PRINT_INT_STAT(os_error);
 
248
#undef PRINT_STAT
 
249
 
 
250
  printf("\n");
 
251
 
 
252
  printf(
 
253
      "\tJS_GLOBAL_OBJECT_TYPE/JS_BUILTINS_OBJECT_TYPE/JS_GLOBAL_PROXY_TYPE: "
 
254
      "%d/%d/%d\n\n",
 
255
      js_global_objects, js_builtins_objects, js_global_proxies);
 
256
 
 
257
  int running_size = 0;
 
258
  for (int i = 0; i <= v8::internal::LAST_TYPE; i++) {
 
259
    int type = indices[i];
 
260
    const char* name = InstanceTypeToString(type);
 
261
    if (name == NULL) {
 
262
      // Unknown instance type.  Check that there is no objects of that type.
 
263
      CHECK_EQ(0, objects_per_type[type]);
 
264
      CHECK_EQ(0, size_per_type[type]);
 
265
      continue;
 
266
    }
 
267
    int size = size_per_type[type];
 
268
    running_size += size;
 
269
    printf("\t%-37s% 9d% 11.3f MB% 10.3f%%% 10.3f%%\n",
 
270
           name, objects_per_type[type], toM(size),
 
271
           100. * size / total_size, 100. * running_size / total_size);
 
272
  }
 
273
  printf("\t%-37s% 9d% 11.3f MB% 10.3f%%% 10.3f%%\n",
 
274
         "total", 0, toM(total_size), 100., 100.);
 
275
}
 
276
 
 
277
}  // namespace
 
278
 
 
279
int main(int argc, char **argv) {
 
280
  if (argc != 2) {
 
281
    fprintf(stderr, "usage: %s <minidump>\n", argv[0]);
 
282
    return 1;
 
283
  }
 
284
 
 
285
  DumpHeapStats(argv[1]);
 
286
 
 
287
  return 0;
 
288
}