Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(67)

Side by Side Diff: tools/cygprofile/cygprofile2.cc

Issue 2924093003: (Do not land) Very hacky patch for using -fprofile-functions in the Win-Clang build
Patch Set: Add code to print functions by call frquency Created 3 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « tools/cygprofile/BUILD.gn ('k') | tools/cygprofile/cygprofile2_test.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 #include <stdio.h>
2 #include <algorithm>
3 #include <unordered_set>
4 #include <unordered_map>
5
6 // Compiling printf with -finstrument-functions seems to break it?
7
8 #ifdef _MSC_VER
9 #include <windows.h>
10 #include <process.h>
11 #include <dbghelp.h>
12
13 #if 0
14 extern "C" unsigned long __stdcall GetCurrentProcessId(void);
15
16 extern "C" unsigned long _beginthread( void( __cdecl *start_address )( void * ), unsigned stack_size, void *arglist );
17 #endif
18
19 namespace {
20
21 // We can easily run out of memory if this is too high.
22 #define N (50*1024*1024)
23 //#define N (1*1024*1024)
24 void *tracebuf[N];
25 int n = 0;
26
27 char symbuf[1024*1024];
28
29 void dump(void*) {
30 HMODULE dbghelp = LoadLibraryA("dbghelp.dll");
31 decltype(::SymFromAddr) *symfromaddr =
32 reinterpret_cast<decltype(::SymFromAddr)*>(GetProcAddress(dbghelp, "SymFromA ddr"));
33 decltype(::SymInitialize) *syminitialize =
34 reinterpret_cast<decltype(::SymInitialize)*>(GetProcAddress(dbghelp, "SymIni tialize"));
35 decltype(::SymSetOptions) *symsetoptions =
36 reinterpret_cast<decltype(::SymSetOptions)*>(GetProcAddress(dbghelp, "SymSet Options"));
37
38
39 char fname[128];
40 sprintf(fname, "/src/tmp/cygprofile%lu.txt", GetCurrentProcessId());
41 FILE *f = fopen(fname, "a");
42
43 syminitialize(GetCurrentProcess(), NULL, TRUE);
44 symsetoptions(SYMOPT_DEFERRED_LOADS | SYMOPT_PUBLICS_ONLY);
45
46 std::unordered_set<void*> seen;
47
48 #if 0
49 std::unordered_map<void*, unsigned> freq;
50 for (int i = 0; i < N; i++)
51 ++freq[tracebuf[i]];
52 std::vector<void*> funcs;
53 for (auto i : freq)
54 funcs.push_back(i.first);
55 std::sort(funcs.begin(), funcs.end(), [&](void* a, void* b) {
56 return freq[b] < freq[a];
57 });
58 std::unordered_set<std::string> seen_names;
59 for (void *func : funcs) {
60 PSYMBOL_INFO symbol = (PSYMBOL_INFO)symbuf;
61 symbol->SizeOfStruct = sizeof(SYMBOL_INFO);
62 symbol->MaxNameLen = MAX_SYM_NAME;
63 DWORD64 offset = 0;
64 if (symfromaddr(GetCurrentProcess(), (DWORD64)func, &offset, symbol)) {
65 char *name = symbol->Name;
66 if (name[0] == '_')
67 name++;
68 if (seen_names.count(name))
69 continue;
70 seen_names.insert(name);
71 fprintf(f, "%s (%u)\n", name, freq[func]);
72 }
73 }
74 #endif
75
76 #if 1
77 // Due to inlining, multiple functions can end up with the same symbol.
78 std::unordered_set<std::string> seen_names;
79
80 for (int i = 0; i < N; i++) {
81 if (seen.count(tracebuf[i]))
82 continue;
83 seen.insert(tracebuf[i]);
84
85 //fprintf(f, "0x%p\n", tracebuf[i]);
86
87 PSYMBOL_INFO symbol = (PSYMBOL_INFO)symbuf;
88 symbol->SizeOfStruct = sizeof(SYMBOL_INFO);
89 symbol->MaxNameLen = MAX_SYM_NAME;
90 DWORD64 offset = 0;
91 if (symfromaddr(GetCurrentProcess(), (DWORD64)tracebuf[i], &offset, symbol)) {
92 char *name = symbol->Name;
93 if (name[0] == '_')
94 name++;
95 if (seen_names.count(name))
96 continue;
97 seen_names.insert(name);
98 fprintf(f, "%s\n", name);
99 }
100 }
101 #endif
102
103 fclose(f);
104 }
105
106 }
107 #endif
108
109 extern "C" {
110
111 // Set attributes to be sure we don't instrument ourselves.
112 void __cyg_profile_func_enter(void* this_fn, void* call_site)
113 __attribute__((no_instrument_function));
114 void __cyg_profile_func_exit(void* this_fn, void* call_site)
115 __attribute__((no_instrument_function));
116
117 void __cyg_profile_func_enter(void* this_fn, void* callee_unused) {
118 // This gets pulled into NaCL binaries and all kinds of places.
119 #ifdef _MSC_VER
120 static int done = 0;
121
122 if (done)
123 return;
124
125 tracebuf[n++] = this_fn;
126
127 if (n == N) {
128 done = 1;
129 _beginthread(dump, 0, nullptr);
130 return;
131 }
132 #endif
133 }
134
135 void __cyg_profile_func_exit(void* this_fn, void* call_site) {}
136
137 } // extern "C"
138
OLDNEW
« no previous file with comments | « tools/cygprofile/BUILD.gn ('k') | tools/cygprofile/cygprofile2_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698