* Write a BacktraceMap as Google CPU profiler binary data. */
| 349 | * Write a BacktraceMap as Google CPU profiler binary data. |
| 350 | */ |
| 351 | static void profile_write_pprof_file(FILE* f, BacktraceMap const& map) { |
| 352 | // Write the header |
| 353 | uintptr_t header[5] = {0, 3, 0, 0, 0}; |
| 354 | fwrite(&header, sizeof(header), 1, f); |
| 355 | |
| 356 | // Write the profile records |
| 357 | for (BacktraceMap::const_iterator it = map.begin(); it != map.end(); ++it) { |
| 358 | uintptr_t count = it->second; |
| 359 | fwrite(&count, sizeof(count), 1, f); |
| 360 | |
| 361 | Backtrace const* bt = it->first.getBacktrace(); |
| 362 | uintptr_t num_pcs = bt->getDepth(); |
| 363 | fwrite(&num_pcs, sizeof(num_pcs), 1, f); |
| 364 | |
| 365 | for (uintptr_t n = 0; n < num_pcs; ++n) { |
| 366 | void* pc = bt->getFrame(n); |
| 367 | fwrite(&pc, sizeof(pc), 1, f); |
| 368 | } |
| 369 | } |
| 370 | |
| 371 | // Write the trailer |
| 372 | uintptr_t trailer[3] = {0, 1, 0}; |
| 373 | fwrite(&trailer, sizeof(trailer), 1, f); |
| 374 | |
| 375 | // Write /proc/self/maps |
| 376 | // TODO(simpkins): This only works on linux |
| 377 | FILE* proc_maps = fopen("/proc/self/maps", "r"); |
| 378 | if (proc_maps) { |
| 379 | uint8_t buf[4096]; |
| 380 | while (true) { |
| 381 | size_t bytes_read = fread(buf, 1, sizeof(buf), proc_maps); |
| 382 | if (bytes_read == 0) { |
| 383 | break; |
| 384 | } |
| 385 | fwrite(buf, 1, bytes_read, f); |
| 386 | } |
| 387 | fclose(proc_maps); |
| 388 | } |
| 389 | } |
| 390 | |
| 391 | /** |
| 392 | * Write the recorded profiling information as pprof files. |
no test coverage detected