/src/mozilla-central/tools/profiler/lul/platform-linux-lul.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
2 | | /* This Source Code Form is subject to the terms of the Mozilla Public |
3 | | * License, v. 2.0. If a copy of the MPL was not distributed with this |
4 | | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
5 | | |
6 | | #include <stdio.h> |
7 | | #include <signal.h> |
8 | | #include <string.h> |
9 | | #include <stdlib.h> |
10 | | #include <time.h> |
11 | | |
12 | | #include "platform.h" |
13 | | #include "PlatformMacros.h" |
14 | | #include "LulMain.h" |
15 | | #include "shared-libraries.h" |
16 | | #include "AutoObjectMapper.h" |
17 | | |
18 | | // Contains miscellaneous helpers that are used to connect the Gecko Profiler |
19 | | // and LUL. |
20 | | |
21 | | // Find out, in a platform-dependent way, where the code modules got |
22 | | // mapped in the process' virtual address space, and get |aLUL| to |
23 | | // load unwind info for them. |
24 | | void |
25 | | read_procmaps(lul::LUL* aLUL) |
26 | 0 | { |
27 | 0 | MOZ_ASSERT(aLUL->CountMappings() == 0); |
28 | 0 |
|
29 | 0 | # if defined(GP_OS_linux) || defined(GP_OS_android) |
30 | 0 | SharedLibraryInfo info = SharedLibraryInfo::GetInfoForSelf(); |
31 | 0 |
|
32 | 0 | for (size_t i = 0; i < info.GetSize(); i++) { |
33 | 0 | const SharedLibrary& lib = info.GetEntry(i); |
34 | 0 |
|
35 | 0 | std::string nativePath = lib.GetNativeDebugPath(); |
36 | 0 |
|
37 | | # if defined(GP_OS_android) |
38 | | // We're using faulty.lib. Use a special-case object mapper. |
39 | | AutoObjectMapperFaultyLib mapper(aLUL->mLog); |
40 | | # else |
41 | | // We can use the standard POSIX-based mapper. |
42 | 0 | AutoObjectMapperPOSIX mapper(aLUL->mLog); |
43 | 0 | # endif |
44 | 0 |
|
45 | 0 | // Ask |mapper| to map the object. Then hand its mapped address |
46 | 0 | // to NotifyAfterMap(). |
47 | 0 | void* image = nullptr; |
48 | 0 | size_t size = 0; |
49 | 0 | bool ok = mapper.Map(&image, &size, nativePath); |
50 | 0 | if (ok && image && size > 0) { |
51 | 0 | aLUL->NotifyAfterMap(lib.GetStart(), lib.GetEnd()-lib.GetStart(), |
52 | 0 | nativePath.c_str(), image); |
53 | 0 | } else if (!ok && lib.GetDebugName().IsEmpty()) { |
54 | 0 | // The object has no name and (as a consequence) the mapper failed to map |
55 | 0 | // it. This happens on Linux, where GetInfoForSelf() produces such a |
56 | 0 | // mapping for the VDSO. This is a problem on x86-{linux,android} because |
57 | 0 | // lack of knowledge about the mapped area inhibits LUL's special |
58 | 0 | // __kernel_syscall handling. Hence notify |aLUL| at least of the |
59 | 0 | // mapping, even though it can't read any unwind information for the area. |
60 | 0 | aLUL->NotifyExecutableArea(lib.GetStart(), lib.GetEnd()-lib.GetStart()); |
61 | 0 | } |
62 | 0 |
|
63 | 0 | // |mapper| goes out of scope at this point and so its destructor |
64 | 0 | // unmaps the object. |
65 | 0 | } |
66 | 0 |
|
67 | | # else |
68 | | # error "Unknown platform" |
69 | | # endif |
70 | | } |
71 | | |
72 | | // LUL needs a callback for its logging sink. |
73 | | void |
74 | | logging_sink_for_LUL(const char* str) |
75 | 0 | { |
76 | 0 | // These are only printed when Verbose logging is enabled (e.g. with |
77 | 0 | // MOZ_LOG="prof:5"). This is because LUL's logging is much more verbose than |
78 | 0 | // the rest of the profiler's logging, which occurs at the Info (3) and Debug |
79 | 0 | // (4) levels. |
80 | 0 | MOZ_LOG(gProfilerLog, mozilla::LogLevel::Verbose, ("[%d] %s", getpid(), str)); |
81 | 0 | } |