DebugManager.cpp 45 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778
  1. #include "DebugManager.h"
  2. #include "BeefySysLib/util/CritSect.h"
  3. #include "Compiler/BfSystem.h"
  4. #include "Compiler/BfParser.h"
  5. #include "Compiler/MemReporter.h"
  6. #include "Compiler/BfIRCodeGen.h"
  7. #include "Debugger.h"
  8. #include "DebugVisualizers.h"
  9. #include "RadixMap.h"
  10. #include "Compiler/BfDemangler.h"
  11. #include "llvm/Support/ErrorHandling.h"
  12. #include "BeefySysLib/util/BeefPerf.h"
  13. #include "NetManager.h"
  14. #include "Compiler/CeDebugger.h"
  15. #ifdef BF_PLATFORM_WINDOWS
  16. #include "DbgMiniDump.h"
  17. #endif
  18. #include <iostream>
  19. #pragma warning(push)
  20. #pragma warning(disable:4141)
  21. #pragma warning(disable:4146)
  22. #pragma warning(disable:4291)
  23. #pragma warning(disable:4244)
  24. #pragma warning(disable:4267)
  25. #pragma warning(disable:4624)
  26. #pragma warning(disable:4800)
  27. #pragma warning(disable:4996)
  28. #include "llvm/IR/LLVMContext.h"
  29. #include "llvm/IRReader/IRReader.h"
  30. //#include "llvm/Bitcode/ReaderWriter.h"
  31. #pragma warning(pop)
  32. #ifdef BF_PLATFORM_WINDOWS
  33. #include <psapi.h>
  34. #include <shlobj.h>
  35. #endif
  36. #include "BeefySysLib/util/AllocDebug.h"
  37. #pragma warning(disable:4190)
  38. #define ENABLE_DBG_32
  39. //#define BF_DBG_32
  40. //#include "WinDebugger.h"
  41. //#undef BF_DBG_32
  42. /*#define BF_DBG_64
  43. #include "WinDebugger.h"
  44. #undef BF_DBG_64*/
  45. int Beefy::sRadixMapCount = 0;
  46. int Beefy::sRootSize = 0;
  47. int Beefy::sMidSize = 0;
  48. int Beefy::sLeafSize = 0;
  49. USING_NS_BF;
  50. DebugManager* Beefy::gDebugManager = NULL;
  51. Debugger* Beefy::gDebugger = NULL;
  52. PerfManager* Beefy::gDbgPerfManager = NULL;
  53. int64 gBfAllocCount = 0;
  54. int64 gBfFreeCount = 0;
  55. static Dictionary<long, int> gBfAllocMap;
  56. static Dictionary<void*, long> gBfAllocAddrMap;
  57. //////////////////////////////////////////////////////////////////////////
  58. DebugManager::DebugManager()
  59. {
  60. gDbgPerfManager = new PerfManager();
  61. mDebugVisualizers = new DebugVisualizers();
  62. mStepFilterVersion = 0;
  63. mStepOverExternalFiles = false;
  64. mDebugger32 = NULL;
  65. mDebugger64 = NULL;
  66. mNetManager = new NetManager();
  67. mNetManager->mDebugManager = this;
  68. mSymSrvOptions.mCacheDir = "C:\\SymCache";
  69. mSymSrvOptions.mSymbolServers.Add("C:\\BeefSyms");
  70. mSymSrvOptions.mSymbolServers.Add("https://msdl.microsoft.com/download/symbols");
  71. mSymSrvOptions.mSymbolServers.Add("http://wintest.beefy2d.com/symbols/");
  72. mSymSrvOptions.mSymbolServers.Add("https://chromium-browser-symsrv.commondatastorage.googleapis.com");
  73. //TODO: Just for testing
  74. mSymSrvOptions.mSymbolServers.Add("http://127.0.0.1/symbols");
  75. SetSourceServerCacheDir();
  76. }
  77. DebugManager::~DebugManager()
  78. {
  79. if ((gDebugger != NULL) && (gDebugger->IsOnDemandDebugger()))
  80. {
  81. delete gDebugger;
  82. gDebugger = NULL;
  83. }
  84. delete mNetManager;
  85. delete mDebugger64;
  86. delete mDebugger32;
  87. /*for (auto stepFilter : mStepFilters)
  88. {
  89. }*/
  90. delete mDebugVisualizers;
  91. }
  92. void DebugManager::OutputMessage(const StringImpl& msg)
  93. {
  94. AutoCrit autoCrit(mCritSect);
  95. mOutMessages.push_back("msg " + msg);
  96. }
  97. void DebugManager::OutputRawMessage(const StringImpl& msg)
  98. {
  99. AutoCrit autoCrit(mCritSect);
  100. mOutMessages.push_back(msg);
  101. }
  102. void DebugManager::SetSourceServerCacheDir()
  103. {
  104. #ifdef BF_PLATFORM_WINDOWS
  105. AutoCrit autoCrit(mCritSect);
  106. WCHAR appDataPath[MAX_PATH] = { 0 };
  107. SHGetFolderPath(NULL, CSIDL_LOCAL_APPDATA | CSIDL_FLAG_CREATE, NULL, 0, appDataPath);
  108. mSymSrvOptions.mSourceServerCacheDir = UTF8Encode(appDataPath);
  109. mSymSrvOptions.mSourceServerCacheDir += "\\SourceServer";
  110. if (mSymSrvOptions.mFlags & BfSymSrvFlag_TempCache)
  111. {
  112. mSymSrvOptions.mSourceServerCacheDir += "\\temp";
  113. RecursiveDeleteDirectory(mSymSrvOptions.mSourceServerCacheDir);
  114. }
  115. #endif
  116. }
  117. //#define CAPTURE_ALLOC_BACKTRACE
  118. //#define CAPTURE_ALLOC_SOURCES
  119. #ifdef CAPTURE_ALLOC_BACKTRACE
  120. const int sNumAllocAddrs = 0x300000;
  121. const int sCaptureDepth = 14;
  122. const int sCaptureOffset = 4;
  123. static intptr gAllocAddrs[sNumAllocAddrs][sCaptureDepth];
  124. #endif
  125. #ifdef CAPTURE_ALLOC_SOURCES
  126. #include <Dbghelp.h>
  127. #pragma comment(lib, "dbghelp.lib")
  128. struct CaptureAllocLocation
  129. {
  130. public:
  131. char* mSymName;
  132. int mTotalSize;
  133. bool mIsEndpoint;
  134. };
  135. struct CaptureAllocEntry
  136. {
  137. public:
  138. CaptureAllocLocation* mLoc;
  139. int mAllocSize;
  140. };
  141. std::map<long, CaptureAllocEntry> gBfCaptureSourceAllocMap;
  142. //std::map<void*, CaptureAllocLocation> gBfCaptureAllocLocation;
  143. #define CAPTURE_ALLOC_POOL_SIZE 0x100000
  144. CaptureAllocLocation* gHashCaptureAllocSize[CAPTURE_ALLOC_POOL_SIZE] = { 0 };
  145. static void ReallocEntry(long oldRequest, long newRequest, int newSize)
  146. {
  147. auto itr = gBfCaptureSourceAllocMap.find(oldRequest);
  148. if (itr != gBfCaptureSourceAllocMap.end())
  149. {
  150. CaptureAllocEntry* entry = &itr->second;
  151. entry->mLoc->mTotalSize -= entry->mAllocSize;
  152. entry->mLoc->mTotalSize += newSize;
  153. entry->mAllocSize = newSize;
  154. gBfCaptureSourceAllocMap[newRequest] = *entry;
  155. gBfCaptureSourceAllocMap.erase(itr);
  156. }
  157. }
  158. static void RemoveAllocEntry(long lRequest)
  159. {
  160. auto itr = gBfCaptureSourceAllocMap.find(lRequest);
  161. if (itr != gBfCaptureSourceAllocMap.end())
  162. {
  163. CaptureAllocEntry* entry = &itr->second;
  164. entry->mLoc->mTotalSize -= entry->mAllocSize;
  165. gBfCaptureSourceAllocMap.erase(itr);
  166. }
  167. }
  168. //const LOC_HASHES
  169. #endif
  170. static int gBfNumAllocs = 0;
  171. #ifdef BF_PLATFORM_WINDOWS
  172. static bool gBgTrackingAllocs = false; ///// Leave false most of the time
  173. CritSect gBfCritSect;
  174. static bool gInsideAlloc = false;
  175. static int gLastReqId = 0;
  176. static int BfAllocHook(int nAllocType, void *pvData,
  177. size_t nSize, int nBlockUse, long lRequest,
  178. const unsigned char * szFileName, int nLine)
  179. {
  180. #ifdef CAPTURE_ALLOC_SOURCES
  181. if (gInsideAlloc)
  182. return TRUE;
  183. gInsideAlloc = true;
  184. intptr stackTrace[20];
  185. int traceCount = (int)RtlCaptureStackBackTrace(1, 20, (void**)&stackTrace, 0);
  186. /*intptr ebpVal;
  187. __asm
  188. {
  189. mov ebpVal, ebp
  190. }*/
  191. //intptr ebp = ebpVal;
  192. //intptr eip = 0;
  193. static HANDLE hProcess = 0;
  194. if (hProcess == NULL)
  195. {
  196. hProcess = GetCurrentProcess();
  197. BOOL worked = SymInitialize(hProcess, NULL, TRUE);
  198. }
  199. if (nAllocType == _HOOK_ALLOC)
  200. {
  201. for (int i = 0; i < traceCount; i++)
  202. {
  203. /*__try
  204. {
  205. ebp = *((intptr*)ebp + 0);
  206. if (ebp < 0x100000)
  207. break;
  208. eip = *((intptr*)ebp + 1);
  209. }
  210. __except (EXCEPTION_EXECUTE_HANDLER)
  211. {
  212. break;
  213. }*/
  214. intptr curAddr = stackTrace[i];
  215. const char* name = "?";
  216. int hashVal = (curAddr & 0x7FFFFFFF) % CAPTURE_ALLOC_POOL_SIZE;
  217. if (gHashCaptureAllocSize[hashVal] == NULL)
  218. {
  219. //static HPROCESS hProc = GEtProcessH
  220. char symData[4096];
  221. DWORD64 disp = 0;
  222. SYMBOL_INFO* symInfo = (SYMBOL_INFO*)&symData;
  223. memset(symInfo, 0, sizeof(SYMBOL_INFO));
  224. symInfo->SizeOfStruct = sizeof(SYMBOL_INFO);
  225. symInfo->MaxNameLen = sizeof(symData) - sizeof(SYMBOL_INFO);
  226. bool foundSym = false;
  227. if (SymFromAddr(hProcess, (DWORD64)curAddr, &disp, symInfo))
  228. {
  229. name = symInfo->Name;
  230. foundSym = true;
  231. }
  232. CaptureAllocLocation* captureAllocLoc = new CaptureAllocLocation();
  233. captureAllocLoc->mSymName = strdup(name);
  234. captureAllocLoc->mTotalSize = 0;
  235. captureAllocLoc->mIsEndpoint = (!foundSym) || (strncmp(name, "Beefy::", 7) == 0) || (strncmp(name, "llvm::", 6) == 0);
  236. if (strstr(name, "operator new") != NULL)
  237. captureAllocLoc->mIsEndpoint = false;
  238. if (strstr(name, "::allocateBuckets") != NULL)
  239. captureAllocLoc->mIsEndpoint = false;
  240. if (strstr(name, "::grow") != NULL)
  241. captureAllocLoc->mIsEndpoint = false;
  242. if (strstr(name, "::DenseMap") != NULL)
  243. captureAllocLoc->mIsEndpoint = false;
  244. /*if (strstr(name, "::Allocate") != NULL)
  245. captureAllocLoc->mIsEndpoint = false;*/
  246. if (strstr(name, "::Alloc") != NULL)
  247. captureAllocLoc->mIsEndpoint = false;
  248. /*if (strstr(name, "::AllocBytes") != NULL)
  249. captureAllocLoc->mIsEndpoint = false;
  250. if (strstr(name, "::AllocMemoryBlock") != NULL)
  251. captureAllocLoc->mIsEndpoint = false;*/
  252. if (strstr(name, "::GrowPool") != NULL)
  253. captureAllocLoc->mIsEndpoint = false;
  254. // Testing COnstantInt::get
  255. if (strstr(name, "::CreateConst") != NULL)
  256. captureAllocLoc->mIsEndpoint = false;
  257. if (strstr(name, "::get") != NULL)
  258. captureAllocLoc->mIsEndpoint = false;
  259. if ((captureAllocLoc->mIsEndpoint) && (foundSym))
  260. {
  261. }
  262. gHashCaptureAllocSize[hashVal] = captureAllocLoc;
  263. }
  264. CaptureAllocLocation* captureAllocLoc = gHashCaptureAllocSize[hashVal];
  265. if ((i < 19) && (!captureAllocLoc->mIsEndpoint))
  266. {
  267. continue;
  268. }
  269. captureAllocLoc->mTotalSize += (int)nSize;
  270. CaptureAllocEntry entry;
  271. entry.mAllocSize = (int)nSize;
  272. entry.mLoc = captureAllocLoc;
  273. gBfCaptureSourceAllocMap[lRequest] = entry;
  274. break;
  275. //if (i >= sCaptureOffset)
  276. //gAllocAddrs[lRequest][i - sCaptureOffset] = eip;
  277. }
  278. }
  279. else if (nAllocType == _HOOK_REALLOC)
  280. {
  281. long oldRequest = ((int*)pvData)[-2];
  282. ReallocEntry(oldRequest, lRequest, nSize);
  283. }
  284. else if (nAllocType == _HOOK_FREE)
  285. {
  286. lRequest = ((int*)pvData)[-2];
  287. RemoveAllocEntry(lRequest);
  288. }
  289. gInsideAlloc = false;
  290. #endif
  291. #ifdef CAPTURE_ALLOC_BACKTRACE
  292. if (lRequest < sNumAllocAddrs)
  293. {
  294. gAllocAddrs[lRequest][0] = 1;
  295. intptr ebpVal;
  296. __asm
  297. {
  298. mov ebpVal, ebp
  299. }
  300. intptr ebp = ebpVal;
  301. intptr eip = 0;
  302. for (int i = 0; i < sCaptureDepth + sCaptureOffset; i++)
  303. {
  304. __try
  305. {
  306. ebp = *((intptr*)ebp + 0);
  307. if (ebp < 0x100000)
  308. break;
  309. eip = *((intptr*)ebp + 1);
  310. }
  311. __except (EXCEPTION_EXECUTE_HANDLER)
  312. {
  313. break;
  314. }
  315. if (i >= sCaptureOffset)
  316. gAllocAddrs[lRequest][i - sCaptureOffset] = eip;
  317. }
  318. }
  319. #else
  320. if (!gBgTrackingAllocs)
  321. return TRUE;
  322. /*AutoCrit critSect(gBfCritSect);
  323. if (gLastReqId == lRequest)
  324. return TRUE;
  325. if (!gInsideAlloc)
  326. {
  327. gInsideAlloc = true;
  328. if (nAllocType == _HOOK_ALLOC)
  329. {
  330. gBfNumAllocs++;
  331. gBfAllocCount += nSize;
  332. gBfAllocMap[lRequest] = nSize;
  333. }
  334. if (nAllocType == _HOOK_FREE)
  335. {
  336. lRequest = ((int*)pvData)[-2];
  337. auto itr = gBfAllocMap.find(lRequest);
  338. if (itr != gBfAllocMap.end())
  339. {
  340. gBfFreeCount += itr->second;
  341. gBfAllocMap.erase(itr);
  342. }
  343. }
  344. gInsideAlloc = false;
  345. }
  346. gLastReqId = lRequest;
  347. if (szFileName == NULL)
  348. return TRUE; */
  349. /*char str[1024];
  350. sprintf(str, "Alloc: %d File: %s Line: %d\n", lRequest, szFileName, nLine);
  351. OutputDebugStringA(str);*/
  352. #endif
  353. return TRUE;
  354. }
  355. #endif //BF_PLATFORM_WINDOWS
  356. void BfReportMemory()
  357. {
  358. BfLogDbg("Used: %.2fM NumAllocs: %d Allocs: %.2fM\n", (gBfAllocCount - gBfFreeCount) / (1024.0 * 1024.0), gBfNumAllocs, gBfAllocCount / (1024.0 * 1024.0));
  359. }
  360. void BfFullReportMemory()
  361. {
  362. /*OutputDebugStrF("Testing OOB\n");
  363. char* str = new char[12];
  364. delete str;
  365. char c = str[1];*/
  366. if (gBfParserCache != NULL)
  367. {
  368. MemReporter memReporter;
  369. memReporter.BeginSection("ParserCache");
  370. gBfParserCache->ReportMemory(&memReporter);
  371. memReporter.EndSection();
  372. memReporter.Report();
  373. }
  374. OutputDebugStrF("Used: %.2fM NumAllocs: %d Allocs: %.2fM\n", (gBfAllocCount - gBfFreeCount) / (1024.0 * 1024.0), gBfNumAllocs, gBfAllocCount / (1024.0 * 1024.0));
  375. OutputDebugStrF("ChunkedDataBuffer allocated blocks: %d\n", ChunkedDataBuffer::sBlocksAllocated);
  376. if (gDebugManager != NULL)
  377. {
  378. MemReporter memReporter;
  379. if (gDebugManager->mDebugger32 != NULL)
  380. {
  381. memReporter.BeginSection("Debugger32");
  382. gDebugManager->mDebugger32->ReportMemory(&memReporter);
  383. memReporter.EndSection();
  384. }
  385. memReporter.BeginSection("Debugger64");
  386. gDebugManager->mDebugger64->ReportMemory(&memReporter);
  387. memReporter.EndSection();
  388. memReporter.Report();
  389. }
  390. BpDump();
  391. #ifdef CAPTURE_ALLOC_SOURCES
  392. int memTotal = 0;
  393. std::map<String, int> byNameMap;
  394. for (int i = 0; i < CAPTURE_ALLOC_POOL_SIZE; i++)
  395. {
  396. CaptureAllocLocation* allocLoc = gHashCaptureAllocSize[i];
  397. if ((allocLoc != NULL) && (allocLoc->mTotalSize > 0))
  398. {
  399. auto itr = byNameMap.insert(std::map<String, int>::value_type(allocLoc->mSymName, 0));
  400. itr.first->second += allocLoc->mTotalSize;
  401. memTotal += allocLoc->mTotalSize;
  402. }
  403. }
  404. std::multimap<int, String> bySizeMap;
  405. for (auto kv : byNameMap)
  406. {
  407. //OutputDebugStrF("%dk %s\n", (kv.second + 1023) / 1024, kv.first.c_str());
  408. bySizeMap.insert(std::multimap<int, String>::value_type(-kv.second, kv.first));
  409. }
  410. for (auto kv : bySizeMap)
  411. {
  412. OutputDebugStrF("%dk %s\n", (-kv.first + 1023) / 1024, kv.second.c_str());
  413. }
  414. OutputDebugStrF("Total %dk\n", memTotal / 1024);
  415. #endif
  416. }
  417. struct _CrtMemBlockHeader
  418. {
  419. _CrtMemBlockHeader* _block_header_next;
  420. _CrtMemBlockHeader* _block_header_prev;
  421. char const* _file_name;
  422. int _line_number;
  423. int _block_use;
  424. size_t _data_size;
  425. long _request_number;
  426. //unsigned char _gap[no_mans_land_size];
  427. // Followed by:
  428. // unsigned char _data[_data_size];
  429. // unsigned char _another_gap[no_mans_land_size];
  430. };
  431. //static _CrtMemBlockHeader* __acrt_first_block;
  432. //static _CrtMemBlockHeader* __acrt_last_block;
  433. void ShowMemoryUsage()
  434. {
  435. #ifdef BF_PLATFORM_WINDOWS
  436. PROCESS_MEMORY_COUNTERS processMemCounters;
  437. processMemCounters.cb = sizeof(PROCESS_MEMORY_COUNTERS);
  438. GetProcessMemoryInfo(GetCurrentProcess(), &processMemCounters, sizeof(PROCESS_MEMORY_COUNTERS));
  439. OutputDebugStrF("WorkingSet : %dk\n", (int)(processMemCounters.WorkingSetSize / 1024));
  440. OutputDebugStrF("VirtualMem : %dk\n", (int)(processMemCounters.PagefileUsage/1024));
  441. static bool hasCheckpoint = true;
  442. _CrtMemState memState;
  443. _CrtMemCheckpoint(&memState);
  444. //OutputDebugStrF("Crt Size: %dk\n", (int)(memState.lTotalCount / 1024));
  445. char* names[6] = { "_FREE_BLOCK", "_NORMAL_BLOCK", "_CRT_BLOCK", "_IGNORE_BLOCK", "_CLIENT_BLOCK", "_MAX_BLOCKS" };
  446. for (int i = 0; i < 5; i++)
  447. {
  448. OutputDebugStrF("%s : %d %dk\n", names[i], memState.lCounts[i], memState.lSizes[i] / 1024);
  449. }
  450. #ifdef _DEBUG
  451. // int64 totalCrtSize = 0;
  452. // int64 totalUseCrtSize = 0;
  453. // _CrtMemBlockHeader* blockPtr = memState.pBlockHeader;
  454. // while (blockPtr != NULL)
  455. // {
  456. // totalCrtSize += blockPtr->_data_size;
  457. // if (blockPtr->_block_use != _FREE_BLOCK)
  458. // totalUseCrtSize += blockPtr->_data_size;
  459. // blockPtr = blockPtr->_block_header_next;
  460. // }
  461. // OutputDebugStrF("Crt Size: %dk Used: %dk\n", (int)(totalCrtSize / 1024), (int)(totalUseCrtSize / 1024));
  462. #endif
  463. _HEAPINFO heapInfo = {0};
  464. int64 heapSize = 0;
  465. int heapStatus;
  466. while ((heapStatus = _heapwalk(&heapInfo)) == _HEAPOK)
  467. {
  468. heapSize += (int64)heapInfo._size;
  469. }
  470. OutputDebugStrF("WALKED HEAP SIZE: %dk\n", heapSize / 1024);
  471. //_CrtMemDumpStatistics(&memState);
  472. #endif
  473. }
  474. /*void* TestHeapAlloc(HANDLE hHeap, DWORD dwFlags, SIZE_T dwBytes)
  475. {
  476. return HeapAlloc(hHeap, dwFlags, dwBytes);
  477. }*/
  478. static void BfFatalErrorHandler(void *user_data, const std::string& reason, bool gen_crash_diag)
  479. {
  480. BF_FATAL(reason.c_str());
  481. OutputDebugStrF("LLVM ERROR: %s\n", reason.c_str());
  482. }
  483. #ifdef BF_PLATFORM_WINDOWS
  484. BOOL WINAPI DllMain(
  485. HANDLE hDllHandle,
  486. DWORD dwReason,
  487. LPVOID lpreserved)
  488. {
  489. if (dwReason == DLL_PROCESS_ATTACH)
  490. {
  491. BpInit("127.0.0.1", "Beef IDE");
  492. BpSetThreadName("Main");
  493. BfpThread_SetName(NULL, "Main", NULL);
  494. llvm::install_fatal_error_handler(BfFatalErrorHandler, NULL);
  495. //_CRTDBG_CHECK_EVERY_16_DF
  496. //_CRTDBG_CHECK_ALWAYS_DF
  497. //_CRTDBG_DELAY_FREE_MEM_DF
  498. //_CrtSetDbgFlag (_CRTDBG_ALLOC_MEM_DF /*| _CRTDBG_CHECK_ALWAYS_DF*/);
  499. _CrtSetAllocHook(BfAllocHook);
  500. }
  501. if (dwReason == -123)
  502. {
  503. BpDump();
  504. }
  505. return TRUE;
  506. }
  507. #endif //BF_PLATFORM_WINDOWS
  508. //////
  509. void SleepTest()
  510. {
  511. BfpThread_Sleep(3000);
  512. }
  513. void WdAllocTest();
  514. namespace BeefyDbg64
  515. {
  516. class WinDebugger;
  517. void TestPDB(const StringImpl& fileName, WinDebugger* debugger);
  518. }
  519. #ifdef BF_PLATFORM_WINDOWS
  520. static _CrtMemState gStartMemCheckpoint;
  521. #endif
  522. BF_EXPORT void BF_CALLTYPE Debugger_Create()
  523. {
  524. //TODO: Very slow, remove
  525. //_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_CHECK_ALWAYS_DF);
  526. //_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_CHECK_EVERY_16_DF);
  527. //TODO: _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF /*| _CRTDBG_CHECK_EVERY_16_DF*/);
  528. //_CrtSetAllocHook(BfAllocHook);
  529. #ifdef BF_PLATFORM_WINDOWS
  530. _CrtMemCheckpoint(&gStartMemCheckpoint);
  531. #endif
  532. //_CrtSetBreakAlloc(621);
  533. gDebugManager = new DebugManager();
  534. #ifdef ENABLE_DBG_32
  535. gDebugManager->mDebugger32 = CreateDebugger32(gDebugManager, NULL);
  536. #else
  537. gDebugManager->mDebugger32 = NULL;
  538. #endif
  539. #ifdef BF32
  540. gDebugManager->mDebugger64 = NULL;
  541. #else
  542. gDebugManager->mDebugger64 = CreateDebugger64(gDebugManager, NULL);
  543. #endif
  544. #ifdef BF_PLATFORM_WINDOWS
  545. ::AllowSetForegroundWindow(ASFW_ANY);
  546. #endif
  547. //BeefyDbg64::TestPDB("C:/Beef/IDE/dist/IDEHelper64_d.pdb", (BeefyDbg64::WinDebugger*)gDebugManager->mDebugger64);
  548. }
  549. BF_EXPORT void BF_CALLTYPE Debugger_SetCallbacks(void* callback)
  550. {
  551. }
  552. BF_EXPORT void BF_CALLTYPE Debugger_FullReportMemory()
  553. {
  554. //WdAllocTest();
  555. ShowMemoryUsage();
  556. BfFullReportMemory();
  557. }
  558. BF_EXPORT void BF_CALLTYPE Debugger_Delete()
  559. {
  560. delete gDebugManager;
  561. gDebugManager = NULL;
  562. delete gPerfManager;
  563. gPerfManager = NULL;
  564. //OutputDebugStrF("Deleting Debugger\n");
  565. //BfReportMemory();
  566. #ifdef BF_PLATFORM_WINDOWS
  567. gBgTrackingAllocs = false;
  568. #endif
  569. }
  570. BF_EXPORT void BF_CALLTYPE IDEHelper_ProgramStart()
  571. {
  572. BfIRCodeGen::StaticInit();
  573. }
  574. BF_EXPORT void BF_CALLTYPE IDEHelper_ProgramDone()
  575. {
  576. //TODO:
  577. //::MessageBoxA(NULL, "Done", "Done", MB_OK);
  578. BF_ASSERT(gDebugger == NULL);
  579. //ShowMemoryUsage();
  580. //BfFullReportMemory();
  581. #ifdef CAPTURE_ALLOC_SOURCES
  582. gInsideAlloc = true;
  583. for (int i = 0; i < CAPTURE_ALLOC_POOL_SIZE; i++)
  584. {
  585. if (gHashCaptureAllocSize[i] != NULL)
  586. {
  587. free(gHashCaptureAllocSize[i]->mSymName);
  588. delete gHashCaptureAllocSize[i];
  589. gHashCaptureAllocSize[i] = NULL;
  590. }
  591. }
  592. gBfCaptureSourceAllocMap.clear();
  593. #endif
  594. #ifdef BF_PLATFORM_WINDOWS
  595. _CrtMemDumpAllObjectsSince(&gStartMemCheckpoint);
  596. /*_CrtMemState curMemCheckpoint;
  597. _CrtMemCheckpoint(&curMemCheckpoint);
  598. _CrtMemState memDiff;
  599. if (_CrtMemDifference(&memDiff, &gStartMemCheckpoint, &curMemCheckpoint))
  600. _CrtMemDumpStatistics(&memDiff);*/
  601. _CrtMemState curMemCheckpoint = { 0 };
  602. _CrtMemCheckpoint(&curMemCheckpoint);
  603. OutputDebugStrF("Heap memory usage: %dk\n", curMemCheckpoint.lTotalCount / 1024);
  604. #endif //BF_PLATFORM_WINDOWS
  605. BpShutdown();
  606. }
  607. BF_EXPORT int BF_CALLTYPE Debugger_GetAddrSize()
  608. {
  609. if (gDebugger == NULL)
  610. return 0;
  611. return gDebugger->GetAddrSize();
  612. }
  613. BF_EXPORT bool BF_CALLTYPE Debugger_OpenFile(const char* launchPath, const char* targetPath, const char* args, const char* workingDir, void* envBlockPtr, int envBlockSize, bool hotSwapEnabled)
  614. {
  615. BF_ASSERT(gDebugger == NULL);
  616. if (!FileExists(launchPath))
  617. {
  618. gDebugManager->mOutMessages.push_back(StrFormat("error Unable to locate specified launch target '%s'", launchPath));
  619. return false;
  620. }
  621. DebuggerResult debuggerResult = DebuggerResult_Ok;
  622. if ((gDebugManager->mDebugger64 != NULL) && (gDebugManager->mDebugger64->CanOpen(launchPath, &debuggerResult)))
  623. gDebugger = gDebugManager->mDebugger64;
  624. else
  625. gDebugger = gDebugManager->mDebugger32;
  626. if (gDebugger == NULL)
  627. {
  628. if (debuggerResult == DebuggerResult_WrongBitSize)
  629. gDebugManager->mOutMessages.push_back(StrFormat("error The file 32-bit file '%s' cannot be debugged because 32-bit debugger has been disabled", launchPath));
  630. return false;
  631. }
  632. Array<uint8> envBlock;
  633. if (envBlockPtr != NULL)
  634. {
  635. if (envBlockSize != 0)
  636. envBlock.Insert(0, (uint8*)envBlockPtr, envBlockSize);
  637. }
  638. gDebugger->OpenFile(launchPath, targetPath, args, workingDir, envBlock, hotSwapEnabled);
  639. return true;
  640. }
  641. BF_EXPORT bool BF_CALLTYPE Debugger_ComptimeAttach(void* bfCompiler)
  642. {
  643. gDebugger = new CeDebugger(gDebugManager, (BfCompiler*)bfCompiler);
  644. return true;
  645. }
  646. BF_EXPORT void BF_CALLTYPE Debugger_SetSymSrvOptions(const char* symCacheDir, const char* symSrvStr, int flags)
  647. {
  648. Array<String> symServers;
  649. const char* startStr = symSrvStr;
  650. for (const char* cPtr = symSrvStr; true; cPtr++)
  651. {
  652. if ((*cPtr == '\n') || (*cPtr == 0))
  653. {
  654. String symStr = String(startStr, cPtr - startStr);
  655. symStr.Trim();
  656. if (symStr.EndsWith('/'))
  657. symStr.Remove((int)symStr.length() - 1, 1);
  658. if (!symStr.IsEmpty())
  659. symServers.Add(symStr);
  660. startStr = cPtr;
  661. }
  662. if (*cPtr == 0)
  663. break;
  664. }
  665. AutoCrit autoCrit(gDebugManager->mCritSect);
  666. gDebugManager->mSymSrvOptions.mCacheDir = symCacheDir;
  667. gDebugManager->mSymSrvOptions.mSymbolServers = symServers;
  668. gDebugManager->mSymSrvOptions.mFlags = (BfSymSrvFlags)flags;
  669. gDebugManager->mSymSrvOptions.mCacheDir.Trim();
  670. if (gDebugManager->mSymSrvOptions.mCacheDir.IsEmpty())
  671. gDebugManager->mSymSrvOptions.mFlags = BfSymSrvFlag_Disable;
  672. if (flags & BfSymSrvFlag_TempCache)
  673. {
  674. if (!gDebugManager->mSymSrvOptions.mCacheDir.IsEmpty())
  675. {
  676. gDebugManager->mSymSrvOptions.mCacheDir.Append("\\temp");
  677. RecursiveDeleteDirectory(gDebugManager->mSymSrvOptions.mCacheDir);
  678. }
  679. }
  680. gDebugManager->SetSourceServerCacheDir();
  681. }
  682. BF_EXPORT void BF_CALLTYPE Debugger_SetSourcePathRemap(const char* remapStr)
  683. {
  684. AutoCrit autoCrit(gDebugManager->mCritSect);
  685. gDebugManager->mSourcePathRemap.Clear();
  686. const char* startStr = remapStr;
  687. for (const char* cPtr = remapStr; true; cPtr++)
  688. {
  689. if ((*cPtr == '\n') || (*cPtr == 0))
  690. {
  691. String remapStr = String(startStr, cPtr - startStr);
  692. remapStr.Trim();
  693. int eqPos = (int)remapStr.IndexOf('=');
  694. if (eqPos != -1)
  695. {
  696. auto keyStr = remapStr.Substring(0, eqPos);
  697. keyStr.Trim();
  698. auto valueStr = remapStr.Substring(eqPos + 1);
  699. valueStr.Trim();
  700. gDebugManager->mSourcePathRemap[keyStr] = valueStr;
  701. }
  702. startStr = cPtr;
  703. }
  704. if (*cPtr == 0)
  705. break;
  706. }
  707. }
  708. BF_EXPORT bool BF_CALLTYPE Debugger_OpenMiniDump(const char* fileName)
  709. {
  710. #ifdef BF_PLATFORM_WINDOWS
  711. DbgMiniDump* dbgMiniDump = new DbgMiniDump();
  712. bool result = dbgMiniDump->StartLoad(fileName);
  713. if (!result)
  714. {
  715. delete dbgMiniDump;
  716. return false;
  717. }
  718. if (dbgMiniDump->GetTargetBitCount() == 32)
  719. gDebugger = CreateDebugger32(gDebugManager, dbgMiniDump);
  720. else
  721. gDebugger = CreateDebugger64(gDebugManager, dbgMiniDump);
  722. return result;
  723. #else //BF_PLATFORM_WINDOWS
  724. return false;
  725. #endif
  726. }
  727. BF_EXPORT bool BF_CALLTYPE Debugger_Attach(int processId, BfDbgAttachFlags attachFlags)
  728. {
  729. BF_ASSERT(gDebugger == NULL);
  730. if (gDebugManager->mDebugger64->Attach(processId, attachFlags))
  731. {
  732. gDebugger = gDebugManager->mDebugger64;
  733. return true;
  734. }
  735. if (gDebugManager->mDebugger32->Attach(processId, attachFlags))
  736. {
  737. gDebugger = gDebugManager->mDebugger32;
  738. return true;
  739. }
  740. return false;
  741. }
  742. BF_EXPORT void BF_CALLTYPE Debugger_Run()
  743. {
  744. gDebugger->Run();
  745. }
  746. BF_EXPORT bool BF_CALLTYPE Debugger_HotLoad(const char* fileNamesStr, int hotIdx)
  747. {
  748. //DbgModule* dwarf = new DbgModule(gDebugger);
  749. //dwarf->ReadPE(fileName);
  750. Array<String> fileNames;
  751. const char* curPtr = fileNamesStr;
  752. for (int i = 0; true; i++)
  753. {
  754. if ((fileNamesStr[i] == '\0') || (fileNamesStr[i] == '\n'))
  755. {
  756. String curFileName = String(curPtr, fileNamesStr + i);
  757. if ((curFileName.IndexOf("/vdata.") != -1) || (curFileName.IndexOf("\\vdata.") != -1))
  758. {
  759. // Do vdata first - so new data and special functions don't have to be deferred resolved
  760. fileNames.Insert(0, curFileName);
  761. }
  762. else
  763. fileNames.Add(curFileName);
  764. curPtr = fileNamesStr + i + 1;
  765. }
  766. if (fileNamesStr[i] == '\0')
  767. break;
  768. }
  769. gDebugger->HotLoad(fileNames, hotIdx);
  770. return true;
  771. }
  772. BF_EXPORT bool BF_CALLTYPE Debugger_LoadDebugVisualizers(const char* fileName)
  773. {
  774. String fn = fileName;
  775. bool worked = false;
  776. worked = gDebugManager->mDebugVisualizers->Load(fileName);
  777. if (!gDebugManager->mDebugVisualizers->mErrorString.empty())
  778. {
  779. gDebugManager->mOutMessages.push_back(StrFormat("msg ERROR: %s\n", gDebugManager->mDebugVisualizers->mErrorString.c_str()));
  780. }
  781. // {
  782. // BF_FATAL(gDebugManager->mDebugVisualizers->mErrorString.c_str());
  783. // }
  784. return worked;
  785. }
  786. BF_EXPORT void BF_CALLTYPE Debugger_StopDebugging()
  787. {
  788. gDebugger->StopDebugging();
  789. }
  790. BF_EXPORT void BF_CALLTYPE Debugger_Terminate()
  791. {
  792. gDebugger->Terminate();
  793. }
  794. BF_EXPORT void BF_CALLTYPE Debugger_Detach()
  795. {
  796. gDebugManager->mNetManager->CancelAll();
  797. gDebugger->Detach();
  798. if (gDebugger->IsOnDemandDebugger())
  799. delete gDebugger;
  800. gDebugger = NULL;
  801. gDebugManager->mNetManager->Clear();
  802. }
  803. BF_EXPORT Breakpoint* BF_CALLTYPE Debugger_CreateBreakpoint(const char* fileName, int lineNum, int wantColumn, int instrOffset)
  804. {
  805. return gDebugger->CreateBreakpoint(fileName, lineNum, wantColumn, instrOffset);
  806. }
  807. BF_EXPORT Breakpoint* BF_CALLTYPE Debugger_CreateMemoryBreakpoint(intptr address, int byteCount)
  808. {
  809. return gDebugger->CreateMemoryBreakpoint(address, byteCount);
  810. }
  811. BF_EXPORT Breakpoint* BF_CALLTYPE Debugger_CreateSymbolBreakpoint(const char* symbolName)
  812. {
  813. return gDebugger->CreateSymbolBreakpoint(symbolName);
  814. }
  815. BF_EXPORT Breakpoint* BF_CALLTYPE Debugger_CreateAddressBreakpoint(intptr address)
  816. {
  817. return gDebugger->CreateAddressBreakpoint(address);
  818. }
  819. BF_EXPORT Breakpoint* BF_CALLTYPE Debugger_GetActiveBreakpoint()
  820. {
  821. return gDebugger->GetActiveBreakpoint();
  822. }
  823. BF_EXPORT void BF_CALLTYPE Breakpoint_Delete(Breakpoint* wdBreakpoint)
  824. {
  825. gDebugger->DeleteBreakpoint(wdBreakpoint);
  826. }
  827. BF_EXPORT void BF_CALLTYPE Breakpoint_Check(Breakpoint* breakpoint)
  828. {
  829. gDebugger->CheckBreakpoint(breakpoint);
  830. }
  831. BF_EXPORT int BF_CALLTYPE Breakpoint_GetPendingHotBindIdx(Breakpoint* breakpoint)
  832. {
  833. return breakpoint->mPendingHotBindIdx;
  834. }
  835. BF_EXPORT void BF_CALLTYPE Breakpoint_HotBindBreakpoint(Breakpoint* breakpoint, int lineNum, int hotIdx)
  836. {
  837. gDebugger->HotBindBreakpoint(breakpoint, lineNum, hotIdx);
  838. }
  839. BF_EXPORT void BF_CALLTYPE Breakpoint_SetThreadId(Breakpoint* breakpoint, intptr threadId)
  840. {
  841. BfLogDbg("Breakpoint %p set ThreadId=%d\n", breakpoint, threadId);
  842. breakpoint->mThreadId = threadId;
  843. gDebugger->CheckBreakpoint(breakpoint);
  844. }
  845. BF_EXPORT int BF_CALLTYPE Breakpoint_GetHitCount(Breakpoint* breapoint)
  846. {
  847. return breapoint->mHitCount;
  848. }
  849. BF_EXPORT void BF_CALLTYPE Breakpoint_ClearHitCount(Breakpoint* breapoint)
  850. {
  851. breapoint->mHitCount = 0;
  852. }
  853. BF_EXPORT void BF_CALLTYPE Breakpoint_SetHitCountTarget(Breakpoint* breakpoint, int targetHitCount, DbgHitCountBreakKind breakKind)
  854. {
  855. breakpoint->mTargetHitCount = targetHitCount;
  856. breakpoint->mHitCountBreakKind = breakKind;
  857. }
  858. BF_EXPORT void BF_CALLTYPE Breakpoint_SetCondition(Breakpoint* wdBreakpoint, const char* condition)
  859. {
  860. gDebugger->SetBreakpointCondition(wdBreakpoint, condition);
  861. }
  862. BF_EXPORT void BF_CALLTYPE Breakpoint_SetLogging(Breakpoint* wdBreakpoint, const char* logging, bool breakAfterLogging)
  863. {
  864. gDebugger->SetBreakpointLogging(wdBreakpoint, logging, breakAfterLogging);
  865. }
  866. BF_EXPORT uintptr BF_CALLTYPE Breakpoint_GetAddress(Breakpoint* wdBreakpoint, Breakpoint** outLinkedSibling)
  867. {
  868. if (outLinkedSibling != NULL)
  869. *outLinkedSibling = wdBreakpoint->mLinkedSibling;
  870. return gDebugger->GetBreakpointAddr(wdBreakpoint);
  871. }
  872. BF_EXPORT bool BF_CALLTYPE Breakpoint_IsMemoryBreakpointBound(Breakpoint* wdBreakpoint)
  873. {
  874. return wdBreakpoint->IsMemoryBreakpointBound();
  875. }
  876. BF_EXPORT intptr BF_CALLTYPE Breakpoint_GetLineNum(Breakpoint* wdBreakpoint)
  877. {
  878. return wdBreakpoint->mLineNum;
  879. }
  880. BF_EXPORT void BF_CALLTYPE Breakpoint_Move(Breakpoint* breakpoint, int lineNum, int wantColumn, bool rebindNow)
  881. {
  882. gDebugger->MoveBreakpoint(breakpoint, lineNum, wantColumn, rebindNow);
  883. }
  884. BF_EXPORT void BF_CALLTYPE Breakpoint_MoveMemoryBreakpoint(Breakpoint* breakpoint, intptr addr, int byteCount)
  885. {
  886. gDebugger->MoveMemoryBreakpoint(breakpoint, addr, byteCount);
  887. }
  888. BF_EXPORT void BF_CALLTYPE Breakpoint_Disable(Breakpoint* wdBreakpoint)
  889. {
  890. gDebugger->DisableBreakpoint(wdBreakpoint);
  891. }
  892. BF_EXPORT void BF_CALLTYPE Debugger_CreateStepFilter(const char* filter, bool isGlobal, BfStepFilterKind filterKind)
  893. {
  894. AutoCrit autoCrit(gDebugManager->mCritSect);
  895. StepFilter stepFilter;
  896. stepFilter.mFilterKind = filterKind;
  897. gDebugManager->mStepFilters[filter] = stepFilter;
  898. gDebugManager->mStepFilterVersion++;
  899. }
  900. BF_EXPORT void BF_CALLTYPE StepFilter_Delete(const char* filter)
  901. {
  902. AutoCrit autoCrit(gDebugManager->mCritSect);
  903. bool didRemove = gDebugManager->mStepFilters.Remove(filter);
  904. BF_ASSERT(didRemove);
  905. gDebugManager->mStepFilterVersion++;
  906. }
  907. BF_EXPORT int BF_CALLTYPE Debugger_GetRunState()
  908. {
  909. AutoCrit autoCrit(gDebugManager->mCritSect);
  910. if (gDebugger == NULL)
  911. return RunState_NotStarted;
  912. return gDebugger->mRunState;
  913. }
  914. BF_EXPORT bool BF_CALLTYPE Debugger_HasPendingDebugLoads()
  915. {
  916. if (gDebugger == NULL)
  917. return false;
  918. return gDebugger->HasPendingDebugLoads();
  919. }
  920. BF_EXPORT const char* BF_CALLTYPE Debugger_PopMessage()
  921. {
  922. AutoCrit autoCrit(gDebugManager->mCritSect);
  923. if (gDebugManager->mOutMessages.size() == 0)
  924. return NULL;
  925. String& outString = *gTLStrReturn.Get();
  926. outString = gDebugManager->mOutMessages.front();
  927. gDebugManager->mOutMessages.pop_front();
  928. //gDebugManager->mOutMessages.erase(gDebugManager->mOutMessages.begin());
  929. return outString.c_str();
  930. }
  931. BF_EXPORT bool BF_CALLTYPE Debugger_HasMessages()
  932. {
  933. AutoCrit autoCrit(gDebugManager->mCritSect);
  934. return gDebugManager->mOutMessages.size() != 0;
  935. }
  936. BF_EXPORT const char* BF_CALLTYPE Debugger_GetCurrentException()
  937. {
  938. /*outString = StrFormat("Exception at 0x%p, exception code 0x%08X",
  939. gDebugger->mCurException.ExceptionAddress, gDebugger->mCurException.ExceptionCode);*/
  940. String& outString = *gTLStrReturn.Get();
  941. outString = gDebugger->GetCurrentException();
  942. return outString.c_str();
  943. }
  944. BF_EXPORT void BF_CALLTYPE Debugger_BreakAll()
  945. {
  946. if (gDebugger != NULL)
  947. gDebugger->BreakAll();
  948. }
  949. BF_EXPORT void BF_CALLTYPE Debugger_Continue()
  950. {
  951. BfLogDbg("Debugger_Continue\n");
  952. gDebugger->ContinueDebugEvent();
  953. }
  954. BF_EXPORT void BF_CALLTYPE Debugger_StepInto(bool inAssembly)
  955. {
  956. gDebugger->StepInto(inAssembly);
  957. }
  958. BF_EXPORT void BF_CALLTYPE Debugger_StepIntoSpecific(intptr addr)
  959. {
  960. gDebugger->StepIntoSpecific(addr);
  961. }
  962. BF_EXPORT void BF_CALLTYPE Debugger_StepOver(bool inAssembly)
  963. {
  964. gDebugger->StepOver(inAssembly);
  965. }
  966. BF_EXPORT void BF_CALLTYPE Debugger_StepOut(bool inAssembly)
  967. {
  968. gDebugger->StepOut(inAssembly);
  969. }
  970. BF_EXPORT void BF_CALLTYPE Debugger_SetNextStatement(bool inAssembly, const char* fileName, int64 wantLineNumOrAsmAddr, int wantColumn)
  971. {
  972. if (fileName == NULL)
  973. fileName = "";
  974. gDebugger->SetNextStatement(inAssembly, fileName, wantLineNumOrAsmAddr, wantColumn);
  975. }
  976. BF_EXPORT void BF_CALLTYPE Debugger_Update()
  977. {
  978. if (gDebugger != NULL)
  979. gDebugger->Update();
  980. }
  981. BF_EXPORT void BF_CALLTYPE Debugger_SetDisplayTypes(const char* referenceId, const char* formatStr, int8 intDisplayType, int8 mmDisplayType, int8 floatDisplayType)
  982. {
  983. AutoCrit autoCrit(gDebugManager->mCritSect);
  984. DwDisplayInfo* displayInfo = NULL;
  985. if (referenceId == NULL)
  986. displayInfo = &gDebugManager->mDefaultDisplayInfo;
  987. else
  988. gDebugManager->mDisplayInfos.TryAdd(referenceId, NULL, &displayInfo);
  989. if (formatStr != NULL)
  990. displayInfo->mFormatStr = formatStr;
  991. displayInfo->mIntDisplayType = (DwIntDisplayType)intDisplayType;
  992. displayInfo->mMmDisplayType = (DwMmDisplayType)mmDisplayType;
  993. displayInfo->mFloatDisplayType = (DwFloatDisplayType)floatDisplayType;
  994. if ((referenceId != NULL) &&
  995. (displayInfo->mFormatStr.IsEmpty()) &&
  996. (displayInfo->mIntDisplayType == DwIntDisplayType_Default) &&
  997. (displayInfo->mMmDisplayType == DwMmDisplayType_Default) &&
  998. (displayInfo->mFloatDisplayType == DwFloatDisplayType_Default))
  999. {
  1000. gDebugManager->mDisplayInfos.Remove(referenceId);
  1001. }
  1002. }
  1003. BF_EXPORT const char* BF_CALLTYPE Debugger_GetDisplayTypes(const char* referenceId, int8* intDisplayType, int8* mmDisplayType, int8* floatDisplayType, bool* foundSpecific)
  1004. {
  1005. AutoCrit autoCrit(gDebugManager->mCritSect);
  1006. *foundSpecific = false;
  1007. DwDisplayInfo* displayInfo = &gDebugManager->mDefaultDisplayInfo;
  1008. if (referenceId != NULL)
  1009. {
  1010. /*auto itr = gDebugManager->mDisplayInfos.find(referenceId);
  1011. if (itr != gDebugManager->mDisplayInfos.end())
  1012. {
  1013. displayInfo = &itr->second;
  1014. foundSpecific = true;
  1015. }*/
  1016. if (gDebugManager->mDisplayInfos.TryGetValue(referenceId, &displayInfo))
  1017. {
  1018. *foundSpecific = true;
  1019. }
  1020. }
  1021. *intDisplayType = (int8)displayInfo->mIntDisplayType;
  1022. *mmDisplayType = (int8)displayInfo->mMmDisplayType;
  1023. *floatDisplayType = (int8)displayInfo->mFloatDisplayType;
  1024. return displayInfo->mFormatStr.c_str();
  1025. }
  1026. BF_EXPORT const char* BF_CALLTYPE Debugger_GetDisplayTypeNames()
  1027. {
  1028. AutoCrit autoCrit(gDebugManager->mCritSect);
  1029. String& outString = *gTLStrReturn.Get();
  1030. outString.clear();
  1031. for (auto& displayInfoEntry : gDebugManager->mDisplayInfos)
  1032. {
  1033. outString += displayInfoEntry.mKey + "\n";
  1034. }
  1035. return outString.c_str();
  1036. }
  1037. BF_EXPORT const char* BF_CALLTYPE Debugger_EvaluateContinue()
  1038. {
  1039. auto debugger = gDebugger;
  1040. String& outString = *gTLStrReturn.Get();
  1041. outString = debugger->EvaluateContinue();
  1042. return outString.c_str();
  1043. }
  1044. BF_EXPORT void BF_CALLTYPE Debugger_EvaluateContinueKeep()
  1045. {
  1046. auto debugger = gDebugger;
  1047. debugger->EvaluateContinueKeep();
  1048. }
  1049. BF_EXPORT StringView BF_CALLTYPE Debugger_Evaluate(const char* expr, int callStackIdx, int cursorPos, int32 language, uint16 expressionFlags)
  1050. {
  1051. auto debugger = gDebugger;
  1052. if (debugger == NULL)
  1053. debugger = gDebugManager->mDebugger64;
  1054. String& outString = *gTLStrReturn.Get();
  1055. outString.clear();
  1056. outString = debugger->Evaluate(expr, callStackIdx, cursorPos, language, (DwEvalExpressionFlags)expressionFlags);
  1057. #ifdef BF_WANTS_LOG_DBG
  1058. {
  1059. int crPos = (int)outString.IndexOf('\n');
  1060. if (crPos != -1)
  1061. BfLogDbg("Debugger_Evaluate Result=%s\n", outString.Substring(0, crPos).c_str());
  1062. else
  1063. BfLogDbg("Debugger_Evaluate Result=%s\n", outString.c_str());
  1064. }
  1065. #endif
  1066. return outString;
  1067. }
  1068. BF_EXPORT const char* BF_CALLTYPE Debugger_EvaluateToAddress(const char* expr, int callStackIdx, int cursorPos)
  1069. {
  1070. String& outString = *gTLStrReturn.Get();
  1071. outString.clear();
  1072. if (gDebugger != NULL)
  1073. outString = gDebugger->EvaluateToAddress(expr, callStackIdx, cursorPos);
  1074. return outString.c_str();
  1075. }
  1076. BF_EXPORT const char* BF_CALLTYPE Debugger_EvaluateAtAddress(const char* expr, intptr atAddr, int cursorPos)
  1077. {
  1078. String& outString = *gTLStrReturn.Get();
  1079. outString.clear();
  1080. if (gDebugger != NULL)
  1081. outString = gDebugger->EvaluateAtAddress(expr, atAddr, cursorPos);
  1082. return outString.c_str();
  1083. }
  1084. BF_EXPORT const char* BF_CALLTYPE Debugger_GetAutoExpressions(int callStackIdx, uint64 memoryRangeStart, uint64 memoryRangeLen)
  1085. {
  1086. String& outString = *gTLStrReturn.Get();
  1087. outString = gDebugger->GetAutoExpressions(callStackIdx, memoryRangeStart, memoryRangeLen);
  1088. return outString.c_str();
  1089. }
  1090. BF_EXPORT const char* BF_CALLTYPE Debugger_GetAutoLocals(int callStackIdx, bool showRegs)
  1091. {
  1092. String& outString = *gTLStrReturn.Get();
  1093. outString = gDebugger->GetAutoLocals(callStackIdx, showRegs);
  1094. return outString.c_str();
  1095. }
  1096. BF_EXPORT const char* BF_CALLTYPE Debugger_CompactChildExpression(const char* expr, const char* parentExpr, int callStackIdx)
  1097. {
  1098. String& outString = *gTLStrReturn.Get();
  1099. outString = gDebugger->CompactChildExpression(expr, parentExpr, callStackIdx);
  1100. return outString.c_str();
  1101. }
  1102. BF_EXPORT const char* BF_CALLTYPE Debugger_GetCollectionContinuation(const char* continuationData, int callStackIdx, int count)
  1103. {
  1104. String& outString = *gTLStrReturn.Get();
  1105. outString = gDebugger->GetCollectionContinuation(continuationData, callStackIdx, count);
  1106. return outString.c_str();
  1107. }
  1108. BF_EXPORT void BF_CALLTYPE Debugger_ForegroundTarget()
  1109. {
  1110. gDebugger->ForegroundTarget();
  1111. //BOOL worked = EnumThreadWindows(gDebugger->mProcessInfo.dwThreadId, WdEnumWindowsProc, 0);
  1112. //BF_ASSERT(worked);
  1113. }
  1114. BF_EXPORT const char* BF_CALLTYPE Debugger_GetProcessInfo()
  1115. {
  1116. String& outString = *gTLStrReturn.Get();
  1117. outString = gDebugger->GetProcessInfo();
  1118. return outString.c_str();
  1119. }
  1120. BF_EXPORT const char* BF_CALLTYPE Debugger_GetThreadInfo()
  1121. {
  1122. String& outString = *gTLStrReturn.Get();
  1123. outString = gDebugger->GetThreadInfo();
  1124. return outString.c_str();
  1125. }
  1126. BF_EXPORT void BF_CALLTYPE Debugger_SetActiveThread(int threadId)
  1127. {
  1128. gDebugger->SetActiveThread(threadId);
  1129. }
  1130. BF_EXPORT int BF_CALLTYPE Debugger_GetActiveThread()
  1131. {
  1132. return gDebugger->GetActiveThread();
  1133. }
  1134. BF_EXPORT void BF_CALLTYPE Debugger_FreezeThread(int threadId)
  1135. {
  1136. gDebugger->FreezeThread(threadId);
  1137. }
  1138. BF_EXPORT void BF_CALLTYPE Debugger_ThawThread(int threadId)
  1139. {
  1140. gDebugger->ThawThread(threadId);
  1141. }
  1142. BF_EXPORT bool BF_CALLTYPE Debugger_IsActiveThreadWaiting()
  1143. {
  1144. return gDebugger->IsActiveThreadWaiting();
  1145. }
  1146. BF_EXPORT void BF_CALLTYPE CallStack_Update()
  1147. {
  1148. gDebugger->UpdateCallStack();
  1149. }
  1150. BF_EXPORT void BF_CALLTYPE CallStack_Rehup()
  1151. {
  1152. AutoCrit autoCrit(gDebugManager->mCritSect);
  1153. gDebugger->ClearCallStack();
  1154. }
  1155. BF_EXPORT int BF_CALLTYPE CallStack_GetCount()
  1156. {
  1157. return gDebugger->GetCallStackCount();
  1158. }
  1159. BF_EXPORT int BF_CALLTYPE CallStack_GetRequestedStackFrameIdx()
  1160. {
  1161. return gDebugger->GetRequestedStackFrameIdx();
  1162. }
  1163. BF_EXPORT int BF_CALLTYPE CallStack_GetBreakStackFrameIdx()
  1164. {
  1165. return gDebugger->GetBreakStackFrameIdx();
  1166. }
  1167. BF_EXPORT const char* BF_CALLTYPE CallStack_GetStackFrameInfo(int stackFrameIdx, intptr* addr, const char** outFile, int32* outHotIdx, int32* outDefLineStart, int32* outDefLineEnd,
  1168. int32* outLine, int32* outColumn, int32* outLanguage, int32* outStackSize, int8* outFlags)
  1169. {
  1170. String& outString = *gTLStrReturn.Get();
  1171. String& outString2 = *gTLStrReturn2.Get();
  1172. outString = gDebugger->GetStackFrameInfo(stackFrameIdx, addr, &outString2, outHotIdx, outDefLineStart, outDefLineEnd, outLine, outColumn, outLanguage, outStackSize, outFlags);
  1173. *outFile = outString2.c_str();
  1174. return outString.c_str();
  1175. }
  1176. BF_EXPORT const char* BF_CALLTYPE CallStack_GetStackFrameId(int stackFrameIdx)
  1177. {
  1178. String& outString = *gTLStrReturn.Get();
  1179. outString = gDebugger->GetStackFrameId(stackFrameIdx);
  1180. return outString.c_str();
  1181. }
  1182. BF_EXPORT const char* BF_CALLTYPE Callstack_GetStackFrameOldFileInfo(int stackFrameIdx)
  1183. {
  1184. String& outString = *gTLStrReturn.Get();
  1185. outString = gDebugger->Callstack_GetStackFrameOldFileInfo(stackFrameIdx);
  1186. return outString.c_str();
  1187. }
  1188. // -1 = no jump, 0 = won't jump, 1 = will jump
  1189. BF_EXPORT int BF_CALLTYPE CallStack_GetJmpState(int stackFrameIdx)
  1190. {
  1191. return gDebugger->GetJmpState(stackFrameIdx);
  1192. }
  1193. BF_EXPORT intptr BF_CALLTYPE Debugger_GetStackFrameCalleeAddr(int stackFrameIdx)
  1194. {
  1195. return gDebugger->GetStackFrameCalleeAddr(stackFrameIdx);
  1196. }
  1197. BF_EXPORT const char* BF_CALLTYPE Debugger_GetCodeAddrInfo(intptr addr, intptr inlineCallAddr, int* outHotIdx, int* outDefLineStart, int* outDefLineEnd, int* outLine, int* outColumn)
  1198. {
  1199. String& outString = *gTLStrReturn.Get();
  1200. outString.clear();
  1201. gDebugger->GetCodeAddrInfo(addr, inlineCallAddr, &outString, outHotIdx, outDefLineStart, outDefLineEnd, outLine, outColumn);
  1202. return outString.c_str();
  1203. }
  1204. BF_EXPORT void BF_CALLTYPE Debugger_GetStackAllocInfo(intptr addr, int* outThreadId, int* outStackIdx)
  1205. {
  1206. gDebugger->GetStackAllocInfo(addr, outThreadId, outStackIdx);
  1207. }
  1208. BF_EXPORT const char* BF_CALLTYPE CallStack_GetStackMethodOwner(int stackFrameIdx, int& language)
  1209. {
  1210. String& outString = *gTLStrReturn.Get();
  1211. outString = gDebugger->GetStackMethodOwner(stackFrameIdx, language);
  1212. return outString.c_str();
  1213. }
  1214. BF_EXPORT const char* BF_CALLTYPE Debugger_FindCodeAddresses(const char* fileName, int line, int column, bool allowAutoResolve)
  1215. {
  1216. String& outString = *gTLStrReturn.Get();
  1217. outString = gDebugger->FindCodeAddresses(fileName, line, column, allowAutoResolve);
  1218. return outString.c_str();
  1219. }
  1220. BF_EXPORT const char* BF_CALLTYPE Debugger_GetAddressSourceLocation(intptr address)
  1221. {
  1222. String& outString = *gTLStrReturn.Get();
  1223. if (gDebugger != NULL)
  1224. outString = gDebugger->GetAddressSourceLocation(address);
  1225. else
  1226. outString = "";
  1227. return outString.c_str();
  1228. }
  1229. BF_EXPORT const char* BF_CALLTYPE Debugger_GetAddressSymbolName(intptr address, bool demangle)
  1230. {
  1231. String& outString = *gTLStrReturn.Get();
  1232. if (gDebugger != NULL)
  1233. outString = gDebugger->GetAddressSymbolName(address, demangle);
  1234. else
  1235. outString = "";
  1236. return outString.c_str();
  1237. }
  1238. BF_EXPORT const char* BF_CALLTYPE Debugger_FindLineCallAddresses(intptr address)
  1239. {
  1240. String& outString = *gTLStrReturn.Get();
  1241. outString = gDebugger->FindLineCallAddresses(address);
  1242. return outString.c_str();
  1243. }
  1244. BF_EXPORT const char* BF_CALLTYPE Debugger_DisassembleAt(intptr address)
  1245. {
  1246. String& outString = *gTLStrReturn.Get();
  1247. outString = gDebugger->DisassembleAt(address);
  1248. return outString.c_str();
  1249. }
  1250. BF_EXPORT void BF_CALLTYPE Debugger_ReadMemory(uintptr address, uintptr size, unsigned char* data)
  1251. {
  1252. if (gDebugger == NULL)
  1253. return;
  1254. gDebugger->ReadMemory(address, size, data);
  1255. }
  1256. BF_EXPORT void BF_CALLTYPE Debugger_WriteMemory(uintptr address, uintptr size, unsigned char* data)
  1257. {
  1258. if (gDebugger == NULL)
  1259. return;
  1260. gDebugger->WriteMemory(address, data, size);
  1261. }
  1262. BF_EXPORT const char* BF_CALLTYPE Debugger_GetModulesInfo()
  1263. {
  1264. String& outString = *gTLStrReturn.Get();
  1265. outString = gDebugger->GetModulesInfo();
  1266. return outString.c_str();
  1267. }
  1268. BF_EXPORT void BF_CALLTYPE Debugger_CancelSymSrv()
  1269. {
  1270. gDebugger->CancelSymSrv();
  1271. }
  1272. BF_EXPORT int BF_CALLTYPE Debugger_LoadImageForModuleWith(const char* moduleName, const char* debugFilePath) // 0 = No Change, 1 = Loaded, 2 = Loading in background
  1273. {
  1274. return gDebugger->LoadImageForModule(moduleName, debugFilePath);
  1275. }
  1276. BF_EXPORT int BF_CALLTYPE Debugger_LoadDebugInfoForModule(const char* moduleName) // 0 = No Change, 1 = Loaded, 2 = Loading in background
  1277. {
  1278. return gDebugger->LoadDebugInfoForModule(moduleName);
  1279. }
  1280. BF_EXPORT int BF_CALLTYPE Debugger_LoadDebugInfoForModuleWith(const char* moduleName, const char* debugFilePath) // 0 = No Change, 1 = Loaded, 2 = Loading in background
  1281. {
  1282. return gDebugger->LoadDebugInfoForModule(moduleName, debugFilePath);
  1283. }
  1284. BF_EXPORT void BF_CALLTYPE Debugger_SetStepOverExternalFiles(bool stepOverExternalFiles)
  1285. {
  1286. gDebugManager->mStepOverExternalFiles = stepOverExternalFiles;
  1287. gDebugManager->mStepFilterVersion++;
  1288. }
  1289. BF_EXPORT void BF_CALLTYPE BfLog_Log(char* str)
  1290. {
  1291. BfLog(str);
  1292. }
  1293. BF_EXPORT void BF_CALLTYPE BfLog_LogDbg(char* str)
  1294. {
  1295. BfLogDbg(str);
  1296. }
  1297. BF_EXPORT Profiler* BF_CALLTYPE Debugger_StartProfiling(intptr threadId, char* desc, int sampleRate)
  1298. {
  1299. BF_ASSERT(sampleRate > 0);
  1300. Profiler* profiler = gDebugger->StartProfiling();
  1301. profiler->mTargetThreadId = threadId;
  1302. if (desc != NULL)
  1303. profiler->mDescription = desc;
  1304. profiler->mSamplesPerSecond = sampleRate;
  1305. profiler->Start();
  1306. return profiler;
  1307. }
  1308. BF_EXPORT Profiler* BF_CALLTYPE Debugger_PopProfiler()
  1309. {
  1310. Profiler* profiler = gDebugger->PopProfiler();
  1311. return profiler;
  1312. }
  1313. BF_EXPORT void BF_CALLTYPE Debugger_InitiateHotResolve(int flags)
  1314. {
  1315. if (gDebugger != NULL)
  1316. gDebugger->InitiateHotResolve((DbgHotResolveFlags)flags);
  1317. }
  1318. BF_EXPORT intptr BF_CALLTYPE Debugger_GetDbgAllocHeapSize()
  1319. {
  1320. AutoCrit autoCrit(gDebugManager->mCritSect);
  1321. return gDebugger->GetDbgAllocHeapSize();
  1322. }
  1323. BF_EXPORT const char* BF_CALLTYPE Debugger_GetDbgAllocInfo()
  1324. {
  1325. AutoCrit autoCrit(gDebugManager->mCritSect);
  1326. String& outString = *gTLStrReturn.Get();
  1327. outString = gDebugger->GetDbgAllocInfo();
  1328. return outString.c_str();
  1329. }
  1330. BF_EXPORT const char* BF_CALLTYPE Debugger_GetHotResolveData(uint8* outTypeData, int* outTypeDataSize)
  1331. {
  1332. AutoCrit autoCrit(gDebugManager->mCritSect);
  1333. if (gDebugger->mHotResolveData == NULL)
  1334. {
  1335. *outTypeDataSize = -1;
  1336. return NULL;
  1337. }
  1338. int dataSize = (int)gDebugger->mHotResolveData->mTypeData.size();
  1339. if (*outTypeDataSize < dataSize)
  1340. {
  1341. *outTypeDataSize = dataSize;
  1342. return NULL;
  1343. }
  1344. *outTypeDataSize = dataSize;
  1345. if (dataSize > 0)
  1346. {
  1347. for (int i = 0; i < dataSize; i++)
  1348. outTypeData[i] = (gDebugger->mHotResolveData->mTypeData[i].mCount > 0) ? 1 : 0;
  1349. }
  1350. String& outString = *gTLStrReturn.Get();
  1351. outString.Clear();
  1352. for (auto& str : gDebugger->mHotResolveData->mBeefCallStackEntries)
  1353. {
  1354. if (!outString.IsEmpty())
  1355. outString += "\n";
  1356. outString += str;
  1357. }
  1358. return outString.c_str();
  1359. }
  1360. BF_EXPORT const char* BF_CALLTYPE Debugger_GetEmitSource(char* inFilePath)
  1361. {
  1362. AutoCrit autoCrit(gDebugManager->mCritSect);
  1363. String& outString = *gTLStrReturn.Get();
  1364. outString.Clear();
  1365. if (!gDebugger->GetEmitSource(inFilePath, outString))
  1366. return NULL;
  1367. return outString.c_str();
  1368. }
  1369. BF_EXPORT NetResult* HTTP_GetFile(char* url, char* destPath)
  1370. {
  1371. AutoCrit autoCrit(gDebugManager->mNetManager->mThreadPool.mCritSect);
  1372. auto netResult = gDebugManager->mNetManager->QueueGet(url, destPath, false);
  1373. netResult->mDoneEvent = new SyncEvent();
  1374. return netResult;
  1375. }
  1376. BF_EXPORT int HTTP_GetResult(NetResult* netResult, int waitMS)
  1377. {
  1378. if (netResult->mDoneEvent->WaitFor(waitMS))
  1379. {
  1380. return netResult->mFailed ? 0 : 1;
  1381. }
  1382. else
  1383. {
  1384. return -1;
  1385. }
  1386. }
  1387. BF_EXPORT void HTTP_GetLastError(NetResult* netResult, const char** error, int* errorLength)
  1388. {
  1389. *error = netResult->mError.GetPtr();
  1390. *errorLength = netResult->mError.GetLength();
  1391. }
  1392. BF_EXPORT void HTTP_Delete(NetResult* netResult)
  1393. {
  1394. if (!netResult->mDoneEvent->WaitFor(0))
  1395. {
  1396. ///
  1397. {
  1398. AutoCrit autoCrit(gDebugManager->mNetManager->mThreadPool.mCritSect);
  1399. if (netResult->mCurRequest != NULL)
  1400. netResult->mCurRequest->Cancel();
  1401. }
  1402. netResult->mDoneEvent->WaitFor(-1);
  1403. }
  1404. delete netResult;
  1405. }
  1406. BF_EXPORT void Debugger_SetAliasPath(char* origPath, char* localPath)
  1407. {
  1408. gDebugger->SetAliasPath(origPath, localPath);
  1409. }
  1410. ///
  1411. BF_EXPORT bool BF_CALLTYPE Profiler_IsRunning(Profiler* profiler)
  1412. {
  1413. return profiler->IsSampling();
  1414. }
  1415. BF_EXPORT void BF_CALLTYPE Profiler_Stop(Profiler* profiler)
  1416. {
  1417. profiler->Stop();
  1418. }
  1419. BF_EXPORT void BF_CALLTYPE Profiler_Clear(Profiler* profiler)
  1420. {
  1421. profiler->Clear();
  1422. }
  1423. BF_EXPORT const char* BF_CALLTYPE Profiler_GetOverview(Profiler* profiler)
  1424. {
  1425. String& outString = *gTLStrReturn.Get();
  1426. outString = profiler->GetOverview();
  1427. return outString.c_str();
  1428. }
  1429. BF_EXPORT const char* BF_CALLTYPE Profiler_GetThreadList(Profiler* profiler)
  1430. {
  1431. String& outString = *gTLStrReturn.Get();
  1432. outString = profiler->GetThreadList();
  1433. return outString.c_str();
  1434. }
  1435. BF_EXPORT const char* BF_CALLTYPE Profiler_GetCallTree(Profiler* profiler, int threadId, bool reverse)
  1436. {
  1437. String& outString = *gTLStrReturn.Get();
  1438. outString = profiler->GetCallTree(threadId, reverse);
  1439. return outString.c_str();
  1440. }
  1441. BF_EXPORT void BF_CALLTYPE Profiler_Delete(Profiler* profiler)
  1442. {
  1443. int z = 0;
  1444. delete profiler;
  1445. }
  1446. BF_TLS_DECLSPEC static int gTLSValue = 3;
  1447. BF_EXPORT void BF_CALLTYPE TimeTest(uint32 startTime)
  1448. {
  1449. gTLSValue++;
  1450. int elapsedTime = BFTickCount() - startTime;
  1451. OutputDebugStrF("Load Time: %d\n", elapsedTime);
  1452. }
  1453. BF_EXPORT void BF_CALLTYPE BFTest()
  1454. {
  1455. struct DeferredResolveEntry2
  1456. {
  1457. BfFieldDef* mFieldDef;
  1458. int mTypeArrayIdx;
  1459. };
  1460. DeferredResolveEntry2 entry = { NULL, 333 };
  1461. llvm::SmallVector<DeferredResolveEntry2, 8> vec;
  1462. vec.push_back(DeferredResolveEntry2 { NULL, 111 } );
  1463. vec.push_back(DeferredResolveEntry2 { NULL, 222 } );
  1464. }
  1465. ///
  1466. // __attribute__((weak))
  1467. // Debugger* Beefy::CreateDebugger32(DebugManager* debugManager, DbgMiniDump* miniDump)
  1468. // {
  1469. // return NULL;
  1470. // }