44#include < fstream>
55#include " json.hpp"
66#include < stack>
7+ #include " ../extended_profiling/extended_profiling.h"
78
89#ifdef _WIN32
910static PLH::CapstoneDisassembler* disassembler;
@@ -13,131 +14,16 @@ urmem::hook CrashProcDetour;
1314CrashProcPtr oCrashProc;
1415CallGlobalProcPtr oCallGlobalProc;
1516
16- #define TOMICROS (x ) std::chrono::duration_cast<std::chrono::microseconds>(x).count()
17-
18- struct ExtendedProfile
19- {
20- unsigned int proc_id;
21- int * bytecode; // facilitate faster searches up the call stack
22- std::vector<ExtendedProfile*> subcalls;
23- std::chrono::time_point<std::chrono::steady_clock> start_time;
24- std::chrono::time_point<std::chrono::steady_clock> end_time;
25- unsigned long long total_time = 0 ;
26- int call_id = 0 ;
27- };
28-
29- ExtendedProfile* proc_being_profiled;
30- ExtendedProfile* profile_result;
31- std::stack<ExtendedProfile*> call_stack;
32-
33- void output_subcalls (std::string base, std::ofstream& output, ExtendedProfile* profile, int depth)
34- {
35- base += Core::get_proc (profile->proc_id ).name +" ;" ;
36- // Core::Alert(base.c_str());
37- if (!(profile->subcalls .empty ()))
38- {
39- output << base << " self " << TOMICROS (profile->subcalls .back ()->start_time - profile->start_time ) << " \n " ;
40- for (ExtendedProfile* sub : profile->subcalls )
41- {
42- output_subcalls (base, output, sub, ++depth);
43- }
44- ExtendedProfile* last_sub = profile->subcalls .back ();
45- output << base << " self " << TOMICROS (profile_result->end_time - last_sub->end_time ) << " \n " ;
46- }
47- else
48- {
49- base.pop_back ();
50- output << base << " " << TOMICROS (profile->end_time - profile->start_time ) << " \n " ;
51- }
52- }
53-
54- void dump_extended_profile ()
55- {
56- /* nlohmann::json result;
57- result["version"] = "0.0.1";
58- result["$schema"] = "https://www.speedscope.app/file-format-schema.json";
59- result["name"] = Core::get_proc(profile_result->proc_id).name;
60- result["activeProfileIndex"] = 1;
61-
62- nlohmann::json shared;
63- std::vector<std::pair<std::string, std::string>> frames;
64- frames.push_back({ "name", "self" });
65- frames.push_back({"name", Core::get_proc(profile_result->proc_id).name });
66- for (ExtendedProfile* sub : profile_result->subcalls)
67- {
68- frames.push_back({ "name", Core::get_proc(sub->proc_id).name });
69- }
70- shared["frames"] = frames;
71- result["shared"] = shared;
72-
73- nlohmann::json profile;
74- profile["type"] = "sampled";
75- profile["name"] = Core::get_proc(profile_result->proc_id).name;
76- profile["unit"] = "microseconds";
77- profile["startValue"] = 0;
78- profile["endValue"] = profile_result->total_time;
79-
80-
81- std::ofstream output("extended_profile.txt");
82- output << result.dump();*/
83- std::ofstream output (" extended_profile.txt" );
84- output_subcalls (" " , output, profile_result, 0 );
85- output.flush ();
86- }
17+ // ExecutionContext* last_suspended_ec;
8718
8819trvh __cdecl hCallGlobalProc (char unk1, int unk2, int proc_type, unsigned int proc_id, int const_0, char unk3, int unk4, Value* argList, unsigned int argListLen, int const_0_2, int const_0_3)
8920{
90- int call_id = 0 ;
91- if (extended_profiling_procs.find (proc_id) != extended_profiling_procs.end ())
92- {
93- proc_being_profiled = new ExtendedProfile ();
94- proc_being_profiled->proc_id = proc_id;
95- proc_being_profiled->bytecode = Core::get_context ()->bytecode ;
96- proc_being_profiled->start_time = std::chrono::high_resolution_clock::now ();
97- call_stack.push (proc_being_profiled);
98- }
99- if (proc_being_profiled && proc_being_profiled->proc_id != proc_id)
100- {
101- call_id = rand ();
102- ExecutionContext* parent_ctx = Core::_get_parent_context ();
103- if (call_stack.top ()->proc_id == Core::get_proc (parent_ctx->bytecode ).id )
104- {
105- ExtendedProfile* subcall = new ExtendedProfile ();
106- subcall->proc_id = proc_id;
107- subcall->bytecode = Core::get_proc (proc_id).get_bytecode ();
108- subcall->start_time = std::chrono::high_resolution_clock::now ();
109- subcall->call_id = call_id;
110- call_stack.top ()->subcalls .push_back (subcall);
111- call_stack.push (subcall);
112- }
113- }
11421 if (proc_hooks.find (proc_id) != proc_hooks.end ())
11522 {
11623 trvh result = proc_hooks[proc_id](argList, argListLen);
117- Core::Alert (" hook" );
11824 return result;
11925 }
12026 trvh result = oCallGlobalProc (unk1, unk2, proc_type, proc_id, const_0, unk3, unk4, argList, argListLen, const_0_2, const_0_3);
121- if (proc_being_profiled)
122- {
123- ExtendedProfile* top = call_stack.top ();
124- if (top->proc_id == proc_id)
125- {
126- ExtendedProfile* sub = call_stack.top ();
127- sub->end_time = std::chrono::high_resolution_clock::now ();
128- call_stack.pop ();
129- sub->total_time = std::chrono::duration_cast<std::chrono::microseconds>(sub->end_time - sub->start_time ).count ();
130- }
131- if (proc_being_profiled->proc_id == proc_id)
132- {
133- proc_being_profiled->end_time = std::chrono::high_resolution_clock::now ();
134- proc_being_profiled->total_time = std::chrono::duration_cast<std::chrono::microseconds>(proc_being_profiled->end_time - proc_being_profiled->start_time ).count ();
135- profile_result = proc_being_profiled;
136- proc_being_profiled = nullptr ;
137- dump_extended_profile ();
138- // Core::Alert("Extended profile results written to file");
139- }
140- }
14127 return result;
14228}
14329
@@ -155,7 +41,6 @@ void hCrashProc(char* error, int argument)
15541#endif
15642}
15743
158-
15944void * Core::install_hook (void * original, void * hook)
16045{
16146#ifdef _WIN32
0 commit comments