DebugManager.cpp 43 KB

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