memento.c 85 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131
  1. /* Copyright (C) 2001-2023 Artifex Software, Inc.
  2. All Rights Reserved.
  3. This software is provided AS-IS with no warranty, either express or
  4. implied.
  5. This software is distributed under license and may not be copied,
  6. modified or distributed except as expressly authorized under the terms
  7. of the license contained in the file LICENSE in this distribution.
  8. Refer to licensing information at http://www.artifex.com or contact
  9. Artifex Software, Inc., 39 Mesa Street, Suite 108A, San Francisco,
  10. CA 94129, USA, for further information.
  11. */
  12. /* Inspired by Fortify by Simon P Bullen. */
  13. /* Set the following if you're only looking for leaks, not memory overwrites
  14. * to speed the operation */
  15. /* #define MEMENTO_LEAKONLY */
  16. /* Set the following to keep extra details about the history of blocks */
  17. #define MEMENTO_DETAILS
  18. /* Don't keep blocks around if they'd mean losing more than a quarter of
  19. * the freelist. */
  20. #define MEMENTO_FREELIST_MAX_SINGLE_BLOCK (MEMENTO_FREELIST_MAX/4)
  21. #define COMPILING_MEMENTO_C
  22. /* SHUT UP, MSVC. I KNOW WHAT I AM DOING. */
  23. #define _CRT_SECURE_NO_WARNINGS
  24. /* We have some GS specific tweaks; more for the GS build environment than
  25. * anything else. */
  26. /* #define MEMENTO_GS_HACKS */
  27. #ifdef MEMENTO_GS_HACKS
  28. /* For GS we include malloc_.h. Anyone else would just include memento.h */
  29. #include "malloc_.h"
  30. #include "memory_.h"
  31. int atexit(void (*)(void));
  32. #else
  33. #include "memento.h"
  34. #include <stdio.h>
  35. #endif
  36. #ifndef _MSC_VER
  37. #include <stdint.h>
  38. #include <limits.h>
  39. #include <unistd.h>
  40. #endif
  41. #include <stdlib.h>
  42. #include <stdarg.h>
  43. #include <string.h>
  44. #ifdef __ANDROID__
  45. #define MEMENTO_ANDROID
  46. #include <stdio.h>
  47. #endif
  48. /* Hacks to portably print large sizes */
  49. #ifdef _MSC_VER
  50. #define FMTZ "%llu"
  51. #define FMTZ_CAST _int64
  52. #define FMTP "0x%p"
  53. #else
  54. #define FMTZ "%zu"
  55. #define FMTZ_CAST size_t
  56. #define FMTP "%p"
  57. #endif
  58. #define UB(x) ((intptr_t)((x) & 0xFF))
  59. #define B2I(x) (UB(x) | (UB(x)<<8) | (UB(x)<<16) | (UB(x)<<24))
  60. #define B2P(x) ((void *)(B2I(x) | ((B2I(x)<<16)<<16)))
  61. #define MEMENTO_PREFILL_UBYTE ((unsigned char)(MEMENTO_PREFILL))
  62. #define MEMENTO_PREFILL_USHORT (((unsigned short)MEMENTO_PREFILL_UBYTE) | (((unsigned short)MEMENTO_PREFILL_UBYTE)<<8))
  63. #define MEMENTO_PREFILL_UINT (((unsigned int)MEMENTO_PREFILL_USHORT) | (((unsigned int)MEMENTO_PREFILL_USHORT)<<16))
  64. #define MEMENTO_PREFILL_PTR (void *)(((uintptr_t)MEMENTO_PREFILL_UINT) | ((((uintptr_t)MEMENTO_PREFILL_UINT)<<16)<<16))
  65. #define MEMENTO_POSTFILL_UBYTE ((unsigned char)(MEMENTO_POSTFILL))
  66. #define MEMENTO_POSTFILL_USHORT (((unsigned short)MEMENTO_POSTFILL_UBYTE) | (((unsigned short)MEMENTO_POSTFILL_UBYTE)<<8))
  67. #define MEMENTO_POSTFILL_UINT (((unsigned int)MEMENTO_POSTFILL_USHORT) | (((unsigned int)MEMENTO_POSTFILL_USHORT)<<16))
  68. #define MEMENTO_POSTFILL_PTR (void *)(((uintptr_t)MEMENTO_POSTFILL_UINT) | ((((uintptr_t)MEMENTO_POSTFILL_UINT)<<16)<<16))
  69. #define MEMENTO_ALLOCFILL_UBYTE ((unsigned char)(MEMENTO_ALLOCFILL))
  70. #define MEMENTO_ALLOCFILL_USHORT (((unsigned short)MEMENTO_ALLOCFILL_UBYTE) | (((unsigned short)MEMENTO_ALLOCFILL_UBYTE)<<8))
  71. #define MEMENTO_ALLOCFILL_UINT (((unsigned int)MEMENTO_ALLOCFILL_USHORT) | (((unsigned int)MEMENTO_ALLOCFILL_USHORT)<<16))
  72. #define MEMENTO_ALLOCFILL_PTR (void *)(((uintptr_t)MEMENTO_ALLOCFILL_UINT) | ((((uintptr_t)MEMENTO_ALLOCFILL_UINT)<<16)<<16))
  73. #define MEMENTO_FREEFILL_UBYTE ((unsigned char)(MEMENTO_FREEFILL))
  74. #define MEMENTO_FREEFILL_USHORT (((unsigned short)MEMENTO_FREEFILL_UBYTE) | (((unsigned short)MEMENTO_FREEFILL_UBYTE)<<8))
  75. #define MEMENTO_FREEFILL_UINT (((unsigned int)MEMENTO_FREEFILL_USHORT) | (((unsigned int)MEMENTO_FREEFILL_USHORT)<<16))
  76. #define MEMENTO_FREEFILL_PTR (void *)(((uintptr_t)MEMENTO_FREEFILL_UINT) | ((((uintptr_t)MEMENTO_FREEFILL_UINT)<<16)<<16))
  77. #ifdef MEMENTO
  78. #ifndef MEMENTO_CPP_EXTRAS_ONLY
  79. #ifdef MEMENTO_ANDROID
  80. #include <android/log.h>
  81. static char log_buffer[4096];
  82. static int log_fill = 0;
  83. static char log_buffer2[4096];
  84. static int
  85. android_fprintf(FILE *file, const char *fmt, ...)
  86. {
  87. va_list args;
  88. char *p, *q;
  89. va_start(args, fmt);
  90. vsnprintf(log_buffer2, sizeof(log_buffer2)-1, fmt, args);
  91. va_end(args);
  92. /* Ensure we are always null terminated */
  93. log_buffer2[sizeof(log_buffer2)-1] = 0;
  94. p = log_buffer2;
  95. q = p;
  96. do
  97. {
  98. /* Find the end of the string, or the next \n */
  99. while (*p && *p != '\n')
  100. p++;
  101. /* We need to output from q to p. Limit ourselves to what
  102. * will fit in the existing */
  103. if (p - q >= sizeof(log_buffer)-1 - log_fill)
  104. p = q + sizeof(log_buffer)-1 - log_fill;
  105. memcpy(&log_buffer[log_fill], q, p-q);
  106. log_fill += p-q;
  107. if (*p == '\n')
  108. {
  109. log_buffer[log_fill] = 0;
  110. __android_log_print(ANDROID_LOG_ERROR, "memento", "%s", log_buffer);
  111. usleep(1);
  112. log_fill = 0;
  113. p++; /* Skip over the \n */
  114. }
  115. else if (log_fill >= sizeof(log_buffer)-1)
  116. {
  117. log_buffer[sizeof(log_buffer2)-1] = 0;
  118. __android_log_print(ANDROID_LOG_ERROR, "memento", "%s", log_buffer);
  119. usleep(1);
  120. log_fill = 0;
  121. }
  122. q = p;
  123. }
  124. while (*p);
  125. return 0;
  126. }
  127. #define fprintf android_fprintf
  128. #define MEMENTO_STACKTRACE_METHOD 3
  129. #endif
  130. /* _WIN64 defined implies _WIN32 will be */
  131. #ifdef _WIN32
  132. #include <windows.h>
  133. static int
  134. windows_fprintf(FILE *file, const char *fmt, ...)
  135. {
  136. va_list args;
  137. char text[4096];
  138. int ret;
  139. va_start(args, fmt);
  140. ret = vfprintf(file, fmt, args);
  141. va_end(args);
  142. va_start(args, fmt);
  143. vsnprintf(text, 4096, fmt, args);
  144. OutputDebugStringA(text);
  145. va_end(args);
  146. return ret;
  147. }
  148. #define fprintf windows_fprintf
  149. #endif
  150. #ifndef MEMENTO_STACKTRACE_METHOD
  151. #ifdef __GNUC__
  152. #define MEMENTO_STACKTRACE_METHOD 1
  153. #endif
  154. #ifdef _WIN32
  155. #define MEMENTO_STACKTRACE_METHOD 2
  156. #endif
  157. #endif
  158. #if defined(__linux__)
  159. #define MEMENTO_HAS_FORK
  160. #elif defined(__APPLE__) && defined(__MACH__)
  161. #define MEMENTO_HAS_FORK
  162. #endif
  163. /* Define the underlying allocators, just in case */
  164. void *MEMENTO_UNDERLYING_MALLOC(size_t);
  165. void MEMENTO_UNDERLYING_FREE(void *);
  166. void *MEMENTO_UNDERLYING_REALLOC(void *,size_t);
  167. void *MEMENTO_UNDERLYING_CALLOC(size_t,size_t);
  168. /* And some other standard functions we use. We don't include the header
  169. * files, just in case they pull in unexpected others. */
  170. int atoi(const char *);
  171. char *getenv(const char *);
  172. /* How far to search for pointers in each block when calculating nestings */
  173. /* mupdf needs at least 34000ish (sizeof(fz_shade))/ */
  174. #define MEMENTO_PTRSEARCH 65536
  175. #ifndef MEMENTO_MAXPATTERN
  176. #define MEMENTO_MAXPATTERN 0
  177. #endif
  178. #ifdef MEMENTO_GS_HACKS
  179. #include "valgrind.h"
  180. #else
  181. #ifdef HAVE_VALGRIND
  182. #include "valgrind/memcheck.h"
  183. #else
  184. #define VALGRIND_MAKE_MEM_NOACCESS(p,s) do { } while (0==1)
  185. #define VALGRIND_MAKE_MEM_UNDEFINED(p,s) do { } while (0==1)
  186. #define VALGRIND_MAKE_MEM_DEFINED(p,s) do { } while (0==1)
  187. #endif
  188. #endif
  189. enum {
  190. Memento_PreSize = 16,
  191. Memento_PostSize = 16
  192. };
  193. /* Some compile time checks */
  194. typedef struct
  195. {
  196. char MEMENTO_PRESIZE_MUST_BE_A_MULTIPLE_OF_4[Memento_PreSize & 3 ? -1 : 1];
  197. char MEMENTO_POSTSIZE_MUST_BE_A_MULTIPLE_OF_4[Memento_PostSize & 3 ? -1 : 1];
  198. char MEMENTO_POSTSIZE_MUST_BE_AT_LEAST_4[Memento_PostSize >= 4 ? 1 : -1];
  199. char MEMENTO_PRESIZE_MUST_BE_AT_LEAST_4[Memento_PreSize >= 4 ? 1 : -1];
  200. } MEMENTO_SANITY_CHECK_STRUCT;
  201. #define MEMENTO_UINT32 unsigned int
  202. #define MEMENTO_UINT16 unsigned short
  203. #define MEMENTO_PREFILL_UINT32 ((MEMENTO_UINT32)(MEMENTO_PREFILL | (MEMENTO_PREFILL <<8) | (MEMENTO_PREFILL <<16) |(MEMENTO_PREFILL <<24)))
  204. #define MEMENTO_POSTFILL_UINT16 ((MEMENTO_UINT16)(MEMENTO_POSTFILL | (MEMENTO_POSTFILL<<8)))
  205. #define MEMENTO_POSTFILL_UINT32 ((MEMENTO_UINT32)(MEMENTO_POSTFILL | (MEMENTO_POSTFILL<<8) | (MEMENTO_POSTFILL<<16) |(MEMENTO_POSTFILL<<24)))
  206. #define MEMENTO_FREEFILL_UINT16 ((MEMENTO_UINT16)(MEMENTO_FREEFILL | (MEMENTO_FREEFILL<<8)))
  207. #define MEMENTO_FREEFILL_UINT32 ((MEMENTO_UINT32)(MEMENTO_FREEFILL | (MEMENTO_FREEFILL<<8) | (MEMENTO_FREEFILL<<16) |(MEMENTO_FREEFILL<<24)))
  208. enum {
  209. Memento_Flag_OldBlock = 1,
  210. Memento_Flag_HasParent = 2,
  211. Memento_Flag_BreakOnFree = 4,
  212. Memento_Flag_BreakOnRealloc = 8,
  213. Memento_Flag_Freed = 16,
  214. Memento_Flag_KnownLeak = 32,
  215. Memento_Flag_Reported = 64
  216. };
  217. enum {
  218. Memento_EventType_malloc = 0,
  219. Memento_EventType_calloc = 1,
  220. Memento_EventType_realloc = 2,
  221. Memento_EventType_free = 3,
  222. Memento_EventType_new = 4,
  223. Memento_EventType_delete = 5,
  224. Memento_EventType_newArray = 6,
  225. Memento_EventType_deleteArray = 7,
  226. Memento_EventType_takeRef = 8,
  227. Memento_EventType_dropRef = 9,
  228. Memento_EventType_reference = 10
  229. };
  230. static const char *eventType[] =
  231. {
  232. "malloc",
  233. "calloc",
  234. "realloc",
  235. "free",
  236. "new",
  237. "delete",
  238. "new[]",
  239. "delete[]",
  240. "takeRef",
  241. "dropRef",
  242. "reference"
  243. };
  244. /* When we list leaked blocks at the end of execution, we search for pointers
  245. * between blocks in order to be able to give a nice nested view.
  246. * Unfortunately, if you have are running your own allocator (such as
  247. * postscript's chunk allocator) you can often find that the header of the
  248. * block always contains pointers to next or previous blocks. This tends to
  249. * mean the nesting displayed is "uninteresting" at best :)
  250. *
  251. * As a hack to get around this, we have a define MEMENTO_SKIP_SEARCH that
  252. * indicates how many bytes to skip over at the start of the chunk.
  253. * This may cause us to miss true nestings, but such is life...
  254. */
  255. #ifndef MEMENTO_SEARCH_SKIP
  256. #ifdef MEMENTO_GS_HACKS
  257. #define MEMENTO_SEARCH_SKIP (2*sizeof(void *))
  258. #else
  259. #define MEMENTO_SEARCH_SKIP 0
  260. #endif
  261. #endif
  262. #define MEMENTO_CHILD_MAGIC ((Memento_BlkHeader *)('M' | ('3' << 8) | ('m' << 16) | ('3' << 24)))
  263. #define MEMENTO_SIBLING_MAGIC ((Memento_BlkHeader *)('n' | ('t' << 8) | ('0' << 16) | ('!' << 24)))
  264. #ifdef MEMENTO_DETAILS
  265. typedef struct Memento_BlkDetails Memento_BlkDetails;
  266. struct Memento_BlkDetails
  267. {
  268. Memento_BlkDetails *next;
  269. char type;
  270. char count;
  271. int sequence;
  272. void *stack[1];
  273. };
  274. #endif /* MEMENTO_DETAILS */
  275. typedef struct Memento_BlkHeader Memento_BlkHeader;
  276. struct Memento_BlkHeader
  277. {
  278. size_t rawsize;
  279. int sequence;
  280. int lastCheckedOK;
  281. int flags;
  282. Memento_BlkHeader *next;
  283. Memento_BlkHeader *prev; /* Reused as 'parent' when printing nested list */
  284. const char *label;
  285. /* Entries for nesting display calculations. Set to magic
  286. * values at all other time. */
  287. Memento_BlkHeader *child;
  288. Memento_BlkHeader *sibling;
  289. #ifdef MEMENTO_DETAILS
  290. Memento_BlkDetails *details;
  291. Memento_BlkDetails **details_tail;
  292. #endif
  293. char preblk[Memento_PreSize];
  294. };
  295. /* In future this could (should) be a smarter data structure, like, say,
  296. * splay trees. For now, we use a list.
  297. */
  298. typedef struct Memento_Blocks
  299. {
  300. Memento_BlkHeader *head;
  301. Memento_BlkHeader *tail;
  302. } Memento_Blocks;
  303. /* What sort of Mutex should we use? */
  304. #ifdef MEMENTO_LOCKLESS
  305. typedef int Memento_mutex;
  306. static void Memento_initMutex(Memento_mutex *m)
  307. {
  308. (void)m;
  309. }
  310. #define MEMENTO_DO_LOCK() do { } while (0)
  311. #define MEMENTO_DO_UNLOCK() do { } while (0)
  312. #else
  313. #if defined(_WIN32) || defined(_WIN64)
  314. /* Windows */
  315. typedef CRITICAL_SECTION Memento_mutex;
  316. static void Memento_initMutex(Memento_mutex *m)
  317. {
  318. InitializeCriticalSection(m);
  319. }
  320. #define MEMENTO_DO_LOCK() \
  321. EnterCriticalSection(&memento.mutex)
  322. #define MEMENTO_DO_UNLOCK() \
  323. LeaveCriticalSection(&memento.mutex)
  324. #else
  325. #include <pthread.h>
  326. typedef pthread_mutex_t Memento_mutex;
  327. static void Memento_initMutex(Memento_mutex *m)
  328. {
  329. pthread_mutex_init(m, NULL);
  330. }
  331. #define MEMENTO_DO_LOCK() \
  332. pthread_mutex_lock(&memento.mutex)
  333. #define MEMENTO_DO_UNLOCK() \
  334. pthread_mutex_unlock(&memento.mutex)
  335. #endif
  336. #endif
  337. /* And our global structure */
  338. static struct {
  339. int inited;
  340. Memento_Blocks used;
  341. Memento_Blocks free;
  342. size_t freeListSize;
  343. int sequence;
  344. int paranoia;
  345. int paranoidAt;
  346. int countdown;
  347. int lastChecked;
  348. int breakAt;
  349. int failAt;
  350. int failing;
  351. int nextFailAt;
  352. int squeezeAt;
  353. int squeezing;
  354. int segv;
  355. int pattern;
  356. int nextPattern;
  357. int patternBit;
  358. int leaking;
  359. size_t maxMemory;
  360. size_t alloc;
  361. size_t peakAlloc;
  362. size_t totalAlloc;
  363. size_t numMallocs;
  364. size_t numFrees;
  365. size_t numReallocs;
  366. Memento_mutex mutex;
  367. } memento;
  368. #define MEMENTO_EXTRASIZE (sizeof(Memento_BlkHeader) + Memento_PostSize)
  369. /* Round up size S to the next multiple of N (where N is a power of 2) */
  370. #define MEMENTO_ROUNDUP(S,N) ((S + N-1)&~(N-1))
  371. #define MEMBLK_SIZE(s) MEMENTO_ROUNDUP(s + MEMENTO_EXTRASIZE, MEMENTO_MAXALIGN)
  372. #define MEMBLK_FROMBLK(B) (&((Memento_BlkHeader*)(void *)(B))[-1])
  373. #define MEMBLK_TOBLK(B) ((void*)(&((Memento_BlkHeader*)(void*)(B))[1]))
  374. #define MEMBLK_POSTPTR(B) \
  375. (&((unsigned char *)(void *)(B))[(B)->rawsize + sizeof(Memento_BlkHeader)])
  376. enum
  377. {
  378. SkipStackBackTraceLevels = 4
  379. };
  380. #if defined(MEMENTO_STACKTRACE_METHOD) && MEMENTO_STACKTRACE_METHOD == 1
  381. extern size_t backtrace(void **, int);
  382. extern void backtrace_symbols_fd(void **, size_t, int);
  383. extern char **backtrace_symbols(void **, size_t);
  384. #define MEMENTO_BACKTRACE_MAX 256
  385. static void (*print_stack_value)(void *address);
  386. /* Libbacktrace gubbins - relies on us having libdl to load the .so */
  387. #ifdef HAVE_LIBDL
  388. #include <dlfcn.h>
  389. typedef void (*backtrace_error_callback) (void *data, const char *msg, int errnum);
  390. typedef struct backtrace_state *(*backtrace_create_state_type)(
  391. const char *filename, int threaded,
  392. backtrace_error_callback error_callback, void *data);
  393. typedef int (*backtrace_full_callback) (void *data, uintptr_t pc,
  394. const char *filename, int lineno,
  395. const char *function);
  396. typedef int (*backtrace_pcinfo_type)(struct backtrace_state *state,
  397. uintptr_t pc,
  398. backtrace_full_callback callback,
  399. backtrace_error_callback error_callback,
  400. void *data);
  401. typedef void (*backtrace_syminfo_callback) (void *data, uintptr_t pc,
  402. const char *symname,
  403. uintptr_t symval,
  404. uintptr_t symsize);
  405. typedef int (*backtrace_syminfo_type)(struct backtrace_state *state,
  406. uintptr_t addr,
  407. backtrace_syminfo_callback callback,
  408. backtrace_error_callback error_callback,
  409. void *data);
  410. static backtrace_syminfo_type backtrace_syminfo;
  411. static backtrace_create_state_type backtrace_create_state;
  412. static backtrace_pcinfo_type backtrace_pcinfo;
  413. static struct backtrace_state *my_backtrace_state;
  414. static void *libbt;
  415. static char backtrace_exe[4096];
  416. static void *current_addr;
  417. static void error2_cb(void *data, const char *msg, int errnum)
  418. {
  419. }
  420. static void syminfo_cb(void *data, uintptr_t pc, const char *symname, uintptr_t symval, uintptr_t symsize)
  421. {
  422. if (sizeof(void *) == 4)
  423. fprintf(stderr, " 0x%08lx %s\n", pc, symname?symname:"?");
  424. else
  425. fprintf(stderr, " 0x%016lx %s\n", pc, symname?symname:"?");
  426. }
  427. static void error_cb(void *data, const char *msg, int errnum)
  428. {
  429. backtrace_syminfo(my_backtrace_state,
  430. (uintptr_t)current_addr,
  431. syminfo_cb,
  432. error2_cb,
  433. NULL);
  434. }
  435. static int full_cb(void *data, uintptr_t pc, const char *fname, int line, const char *fn)
  436. {
  437. if (sizeof(void *) == 4)
  438. fprintf(stderr, " 0x%08lx %s(%s:%d)\n", pc, fn?fn:"?", fname?fname:"?", line);
  439. else
  440. fprintf(stderr, " 0x%016lx %s(%s:%d)\n", pc, fn?fn:"?", fname?fname:"?", line);
  441. return 0;
  442. }
  443. static void print_stack_libbt(void *addr)
  444. {
  445. current_addr = addr;
  446. backtrace_pcinfo(my_backtrace_state,
  447. (uintptr_t)addr,
  448. full_cb,
  449. error_cb,
  450. NULL);
  451. }
  452. static void print_stack_libbt_failed(void *addr)
  453. {
  454. char **strings;
  455. #if 0
  456. /* Let's use a hack from Julian Smith to call gdb to extract the information */
  457. /* Disabled for now, as I can't make this work. */
  458. static char command[1024];
  459. int e;
  460. static int gdb_invocation_failed = 0;
  461. if (gdb_invocation_failed == 0)
  462. {
  463. snprintf(command, sizeof(command),
  464. //"gdb -q --batch -p=%i -ex 'info line *%p' -ex quit 2>/dev/null",
  465. "gdb -q --batch -p=%i -ex 'info line *%p' -ex quit 2>/dev/null| egrep -v '(Thread debugging using)|(Using host libthread_db library)|(A debugging session is active)|(will be detached)|(Quit anyway)|(No such file or directory)|(^0x)|(^$)'",
  466. getpid(), addr);
  467. printf("%s\n", command);
  468. e = system(command);
  469. if (e == 0)
  470. return; /* That'll do! */
  471. gdb_invocation_failed = 1; /* If it's failed once, it'll probably keep failing. */
  472. }
  473. #endif
  474. /* We couldn't even get gdb! Make do. */
  475. strings = backtrace_symbols(&addr, 1);
  476. if (strings == NULL || strings[0] == NULL)
  477. {
  478. if (sizeof(void *) == 4)
  479. fprintf(stderr, " [0x%08lx]\n", (uintptr_t)addr);
  480. else
  481. fprintf(stderr, " [0x%016lx]\n", (uintptr_t)addr);
  482. }
  483. else
  484. {
  485. fprintf(stderr, " %s\n", strings[0]);
  486. }
  487. (free)(strings);
  488. }
  489. static int init_libbt(void)
  490. {
  491. static int libbt_inited = 0;
  492. if (libbt_inited)
  493. return 0;
  494. libbt_inited = 1;
  495. libbt = dlopen("libbacktrace.so", RTLD_LAZY);
  496. if (libbt == NULL)
  497. libbt = dlopen("/opt/lib/libbacktrace.so", RTLD_LAZY);
  498. if (libbt == NULL)
  499. libbt = dlopen("/lib/libbacktrace.so", RTLD_LAZY);
  500. if (libbt == NULL)
  501. libbt = dlopen("/usr/lib/libbacktrace.so", RTLD_LAZY);
  502. if (libbt == NULL)
  503. libbt = dlopen("/usr/local/lib/libbacktrace.so", RTLD_LAZY);
  504. if (libbt == NULL)
  505. goto fail;
  506. backtrace_create_state = dlsym(libbt, "backtrace_create_state");
  507. backtrace_syminfo = dlsym(libbt, "backtrace_syminfo");
  508. backtrace_pcinfo = dlsym(libbt, "backtrace_pcinfo");
  509. if (backtrace_create_state == NULL ||
  510. backtrace_syminfo == NULL ||
  511. backtrace_pcinfo == NULL)
  512. {
  513. goto fail;
  514. }
  515. my_backtrace_state = backtrace_create_state(backtrace_exe,
  516. 1 /*BACKTRACE_SUPPORTS_THREADS*/,
  517. error_cb,
  518. NULL);
  519. if (my_backtrace_state == NULL)
  520. goto fail;
  521. print_stack_value = print_stack_libbt;
  522. return 1;
  523. fail:
  524. fprintf(stderr,
  525. "MEMENTO: libbacktrace.so failed to load; backtraces will be sparse.\n"
  526. "MEMENTO: See memento.h for how to rectify this.\n");
  527. libbt = NULL;
  528. backtrace_create_state = NULL;
  529. backtrace_syminfo = NULL;
  530. print_stack_value = print_stack_libbt_failed;
  531. return 0;
  532. }
  533. #endif
  534. static void print_stack_default(void *addr)
  535. {
  536. char **strings = backtrace_symbols(&addr, 1);
  537. if (strings == NULL || strings[0] == NULL)
  538. {
  539. fprintf(stderr, " ["FMTP"]\n", addr);
  540. }
  541. #ifdef HAVE_LIBDL
  542. else if (strchr(strings[0], ':') == NULL)
  543. {
  544. /* Probably a "path [address]" format string */
  545. char *s = strchr(strings[0], ' ');
  546. if (s != strings[0])
  547. {
  548. memcpy(backtrace_exe, strings[0], s - strings[0]);
  549. backtrace_exe[s-strings[0]] = 0;
  550. init_libbt();
  551. print_stack_value(addr);
  552. }
  553. }
  554. #endif
  555. else
  556. {
  557. fprintf(stderr, " %s\n", strings[0]);
  558. }
  559. free(strings);
  560. }
  561. static void Memento_initStacktracer(void)
  562. {
  563. print_stack_value = print_stack_default;
  564. }
  565. static int Memento_getStacktrace(void **stack, int *skip)
  566. {
  567. size_t num;
  568. num = backtrace(&stack[0], MEMENTO_BACKTRACE_MAX);
  569. *skip = SkipStackBackTraceLevels;
  570. if (num <= SkipStackBackTraceLevels)
  571. return 0;
  572. return (int)(num-SkipStackBackTraceLevels);
  573. }
  574. static void Memento_showStacktrace(void **stack, int numberOfFrames)
  575. {
  576. int i;
  577. for (i = 0; i < numberOfFrames; i++)
  578. {
  579. print_stack_value(stack[i]);
  580. }
  581. }
  582. #elif defined(MEMENTO_STACKTRACE_METHOD) && MEMENTO_STACKTRACE_METHOD == 2
  583. #include <Windows.h>
  584. /* We use DbgHelp.dll rather than DbgHelp.lib. This avoids us needing
  585. * extra link time complications, and enables us to fall back gracefully
  586. * if the DLL cannot be found.
  587. *
  588. * To achieve this we have our own potted versions of the required types
  589. * inline here.
  590. */
  591. #ifdef _WIN64
  592. typedef DWORD64 DWORD_NATIVESIZED;
  593. #else
  594. typedef DWORD DWORD_NATIVESIZED;
  595. #endif
  596. #define MEMENTO_BACKTRACE_MAX 64
  597. typedef USHORT (__stdcall *My_CaptureStackBackTraceType)(__in ULONG, __in ULONG, __out PVOID*, __out_opt PULONG);
  598. typedef struct MY_IMAGEHLP_LINE {
  599. DWORD SizeOfStruct;
  600. PVOID Key;
  601. DWORD LineNumber;
  602. PCHAR FileName;
  603. DWORD_NATIVESIZED Address;
  604. } MY_IMAGEHLP_LINE, *MY_PIMAGEHLP_LINE;
  605. typedef BOOL (__stdcall *My_SymGetLineFromAddrType)(HANDLE hProcess, DWORD_NATIVESIZED dwAddr, PDWORD pdwDisplacement, MY_PIMAGEHLP_LINE Line);
  606. typedef struct MY_SYMBOL_INFO {
  607. ULONG SizeOfStruct;
  608. ULONG TypeIndex; // Type Index of symbol
  609. ULONG64 Reserved[2];
  610. ULONG info;
  611. ULONG Size;
  612. ULONG64 ModBase; // Base Address of module containing this symbol
  613. ULONG Flags;
  614. ULONG64 Value; // Value of symbol, ValuePresent should be 1
  615. ULONG64 Address; // Address of symbol including base address of module
  616. ULONG Register; // register holding value or pointer to value
  617. ULONG Scope; // scope of the symbol
  618. ULONG Tag; // pdb classification
  619. ULONG NameLen; // Actual length of name
  620. ULONG MaxNameLen;
  621. CHAR Name[1]; // Name of symbol
  622. } MY_SYMBOL_INFO, *MY_PSYMBOL_INFO;
  623. typedef BOOL (__stdcall *My_SymFromAddrType)(HANDLE hProcess, DWORD64 Address, PDWORD64 Displacement, MY_PSYMBOL_INFO Symbol);
  624. typedef BOOL (__stdcall *My_SymInitializeType)(HANDLE hProcess, PSTR UserSearchPath, BOOL fInvadeProcess);
  625. static My_CaptureStackBackTraceType Memento_CaptureStackBackTrace;
  626. static My_SymGetLineFromAddrType Memento_SymGetLineFromAddr;
  627. static My_SymFromAddrType Memento_SymFromAddr;
  628. static My_SymInitializeType Memento_SymInitialize;
  629. static HANDLE Memento_process;
  630. static void Memento_initStacktracer(void)
  631. {
  632. HMODULE mod = LoadLibrary("kernel32.dll");
  633. if (mod == NULL)
  634. return;
  635. Memento_CaptureStackBackTrace = (My_CaptureStackBackTraceType)(GetProcAddress(mod, "RtlCaptureStackBackTrace"));
  636. if (Memento_CaptureStackBackTrace == NULL)
  637. return;
  638. mod = LoadLibrary("Dbghelp.dll");
  639. if (mod == NULL) {
  640. Memento_CaptureStackBackTrace = NULL;
  641. return;
  642. }
  643. Memento_SymGetLineFromAddr =
  644. (My_SymGetLineFromAddrType)(GetProcAddress(mod,
  645. #ifdef _WIN64
  646. "SymGetLineFromAddr64"
  647. #else
  648. "SymGetLineFromAddr"
  649. #endif
  650. ));
  651. if (Memento_SymGetLineFromAddr == NULL) {
  652. Memento_CaptureStackBackTrace = NULL;
  653. return;
  654. }
  655. Memento_SymFromAddr = (My_SymFromAddrType)(GetProcAddress(mod, "SymFromAddr"));
  656. if (Memento_SymFromAddr == NULL) {
  657. Memento_CaptureStackBackTrace = NULL;
  658. return;
  659. }
  660. Memento_SymInitialize = (My_SymInitializeType)(GetProcAddress(mod, "SymInitialize"));
  661. if (Memento_SymInitialize == NULL) {
  662. Memento_CaptureStackBackTrace = NULL;
  663. return;
  664. }
  665. Memento_process = GetCurrentProcess();
  666. Memento_SymInitialize(Memento_process, NULL, TRUE);
  667. }
  668. static int Memento_getStacktrace(void **stack, int *skip)
  669. {
  670. if (Memento_CaptureStackBackTrace == NULL)
  671. return 0;
  672. *skip = 0;
  673. /* Limit us to 63 levels due to windows bug */
  674. return Memento_CaptureStackBackTrace(SkipStackBackTraceLevels, 63-SkipStackBackTraceLevels, stack, NULL);
  675. }
  676. static void Memento_showStacktrace(void **stack, int numberOfFrames)
  677. {
  678. MY_IMAGEHLP_LINE line;
  679. int i;
  680. char symbol_buffer[sizeof(MY_SYMBOL_INFO) + 1024 + 1];
  681. MY_SYMBOL_INFO *symbol = (MY_SYMBOL_INFO *)symbol_buffer;
  682. symbol->MaxNameLen = 1024;
  683. symbol->SizeOfStruct = sizeof(MY_SYMBOL_INFO);
  684. line.SizeOfStruct = sizeof(MY_IMAGEHLP_LINE);
  685. for (i = 0; i < numberOfFrames; i++)
  686. {
  687. DWORD64 dwDisplacement64;
  688. DWORD dwDisplacement;
  689. Memento_SymFromAddr(Memento_process, (DWORD64)(stack[i]), &dwDisplacement64, symbol);
  690. Memento_SymGetLineFromAddr(Memento_process, (DWORD_NATIVESIZED)(stack[i]), &dwDisplacement, &line);
  691. fprintf(stderr, " %s in %s:%d\n", symbol->Name, line.FileName, line.LineNumber);
  692. }
  693. }
  694. #elif defined(MEMENTO_STACKTRACE_METHOD) && MEMENTO_STACKTRACE_METHOD == 3
  695. #include <unwind.h>
  696. #include <dlfcn.h>
  697. /* From cxxabi.h */
  698. extern char* __cxa_demangle(const char* mangled_name,
  699. char* output_buffer,
  700. size_t* length,
  701. int* status);
  702. static void Memento_initStacktracer(void)
  703. {
  704. }
  705. #define MEMENTO_BACKTRACE_MAX 256
  706. typedef struct
  707. {
  708. int count;
  709. void **addr;
  710. } my_unwind_details;
  711. static _Unwind_Reason_Code unwind_populate_callback(struct _Unwind_Context *context,
  712. void *arg)
  713. {
  714. my_unwind_details *uw = (my_unwind_details *)arg;
  715. int count = uw->count;
  716. if (count >= MEMENTO_BACKTRACE_MAX)
  717. return _URC_END_OF_STACK;
  718. uw->addr[count] = (void *)_Unwind_GetIP(context);
  719. uw->count++;
  720. return _URC_NO_REASON;
  721. }
  722. static int Memento_getStacktrace(void **stack, int *skip)
  723. {
  724. my_unwind_details uw = { 0, stack };
  725. *skip = 0;
  726. /* Collect the backtrace. Deliberately only unwind once,
  727. * and avoid using malloc etc until this completes just
  728. * in case. */
  729. _Unwind_Backtrace(unwind_populate_callback, &uw);
  730. if (uw.count <= SkipStackBackTraceLevels)
  731. return 0;
  732. *skip = SkipStackBackTraceLevels;
  733. return uw.count-SkipStackBackTraceLevels;
  734. }
  735. static void Memento_showStacktrace(void **stack, int numberOfFrames)
  736. {
  737. int i;
  738. for (i = 0; i < numberOfFrames; i++)
  739. {
  740. Dl_info info;
  741. if (dladdr(stack[i], &info))
  742. {
  743. int status = 0;
  744. const char *sym = info.dli_sname ? info.dli_sname : "<unknown>";
  745. char *demangled = __cxa_demangle(sym, NULL, 0, &status);
  746. int offset = stack[i] - info.dli_saddr;
  747. fprintf(stderr, " ["FMTP"]%s(+0x%x)\n", stack[i], demangled && status == 0 ? demangled : sym, offset);
  748. free(demangled);
  749. }
  750. else
  751. {
  752. fprintf(stderr, " ["FMTP"]\n", stack[i]);
  753. }
  754. }
  755. }
  756. #else
  757. static void Memento_initStacktracer(void)
  758. {
  759. }
  760. static int Memento_getStacktrace(void **stack, int *skip)
  761. {
  762. *skip = 0;
  763. return 0;
  764. }
  765. static void Memento_showStacktrace(void **stack, int numberOfFrames)
  766. {
  767. }
  768. #endif /* MEMENTO_STACKTRACE_METHOD */
  769. #ifdef MEMENTO_DETAILS
  770. static void Memento_storeDetails(Memento_BlkHeader *head, int type)
  771. {
  772. void *stack[MEMENTO_BACKTRACE_MAX];
  773. Memento_BlkDetails *details;
  774. int count;
  775. int skip;
  776. if (head == NULL)
  777. return;
  778. #ifdef MEMENTO_STACKTRACE_METHOD
  779. count = Memento_getStacktrace(stack, &skip);
  780. #else
  781. skip = 0;
  782. count = 0;
  783. #endif
  784. details = MEMENTO_UNDERLYING_MALLOC(sizeof(*details) + (count-1) * sizeof(void *));
  785. if (details == NULL)
  786. return;
  787. if (count)
  788. memcpy(&details->stack, &stack[skip], count * sizeof(void *));
  789. details->type = type;
  790. details->count = count;
  791. details->sequence = memento.sequence;
  792. details->next = NULL;
  793. VALGRIND_MAKE_MEM_DEFINED(&head->details_tail, sizeof(head->details_tail));
  794. *head->details_tail = details;
  795. head->details_tail = &details->next;
  796. VALGRIND_MAKE_MEM_NOACCESS(&head->details_tail, sizeof(head->details_tail));
  797. }
  798. #endif
  799. void (Memento_bt)(void)
  800. {
  801. #ifdef MEMENTO_STACKTRACE_METHOD
  802. void *stack[MEMENTO_BACKTRACE_MAX];
  803. int count;
  804. int skip;
  805. count = Memento_getStacktrace(stack, &skip);
  806. Memento_showStacktrace(&stack[skip-2], count-skip+2);
  807. #endif
  808. }
  809. static void Memento_bt_internal(int skip2)
  810. {
  811. #ifdef MEMENTO_STACKTRACE_METHOD
  812. void *stack[MEMENTO_BACKTRACE_MAX];
  813. int count;
  814. int skip;
  815. count = Memento_getStacktrace(stack, &skip);
  816. Memento_showStacktrace(&stack[skip+skip2], count-skip-skip2);
  817. #endif
  818. }
  819. static int Memento_checkAllMemoryLocked(void);
  820. void Memento_breakpoint(void)
  821. {
  822. /* A handy externally visible function for breakpointing */
  823. #if 0 /* Enable this to force automatic breakpointing */
  824. #ifndef NDEBUG
  825. #ifdef _MSC_VER
  826. __asm int 3;
  827. #endif
  828. #endif
  829. #endif
  830. }
  831. static void Memento_init(void);
  832. #define MEMENTO_LOCK() \
  833. do { if (!memento.inited) Memento_init(); MEMENTO_DO_LOCK(); } while (0)
  834. #define MEMENTO_UNLOCK() \
  835. do { MEMENTO_DO_UNLOCK(); } while (0)
  836. /* Do this as a macro to prevent another level in the callstack,
  837. * which is annoying while stepping. */
  838. #define Memento_breakpointLocked() \
  839. do { MEMENTO_UNLOCK(); Memento_breakpoint(); MEMENTO_LOCK(); } while (0)
  840. static void Memento_addBlockHead(Memento_Blocks *blks,
  841. Memento_BlkHeader *b,
  842. int type)
  843. {
  844. if (blks->tail == NULL)
  845. blks->tail = b;
  846. b->next = blks->head;
  847. b->prev = NULL;
  848. if (blks->head)
  849. {
  850. VALGRIND_MAKE_MEM_DEFINED(&blks->head->prev, sizeof(blks->head->prev));
  851. blks->head->prev = b;
  852. VALGRIND_MAKE_MEM_NOACCESS(&blks->head->prev, sizeof(blks->head->prev));
  853. }
  854. blks->head = b;
  855. #ifndef MEMENTO_LEAKONLY
  856. memset(b->preblk, MEMENTO_PREFILL, Memento_PreSize);
  857. memset(MEMBLK_POSTPTR(b), MEMENTO_POSTFILL, Memento_PostSize);
  858. #endif
  859. VALGRIND_MAKE_MEM_NOACCESS(MEMBLK_POSTPTR(b), Memento_PostSize);
  860. if (type == 0) { /* malloc */
  861. VALGRIND_MAKE_MEM_UNDEFINED(MEMBLK_TOBLK(b), b->rawsize);
  862. } else if (type == 1) { /* free */
  863. VALGRIND_MAKE_MEM_NOACCESS(MEMBLK_TOBLK(b), b->rawsize);
  864. }
  865. VALGRIND_MAKE_MEM_NOACCESS(b, sizeof(Memento_BlkHeader));
  866. }
  867. static void Memento_addBlockTail(Memento_Blocks *blks,
  868. Memento_BlkHeader *b,
  869. int type)
  870. {
  871. VALGRIND_MAKE_MEM_DEFINED(&blks->tail, sizeof(Memento_BlkHeader *));
  872. if (blks->head == NULL)
  873. blks->head = b;
  874. b->prev = blks->tail;
  875. b->next = NULL;
  876. if (blks->tail) {
  877. VALGRIND_MAKE_MEM_DEFINED(&blks->tail->next, sizeof(blks->tail->next));
  878. blks->tail->next = b;
  879. VALGRIND_MAKE_MEM_NOACCESS(&blks->tail->next, sizeof(blks->tail->next));
  880. }
  881. blks->tail = b;
  882. #ifndef MEMENTO_LEAKONLY
  883. memset(b->preblk, MEMENTO_PREFILL, Memento_PreSize);
  884. memset(MEMBLK_POSTPTR(b), MEMENTO_POSTFILL, Memento_PostSize);
  885. #endif
  886. VALGRIND_MAKE_MEM_NOACCESS(MEMBLK_POSTPTR(b), Memento_PostSize);
  887. if (type == 0) { /* malloc */
  888. VALGRIND_MAKE_MEM_UNDEFINED(MEMBLK_TOBLK(b), b->rawsize);
  889. } else if (type == 1) { /* free */
  890. VALGRIND_MAKE_MEM_NOACCESS(MEMBLK_TOBLK(b), b->rawsize);
  891. }
  892. VALGRIND_MAKE_MEM_NOACCESS(b, sizeof(Memento_BlkHeader));
  893. VALGRIND_MAKE_MEM_NOACCESS(&blks->tail, sizeof(Memento_BlkHeader *));
  894. }
  895. typedef struct BlkCheckData {
  896. int found;
  897. int preCorrupt;
  898. int postCorrupt;
  899. int freeCorrupt;
  900. size_t index;
  901. } BlkCheckData;
  902. #ifndef MEMENTO_LEAKONLY
  903. static int Memento_Internal_checkAllocedBlock(Memento_BlkHeader *b, void *arg)
  904. {
  905. int i;
  906. MEMENTO_UINT32 *ip;
  907. unsigned char *p;
  908. BlkCheckData *data = (BlkCheckData *)arg;
  909. ip = (MEMENTO_UINT32 *)(void *)(b->preblk);
  910. i = Memento_PreSize>>2;
  911. do {
  912. if (*ip++ != MEMENTO_PREFILL_UINT32)
  913. goto pre_corrupt;
  914. } while (--i);
  915. if (0) {
  916. pre_corrupt:
  917. data->preCorrupt = 1;
  918. }
  919. /* Postfill may not be aligned, so have to be slower */
  920. p = MEMBLK_POSTPTR(b);
  921. i = Memento_PostSize-4;
  922. if ((intptr_t)p & 1)
  923. {
  924. if (*p++ != MEMENTO_POSTFILL)
  925. goto post_corrupt;
  926. i--;
  927. }
  928. if ((intptr_t)p & 2)
  929. {
  930. if (*(MEMENTO_UINT16 *)p != MEMENTO_POSTFILL_UINT16)
  931. goto post_corrupt;
  932. p += 2;
  933. i -= 2;
  934. }
  935. do {
  936. if (*(MEMENTO_UINT32 *)p != MEMENTO_POSTFILL_UINT32)
  937. goto post_corrupt;
  938. p += 4;
  939. i -= 4;
  940. } while (i >= 0);
  941. if (i & 2)
  942. {
  943. if (*(MEMENTO_UINT16 *)p != MEMENTO_POSTFILL_UINT16)
  944. goto post_corrupt;
  945. p += 2;
  946. }
  947. if (i & 1)
  948. {
  949. if (*p != MEMENTO_POSTFILL)
  950. goto post_corrupt;
  951. }
  952. if (0) {
  953. post_corrupt:
  954. data->postCorrupt = 1;
  955. }
  956. if ((data->freeCorrupt | data->preCorrupt | data->postCorrupt) == 0) {
  957. b->lastCheckedOK = memento.sequence;
  958. }
  959. data->found |= 1;
  960. return 0;
  961. }
  962. static int Memento_Internal_checkFreedBlock(Memento_BlkHeader *b, void *arg)
  963. {
  964. size_t i;
  965. unsigned char *p;
  966. BlkCheckData *data = (BlkCheckData *)arg;
  967. p = MEMBLK_TOBLK(b); /* p will always be aligned */
  968. i = b->rawsize;
  969. /* Attempt to speed this up by checking an (aligned) int at a time */
  970. if (i >= 4) {
  971. i -= 4;
  972. do {
  973. if (*(MEMENTO_UINT32 *)p != MEMENTO_FREEFILL_UINT32)
  974. goto mismatch4;
  975. p += 4;
  976. i -= 4;
  977. } while (i > 0);
  978. i += 4;
  979. }
  980. if (i & 2) {
  981. if (*(MEMENTO_UINT16 *)p != MEMENTO_FREEFILL_UINT16)
  982. goto mismatch;
  983. p += 2;
  984. i -= 2;
  985. }
  986. if (0) {
  987. mismatch4:
  988. i += 4;
  989. }
  990. mismatch:
  991. while (i) {
  992. if (*p++ != (unsigned char)MEMENTO_FREEFILL)
  993. break;
  994. i--;
  995. }
  996. if (i) {
  997. data->freeCorrupt = 1;
  998. data->index = b->rawsize-i;
  999. }
  1000. return Memento_Internal_checkAllocedBlock(b, arg);
  1001. }
  1002. #endif /* MEMENTO_LEAKONLY */
  1003. static void Memento_removeBlock(Memento_Blocks *blks,
  1004. Memento_BlkHeader *b)
  1005. {
  1006. VALGRIND_MAKE_MEM_DEFINED(b, sizeof(*b));
  1007. if (b->next) {
  1008. VALGRIND_MAKE_MEM_DEFINED(&b->next->prev, sizeof(b->next->prev));
  1009. b->next->prev = b->prev;
  1010. VALGRIND_MAKE_MEM_NOACCESS(&b->next->prev, sizeof(b->next->prev));
  1011. }
  1012. if (b->prev) {
  1013. VALGRIND_MAKE_MEM_DEFINED(&b->prev->next, sizeof(b->prev->next));
  1014. b->prev->next = b->next;
  1015. VALGRIND_MAKE_MEM_NOACCESS(&b->prev->next, sizeof(b->prev->next));
  1016. }
  1017. if (blks->tail == b)
  1018. blks->tail = b->prev;
  1019. if (blks->head == b)
  1020. blks->head = b->next;
  1021. }
  1022. static void free_block(Memento_BlkHeader *head)
  1023. {
  1024. #ifdef MEMENTO_DETAILS
  1025. Memento_BlkDetails *details = head->details;
  1026. while (details)
  1027. {
  1028. Memento_BlkDetails *next = details->next;
  1029. MEMENTO_UNDERLYING_FREE(details);
  1030. details = next;
  1031. }
  1032. #endif
  1033. MEMENTO_UNDERLYING_FREE(head);
  1034. }
  1035. static int Memento_Internal_makeSpace(size_t space)
  1036. {
  1037. /* If too big, it can never go on the freelist */
  1038. if (space > MEMENTO_FREELIST_MAX_SINGLE_BLOCK)
  1039. return 0;
  1040. /* Pretend we added it on. */
  1041. memento.freeListSize += space;
  1042. /* Ditch blocks until it fits within our limit */
  1043. while (memento.freeListSize > MEMENTO_FREELIST_MAX) {
  1044. Memento_BlkHeader *head = memento.free.head;
  1045. VALGRIND_MAKE_MEM_DEFINED(head, sizeof(*head));
  1046. memento.free.head = head->next;
  1047. memento.freeListSize -= MEMBLK_SIZE(head->rawsize);
  1048. free_block(head);
  1049. }
  1050. /* Make sure we haven't just completely emptied the free list */
  1051. /* (This should never happen, but belt and braces... */
  1052. if (memento.free.head == NULL)
  1053. memento.free.tail = NULL;
  1054. return 1;
  1055. }
  1056. static int Memento_appBlocks(Memento_Blocks *blks,
  1057. int (*app)(Memento_BlkHeader *,
  1058. void *),
  1059. void *arg)
  1060. {
  1061. Memento_BlkHeader *head = blks->head;
  1062. Memento_BlkHeader *next;
  1063. int result;
  1064. while (head) {
  1065. VALGRIND_MAKE_MEM_DEFINED(head, sizeof(Memento_BlkHeader));
  1066. VALGRIND_MAKE_MEM_DEFINED(MEMBLK_TOBLK(head),
  1067. head->rawsize + Memento_PostSize);
  1068. result = app(head, arg);
  1069. next = head->next;
  1070. VALGRIND_MAKE_MEM_NOACCESS(MEMBLK_POSTPTR(head), Memento_PostSize);
  1071. VALGRIND_MAKE_MEM_NOACCESS(head, sizeof(Memento_BlkHeader));
  1072. if (result)
  1073. return result;
  1074. head = next;
  1075. }
  1076. return 0;
  1077. }
  1078. #ifndef MEMENTO_LEAKONLY
  1079. /* Distrustful - check the block is a real one */
  1080. static int Memento_appBlockUser(Memento_Blocks *blks,
  1081. int (*app)(Memento_BlkHeader *,
  1082. void *),
  1083. void *arg,
  1084. Memento_BlkHeader *b)
  1085. {
  1086. Memento_BlkHeader *head = blks->head;
  1087. Memento_BlkHeader *next;
  1088. int result;
  1089. while (head && head != b) {
  1090. VALGRIND_MAKE_MEM_DEFINED(head, sizeof(Memento_BlkHeader));
  1091. next = head->next;
  1092. VALGRIND_MAKE_MEM_NOACCESS(MEMBLK_POSTPTR(head), Memento_PostSize);
  1093. head = next;
  1094. }
  1095. if (head == b) {
  1096. VALGRIND_MAKE_MEM_DEFINED(head, sizeof(Memento_BlkHeader));
  1097. VALGRIND_MAKE_MEM_DEFINED(MEMBLK_TOBLK(head),
  1098. head->rawsize + Memento_PostSize);
  1099. result = app(head, arg);
  1100. VALGRIND_MAKE_MEM_NOACCESS(MEMBLK_POSTPTR(head), Memento_PostSize);
  1101. VALGRIND_MAKE_MEM_NOACCESS(head, sizeof(Memento_BlkHeader));
  1102. return result;
  1103. }
  1104. return 0;
  1105. }
  1106. static int Memento_appBlock(Memento_Blocks *blks,
  1107. int (*app)(Memento_BlkHeader *,
  1108. void *),
  1109. void *arg,
  1110. Memento_BlkHeader *b)
  1111. {
  1112. int result;
  1113. VALGRIND_MAKE_MEM_DEFINED(b, sizeof(Memento_BlkHeader));
  1114. VALGRIND_MAKE_MEM_DEFINED(MEMBLK_TOBLK(b),
  1115. b->rawsize + Memento_PostSize);
  1116. result = app(b, arg);
  1117. VALGRIND_MAKE_MEM_NOACCESS(MEMBLK_POSTPTR(b), Memento_PostSize);
  1118. VALGRIND_MAKE_MEM_NOACCESS(b, sizeof(Memento_BlkHeader));
  1119. return result;
  1120. }
  1121. #endif /* MEMENTO_LEAKONLY */
  1122. static int showBlock(Memento_BlkHeader *b, int space)
  1123. {
  1124. int seq;
  1125. VALGRIND_MAKE_MEM_DEFINED(b, sizeof(Memento_BlkHeader));
  1126. fprintf(stderr, FMTP":(size=" FMTZ ",num=%d)",
  1127. MEMBLK_TOBLK(b), (FMTZ_CAST)b->rawsize, b->sequence);
  1128. if (b->label)
  1129. fprintf(stderr, "%c(%s)", space, b->label);
  1130. if (b->flags & Memento_Flag_KnownLeak)
  1131. fprintf(stderr, "(Known Leak)");
  1132. seq = b->sequence;
  1133. VALGRIND_MAKE_MEM_NOACCESS(b, sizeof(Memento_BlkHeader));
  1134. return seq;
  1135. }
  1136. static void blockDisplay(Memento_BlkHeader *b, int n)
  1137. {
  1138. n++;
  1139. while (n > 40)
  1140. {
  1141. fprintf(stderr, "*");
  1142. n -= 40;
  1143. }
  1144. while(n > 0)
  1145. {
  1146. int i = n;
  1147. if (i > 32)
  1148. i = 32;
  1149. n -= i;
  1150. fprintf(stderr, "%s", &" "[32-i]);
  1151. }
  1152. showBlock(b, '\t');
  1153. fprintf(stderr, "\n");
  1154. }
  1155. static int Memento_listBlock(Memento_BlkHeader *b,
  1156. void *arg)
  1157. {
  1158. size_t *counts = (size_t *)arg;
  1159. blockDisplay(b, 0);
  1160. counts[0]++;
  1161. VALGRIND_MAKE_MEM_DEFINED(b, sizeof(Memento_BlkHeader));
  1162. counts[1]+= b->rawsize;
  1163. VALGRIND_MAKE_MEM_NOACCESS(b, sizeof(Memento_BlkHeader));
  1164. return 0;
  1165. }
  1166. static void doNestedDisplay(Memento_BlkHeader *b,
  1167. int depth)
  1168. {
  1169. /* Try and avoid recursion if we can help it */
  1170. do {
  1171. Memento_BlkHeader *c = NULL;
  1172. blockDisplay(b, depth);
  1173. VALGRIND_MAKE_MEM_DEFINED(b, sizeof(Memento_BlkHeader));
  1174. if (b->sibling) {
  1175. c = b->child;
  1176. b = b->sibling;
  1177. } else {
  1178. b = b->child;
  1179. depth++;
  1180. }
  1181. VALGRIND_MAKE_MEM_NOACCESS(b, sizeof(Memento_BlkHeader));
  1182. if (c)
  1183. doNestedDisplay(c, depth+1);
  1184. } while (b);
  1185. }
  1186. static int ptrcmp(const void *a_, const void *b_)
  1187. {
  1188. const char **a = (const char **)a_;
  1189. const char **b = (const char **)b_;
  1190. return (int)(*a-*b);
  1191. }
  1192. static
  1193. int Memento_listBlocksNested(void)
  1194. {
  1195. int count, i;
  1196. size_t size;
  1197. Memento_BlkHeader *b, *prev;
  1198. void **blocks, *minptr, *maxptr;
  1199. intptr_t mask;
  1200. /* Count the blocks */
  1201. count = 0;
  1202. size = 0;
  1203. for (b = memento.used.head; b; b = b->next) {
  1204. VALGRIND_MAKE_MEM_DEFINED(b, sizeof(*b));
  1205. size += b->rawsize;
  1206. count++;
  1207. }
  1208. /* Make our block list */
  1209. blocks = MEMENTO_UNDERLYING_MALLOC(sizeof(void *) * count);
  1210. if (blocks == NULL)
  1211. return 1;
  1212. /* Populate our block list */
  1213. b = memento.used.head;
  1214. minptr = maxptr = MEMBLK_TOBLK(b);
  1215. mask = (intptr_t)minptr;
  1216. for (i = 0; b; b = b->next, i++) {
  1217. void *p = MEMBLK_TOBLK(b);
  1218. mask &= (intptr_t)p;
  1219. if (p < minptr)
  1220. minptr = p;
  1221. if (p > maxptr)
  1222. maxptr = p;
  1223. blocks[i] = p;
  1224. b->flags &= ~Memento_Flag_HasParent;
  1225. b->child = NULL;
  1226. b->sibling = NULL;
  1227. b->prev = NULL; /* parent */
  1228. }
  1229. qsort(blocks, count, sizeof(void *), ptrcmp);
  1230. /* Now, calculate tree */
  1231. for (b = memento.used.head; b; b = b->next) {
  1232. char *p = MEMBLK_TOBLK(b);
  1233. int end = (b->rawsize < MEMENTO_PTRSEARCH ? b->rawsize : MEMENTO_PTRSEARCH);
  1234. for (i = MEMENTO_SEARCH_SKIP; i < end; i += sizeof(void *)) {
  1235. void *q = *(void **)(&p[i]);
  1236. void **r;
  1237. /* Do trivial checks on pointer */
  1238. if ((mask & (intptr_t)q) != mask || q < minptr || q > maxptr)
  1239. continue;
  1240. /* Search for pointer */
  1241. r = bsearch(&q, blocks, count, sizeof(void *), ptrcmp);
  1242. if (r) {
  1243. /* Found child */
  1244. Memento_BlkHeader *child = MEMBLK_FROMBLK(*r);
  1245. Memento_BlkHeader *parent;
  1246. /* We're assuming tree structure, not graph - ignore second
  1247. * and subsequent pointers. */
  1248. if (child->prev != NULL) /* parent */
  1249. continue;
  1250. if (child->flags & Memento_Flag_HasParent)
  1251. continue;
  1252. /* Not interested in pointers to ourself! */
  1253. if (child == b)
  1254. continue;
  1255. /* We're also assuming acyclicness here. If this is one of
  1256. * our parents, ignore it. */
  1257. parent = b->prev; /* parent */
  1258. while (parent != NULL && parent != child)
  1259. parent = parent->prev; /* parent */
  1260. if (parent == child)
  1261. continue;
  1262. child->sibling = b->child;
  1263. b->child = child;
  1264. child->prev = b; /* parent */
  1265. child->flags |= Memento_Flag_HasParent;
  1266. }
  1267. }
  1268. }
  1269. /* Now display with nesting */
  1270. for (b = memento.used.head; b; b = b->next) {
  1271. if ((b->flags & Memento_Flag_HasParent) == 0)
  1272. doNestedDisplay(b, 0);
  1273. }
  1274. fprintf(stderr, " Total number of blocks = %d\n", count);
  1275. fprintf(stderr, " Total size of blocks = "FMTZ"\n", (FMTZ_CAST)size);
  1276. MEMENTO_UNDERLYING_FREE(blocks);
  1277. /* Now put the blocks back for valgrind, and restore the prev
  1278. * and magic values. */
  1279. prev = NULL;
  1280. for (b = memento.used.head; b;) {
  1281. Memento_BlkHeader *next = b->next;
  1282. b->prev = prev;
  1283. b->child = MEMENTO_CHILD_MAGIC;
  1284. b->sibling = MEMENTO_SIBLING_MAGIC;
  1285. prev = b;
  1286. VALGRIND_MAKE_MEM_NOACCESS(b, sizeof(*b));
  1287. b = next;
  1288. }
  1289. return 0;
  1290. }
  1291. void Memento_listBlocks(void)
  1292. {
  1293. MEMENTO_LOCK();
  1294. fprintf(stderr, "Allocated blocks:\n");
  1295. if (Memento_listBlocksNested())
  1296. {
  1297. size_t counts[2];
  1298. counts[0] = 0;
  1299. counts[1] = 0;
  1300. Memento_appBlocks(&memento.used, Memento_listBlock, &counts[0]);
  1301. fprintf(stderr, " Total number of blocks = "FMTZ"\n", (FMTZ_CAST)counts[0]);
  1302. fprintf(stderr, " Total size of blocks = "FMTZ"\n", (FMTZ_CAST)counts[1]);
  1303. }
  1304. MEMENTO_UNLOCK();
  1305. }
  1306. static int Memento_listNewBlock(Memento_BlkHeader *b,
  1307. void *arg)
  1308. {
  1309. if (b->flags & Memento_Flag_OldBlock)
  1310. return 0;
  1311. b->flags |= Memento_Flag_OldBlock;
  1312. return Memento_listBlock(b, arg);
  1313. }
  1314. void Memento_listNewBlocks(void)
  1315. {
  1316. size_t counts[2];
  1317. MEMENTO_LOCK();
  1318. counts[0] = 0;
  1319. counts[1] = 0;
  1320. fprintf(stderr, "Blocks allocated and still extant since last list:\n");
  1321. Memento_appBlocks(&memento.used, Memento_listNewBlock, &counts[0]);
  1322. fprintf(stderr, " Total number of blocks = "FMTZ"\n", (FMTZ_CAST)counts[0]);
  1323. fprintf(stderr, " Total size of blocks = "FMTZ"\n", (FMTZ_CAST)counts[1]);
  1324. MEMENTO_UNLOCK();
  1325. }
  1326. static void Memento_endStats(void)
  1327. {
  1328. fprintf(stderr, "Total memory malloced = "FMTZ" bytes\n", (FMTZ_CAST)memento.totalAlloc);
  1329. fprintf(stderr, "Peak memory malloced = "FMTZ" bytes\n", (FMTZ_CAST)memento.peakAlloc);
  1330. fprintf(stderr, FMTZ" mallocs, "FMTZ" frees, "FMTZ" reallocs\n", (FMTZ_CAST)memento.numMallocs,
  1331. (FMTZ_CAST)memento.numFrees, (FMTZ_CAST)memento.numReallocs);
  1332. fprintf(stderr, "Average allocation size "FMTZ" bytes\n", (FMTZ_CAST)
  1333. (memento.numMallocs != 0 ? memento.totalAlloc/memento.numMallocs: 0));
  1334. }
  1335. void Memento_stats(void)
  1336. {
  1337. MEMENTO_LOCK();
  1338. fprintf(stderr, "Current memory malloced = "FMTZ" bytes\n", (FMTZ_CAST)memento.alloc);
  1339. Memento_endStats();
  1340. MEMENTO_UNLOCK();
  1341. }
  1342. #ifdef MEMENTO_DETAILS
  1343. static int showInfo(Memento_BlkHeader *b, void *arg)
  1344. {
  1345. Memento_BlkDetails *details;
  1346. fprintf(stderr, FMTP":(size="FMTZ",num=%d)",
  1347. MEMBLK_TOBLK(b), (FMTZ_CAST)b->rawsize, b->sequence);
  1348. if (b->label)
  1349. fprintf(stderr, " (%s)", b->label);
  1350. fprintf(stderr, "\nEvents:\n");
  1351. details = b->details;
  1352. while (details)
  1353. {
  1354. fprintf(stderr, " Event %d (%s)\n", details->sequence, eventType[(int)details->type]);
  1355. Memento_showStacktrace(details->stack, details->count);
  1356. details = details->next;
  1357. }
  1358. return 0;
  1359. }
  1360. #endif
  1361. void Memento_listBlockInfo(void)
  1362. {
  1363. #ifdef MEMENTO_DETAILS
  1364. MEMENTO_LOCK();
  1365. fprintf(stderr, "Details of allocated blocks:\n");
  1366. Memento_appBlocks(&memento.used, showInfo, NULL);
  1367. MEMENTO_UNLOCK();
  1368. #endif
  1369. }
  1370. static int Memento_nonLeakBlocksLeaked(void)
  1371. {
  1372. Memento_BlkHeader *blk = memento.used.head;
  1373. while (blk)
  1374. {
  1375. Memento_BlkHeader *next;
  1376. int leaked;
  1377. VALGRIND_MAKE_MEM_DEFINED(blk, sizeof(*blk));
  1378. leaked = ((blk->flags & Memento_Flag_KnownLeak) == 0);
  1379. next = blk->next;
  1380. VALGRIND_MAKE_MEM_DEFINED(blk, sizeof(*blk));
  1381. if (leaked)
  1382. return 1;
  1383. blk = next;
  1384. }
  1385. return 0;
  1386. }
  1387. void Memento_fin(void)
  1388. {
  1389. Memento_checkAllMemory();
  1390. if (!memento.segv)
  1391. {
  1392. Memento_endStats();
  1393. if (Memento_nonLeakBlocksLeaked()) {
  1394. Memento_listBlocks();
  1395. #ifdef MEMENTO_DETAILS
  1396. fprintf(stderr, "\n");
  1397. Memento_listBlockInfo();
  1398. #endif
  1399. Memento_breakpoint();
  1400. }
  1401. }
  1402. if (memento.squeezing) {
  1403. if (memento.pattern == 0)
  1404. fprintf(stderr, "Memory squeezing @ %d complete%s\n", memento.squeezeAt, memento.segv ? " (with SEGV)" : "");
  1405. else
  1406. fprintf(stderr, "Memory squeezing @ %d (%d) complete%s\n", memento.squeezeAt, memento.pattern, memento.segv ? " (with SEGV)" : "");
  1407. } else if (memento.segv) {
  1408. fprintf(stderr, "Memento completed (with SEGV)\n");
  1409. }
  1410. if (memento.failing)
  1411. {
  1412. fprintf(stderr, "MEMENTO_FAILAT=%d\n", memento.failAt);
  1413. fprintf(stderr, "MEMENTO_PATTERN=%d\n", memento.pattern);
  1414. }
  1415. if (memento.nextFailAt != 0)
  1416. {
  1417. fprintf(stderr, "MEMENTO_NEXTFAILAT=%d\n", memento.nextFailAt);
  1418. fprintf(stderr, "MEMENTO_NEXTPATTERN=%d\n", memento.nextPattern);
  1419. }
  1420. }
  1421. static void Memento_init(void)
  1422. {
  1423. char *env;
  1424. memset(&memento, 0, sizeof(memento));
  1425. memento.inited = 1;
  1426. memento.used.head = NULL;
  1427. memento.used.tail = NULL;
  1428. memento.free.head = NULL;
  1429. memento.free.tail = NULL;
  1430. memento.sequence = 0;
  1431. memento.countdown = 1024;
  1432. env = getenv("MEMENTO_FAILAT");
  1433. memento.failAt = (env ? atoi(env) : 0);
  1434. env = getenv("MEMENTO_BREAKAT");
  1435. memento.breakAt = (env ? atoi(env) : 0);
  1436. env = getenv("MEMENTO_PARANOIA");
  1437. memento.paranoia = (env ? atoi(env) : 0);
  1438. if (memento.paranoia == 0)
  1439. memento.paranoia = -1024;
  1440. env = getenv("MEMENTO_PARANOIDAT");
  1441. memento.paranoidAt = (env ? atoi(env) : 0);
  1442. env = getenv("MEMENTO_SQUEEZEAT");
  1443. memento.squeezeAt = (env ? atoi(env) : 0);
  1444. env = getenv("MEMENTO_PATTERN");
  1445. memento.pattern = (env ? atoi(env) : 0);
  1446. env = getenv("MEMENTO_MAXMEMORY");
  1447. memento.maxMemory = (env ? atoi(env) : 0);
  1448. atexit(Memento_fin);
  1449. Memento_initMutex(&memento.mutex);
  1450. Memento_initStacktracer();
  1451. Memento_breakpoint();
  1452. }
  1453. typedef struct findBlkData {
  1454. void *addr;
  1455. Memento_BlkHeader *blk;
  1456. int flags;
  1457. } findBlkData;
  1458. static int Memento_containsAddr(Memento_BlkHeader *b,
  1459. void *arg)
  1460. {
  1461. findBlkData *data = (findBlkData *)arg;
  1462. char *blkend = &((char *)MEMBLK_TOBLK(b))[b->rawsize];
  1463. if ((MEMBLK_TOBLK(b) <= data->addr) &&
  1464. ((void *)blkend > data->addr)) {
  1465. data->blk = b;
  1466. data->flags = 1;
  1467. return 1;
  1468. }
  1469. if (((void *)b <= data->addr) &&
  1470. (MEMBLK_TOBLK(b) > data->addr)) {
  1471. data->blk = b;
  1472. data->flags = 2;
  1473. return 1;
  1474. }
  1475. if (((void *)blkend <= data->addr) &&
  1476. ((void *)(blkend + Memento_PostSize) > data->addr)) {
  1477. data->blk = b;
  1478. data->flags = 3;
  1479. return 1;
  1480. }
  1481. return 0;
  1482. }
  1483. void Memento_info(void *addr)
  1484. {
  1485. #ifdef MEMENTO_DETAILS
  1486. findBlkData data;
  1487. MEMENTO_LOCK();
  1488. data.addr = addr;
  1489. data.blk = NULL;
  1490. data.flags = 0;
  1491. Memento_appBlocks(&memento.used, Memento_containsAddr, &data);
  1492. if (data.blk != NULL)
  1493. showInfo(data.blk, NULL);
  1494. data.blk = NULL;
  1495. data.flags = 0;
  1496. Memento_appBlocks(&memento.free, Memento_containsAddr, &data);
  1497. if (data.blk != NULL)
  1498. showInfo(data.blk, NULL);
  1499. MEMENTO_UNLOCK();
  1500. #else
  1501. printf("Memento not compiled with details support\n");
  1502. #endif
  1503. }
  1504. #ifdef MEMENTO_HAS_FORK
  1505. #include <unistd.h>
  1506. #include <sys/wait.h>
  1507. #include <time.h>
  1508. #ifdef MEMENTO_STACKTRACE_METHOD
  1509. #if MEMENTO_STACKTRACE_METHOD == 1
  1510. #include <signal.h>
  1511. #endif
  1512. #endif
  1513. /* FIXME: Find some portable way of getting this */
  1514. /* MacOSX has 10240, Ubuntu seems to have 256 */
  1515. #ifndef OPEN_MAX
  1516. #define OPEN_MAX 10240
  1517. #endif
  1518. /* stashed_map[j] = i means that file descriptor i-1 was duplicated to j */
  1519. int stashed_map[OPEN_MAX];
  1520. static void Memento_signal(int sig)
  1521. {
  1522. (void)sig;
  1523. fprintf(stderr, "SEGV at:\n");
  1524. memento.segv = 1;
  1525. Memento_bt_internal(0);
  1526. exit(1);
  1527. }
  1528. static int squeeze(void)
  1529. {
  1530. pid_t pid;
  1531. int i, status;
  1532. if (memento.patternBit < 0)
  1533. return 1;
  1534. if (memento.squeezing && memento.patternBit >= MEMENTO_MAXPATTERN)
  1535. return 1;
  1536. if (memento.patternBit == 0)
  1537. memento.squeezeAt = memento.sequence;
  1538. if (!memento.squeezing) {
  1539. fprintf(stderr, "Memory squeezing @ %d\n", memento.squeezeAt);
  1540. } else
  1541. fprintf(stderr, "Memory squeezing @ %d (%x,%x)\n", memento.squeezeAt, memento.pattern, memento.patternBit);
  1542. /* When we fork below, the child is going to snaffle all our file pointers
  1543. * and potentially corrupt them. Let's make copies of all of them before
  1544. * we fork, so we can restore them when we restart. */
  1545. for (i = 0; i < OPEN_MAX; i++) {
  1546. if (stashed_map[i] == 0) {
  1547. int j = dup(i);
  1548. stashed_map[j] = i+1;
  1549. }
  1550. }
  1551. fprintf(stderr, "Failing at:\n");
  1552. Memento_bt_internal(2);
  1553. pid = fork();
  1554. if (pid == 0) {
  1555. /* Child */
  1556. signal(SIGSEGV, Memento_signal);
  1557. /* In the child, we always fail the next allocation. */
  1558. if (memento.patternBit == 0) {
  1559. memento.patternBit = 1;
  1560. } else
  1561. memento.patternBit <<= 1;
  1562. memento.squeezing = 1;
  1563. return 1;
  1564. }
  1565. /* In the parent if we hit another allocation, pass it (and record the
  1566. * fact we passed it in the pattern. */
  1567. memento.pattern |= memento.patternBit;
  1568. memento.patternBit <<= 1;
  1569. /* Wait for pid to finish, with a timeout. */
  1570. {
  1571. struct timespec tm = { 0, 10 * 1000 * 1000 }; /* 10ms = 100th sec */
  1572. int timeout = 30 * 1000 * 1000; /* time out in microseconds! */
  1573. while (waitpid(pid, &status, WNOHANG) == 0) {
  1574. nanosleep(&tm, NULL);
  1575. timeout -= (tm.tv_nsec/1000);
  1576. tm.tv_nsec *= 2;
  1577. if (tm.tv_nsec > 999999999)
  1578. tm.tv_nsec = 999999999;
  1579. if (timeout <= 0) {
  1580. char text[32];
  1581. fprintf(stderr, "Child is taking a long time to die. Killing it.\n");
  1582. sprintf(text, "kill %d", pid);
  1583. system(text);
  1584. break;
  1585. }
  1586. }
  1587. }
  1588. if (status != 0) {
  1589. fprintf(stderr, "Child status=%d\n", status);
  1590. }
  1591. /* Put the files back */
  1592. for (i = 0; i < OPEN_MAX; i++) {
  1593. if (stashed_map[i] != 0) {
  1594. dup2(i, stashed_map[i]-1);
  1595. close(i);
  1596. stashed_map[i] = 0;
  1597. }
  1598. }
  1599. return 0;
  1600. }
  1601. #else
  1602. #include <signal.h>
  1603. static void Memento_signal(int sig)
  1604. {
  1605. (void)sig;
  1606. memento.segv = 1;
  1607. /* If we just return from this function the SEGV will be unhandled, and
  1608. * we'll launch into whatever JIT debugging system the OS provides. At
  1609. * least fprintf(stderr, something useful first. If MEMENTO_NOJIT is set, then
  1610. * just exit to avoid the JIT (and get the usual atexit handling). */
  1611. if (getenv("MEMENTO_NOJIT"))
  1612. exit(1);
  1613. else
  1614. Memento_fin();
  1615. }
  1616. static int squeeze(void)
  1617. {
  1618. fprintf(stderr, "Memento memory squeezing disabled as no fork!\n");
  1619. return 0;
  1620. }
  1621. #endif
  1622. static void Memento_startFailing(void)
  1623. {
  1624. if (!memento.failing) {
  1625. fprintf(stderr, "Starting to fail...\n");
  1626. Memento_bt();
  1627. fflush(stderr);
  1628. memento.failing = 1;
  1629. memento.failAt = memento.sequence;
  1630. memento.nextFailAt = memento.sequence+1;
  1631. memento.pattern = 0;
  1632. memento.patternBit = 0;
  1633. signal(SIGSEGV, Memento_signal);
  1634. signal(SIGABRT, Memento_signal);
  1635. Memento_breakpointLocked();
  1636. }
  1637. }
  1638. static int Memento_event(void)
  1639. {
  1640. memento.sequence++;
  1641. if ((memento.sequence >= memento.paranoidAt) && (memento.paranoidAt != 0)) {
  1642. memento.paranoia = 1;
  1643. memento.countdown = 1;
  1644. }
  1645. if (--memento.countdown == 0) {
  1646. Memento_checkAllMemoryLocked();
  1647. if (memento.paranoia > 0)
  1648. memento.countdown = memento.paranoia;
  1649. else
  1650. {
  1651. memento.countdown = -memento.paranoia;
  1652. if (memento.paranoia > INT_MIN/2)
  1653. memento.paranoia *= 2;
  1654. }
  1655. }
  1656. if (memento.sequence == memento.breakAt) {
  1657. fprintf(stderr, "Breaking at event %d\n", memento.breakAt);
  1658. return 1;
  1659. }
  1660. return 0;
  1661. }
  1662. int Memento_sequence(void)
  1663. {
  1664. return memento.sequence;
  1665. }
  1666. int Memento_breakAt(int event)
  1667. {
  1668. MEMENTO_LOCK();
  1669. memento.breakAt = event;
  1670. MEMENTO_UNLOCK();
  1671. return event;
  1672. }
  1673. static void *safe_find_block(void *ptr)
  1674. {
  1675. Memento_BlkHeader *block;
  1676. int valid;
  1677. if (ptr == NULL)
  1678. return NULL;
  1679. block = MEMBLK_FROMBLK(ptr);
  1680. /* Sometimes wrapping allocators can mean Memento_label
  1681. * is called with a value within the block, rather than
  1682. * at the start of the block. If we detect this, find it
  1683. * the slow way. */
  1684. VALGRIND_MAKE_MEM_DEFINED(&block->child, sizeof(block->child));
  1685. VALGRIND_MAKE_MEM_DEFINED(&block->sibling, sizeof(block->sibling));
  1686. valid = (block->child == MEMENTO_CHILD_MAGIC &&
  1687. block->sibling == MEMENTO_SIBLING_MAGIC);
  1688. VALGRIND_MAKE_MEM_NOACCESS(&block->child, sizeof(block->child));
  1689. VALGRIND_MAKE_MEM_NOACCESS(&block->sibling, sizeof(block->sibling));
  1690. if (!valid)
  1691. {
  1692. findBlkData data;
  1693. data.addr = ptr;
  1694. data.blk = NULL;
  1695. data.flags = 0;
  1696. Memento_appBlocks(&memento.used, Memento_containsAddr, &data);
  1697. if (data.blk == NULL)
  1698. return NULL;
  1699. block = data.blk;
  1700. }
  1701. return block;
  1702. }
  1703. void *Memento_label(void *ptr, const char *label)
  1704. {
  1705. Memento_BlkHeader *block;
  1706. if (ptr == NULL)
  1707. return NULL;
  1708. MEMENTO_LOCK();
  1709. block = safe_find_block(ptr);
  1710. if (block != NULL)
  1711. {
  1712. VALGRIND_MAKE_MEM_DEFINED(&block->label, sizeof(block->label));
  1713. block->label = label;
  1714. VALGRIND_MAKE_MEM_NOACCESS(&block->label, sizeof(block->label));
  1715. }
  1716. MEMENTO_UNLOCK();
  1717. return ptr;
  1718. }
  1719. void Memento_tick(void)
  1720. {
  1721. MEMENTO_LOCK();
  1722. if (Memento_event()) Memento_breakpointLocked();
  1723. MEMENTO_UNLOCK();
  1724. }
  1725. static int Memento_failThisEventLocked(void)
  1726. {
  1727. int failThisOne;
  1728. if (Memento_event()) Memento_breakpointLocked();
  1729. if ((memento.sequence >= memento.failAt) && (memento.failAt != 0))
  1730. Memento_startFailing();
  1731. if ((memento.sequence >= memento.squeezeAt) && (memento.squeezeAt != 0)) {
  1732. return squeeze();
  1733. }
  1734. if (!memento.failing)
  1735. return 0;
  1736. failThisOne = ((memento.patternBit & memento.pattern) == 0);
  1737. /* If we are failing, and we've reached the end of the pattern and we've
  1738. * still got bits available in the pattern word, and we haven't already
  1739. * set a nextPattern, then extend the pattern. */
  1740. if (memento.failing &&
  1741. ((~(memento.patternBit-1) & memento.pattern) == 0) &&
  1742. (memento.patternBit != 0) &&
  1743. memento.nextPattern == 0)
  1744. {
  1745. /* We'll fail this one, and set the 'next' one to pass it. */
  1746. memento.nextFailAt = memento.failAt;
  1747. memento.nextPattern = memento.pattern | memento.patternBit;
  1748. }
  1749. memento.patternBit = (memento.patternBit ? memento.patternBit << 1 : 1);
  1750. return failThisOne;
  1751. }
  1752. int Memento_failThisEvent(void)
  1753. {
  1754. int ret;
  1755. if (!memento.inited)
  1756. Memento_init();
  1757. MEMENTO_LOCK();
  1758. ret = Memento_failThisEventLocked();
  1759. MEMENTO_UNLOCK();
  1760. return ret;
  1761. }
  1762. static void *do_malloc(size_t s, int eventType)
  1763. {
  1764. Memento_BlkHeader *memblk;
  1765. size_t smem = MEMBLK_SIZE(s);
  1766. if (Memento_failThisEventLocked())
  1767. return NULL;
  1768. if (s == 0)
  1769. return NULL;
  1770. memento.numMallocs++;
  1771. if (memento.maxMemory != 0 && memento.alloc + s > memento.maxMemory)
  1772. return NULL;
  1773. memblk = MEMENTO_UNDERLYING_MALLOC(smem);
  1774. if (memblk == NULL)
  1775. return NULL;
  1776. memento.alloc += s;
  1777. memento.totalAlloc += s;
  1778. if (memento.peakAlloc < memento.alloc)
  1779. memento.peakAlloc = memento.alloc;
  1780. #ifndef MEMENTO_LEAKONLY
  1781. memset(MEMBLK_TOBLK(memblk), MEMENTO_ALLOCFILL, s);
  1782. #endif
  1783. memblk->rawsize = s;
  1784. memblk->sequence = memento.sequence;
  1785. memblk->lastCheckedOK = memblk->sequence;
  1786. memblk->flags = 0;
  1787. memblk->label = 0;
  1788. memblk->child = MEMENTO_CHILD_MAGIC;
  1789. memblk->sibling = MEMENTO_SIBLING_MAGIC;
  1790. #ifdef MEMENTO_DETAILS
  1791. memblk->details = NULL;
  1792. memblk->details_tail = &memblk->details;
  1793. Memento_storeDetails(memblk, Memento_EventType_malloc);
  1794. #endif /* MEMENTO_DETAILS */
  1795. Memento_addBlockHead(&memento.used, memblk, 0);
  1796. if (memento.leaking > 0)
  1797. memblk->flags |= Memento_Flag_KnownLeak;
  1798. return MEMBLK_TOBLK(memblk);
  1799. }
  1800. void *Memento_malloc(size_t s)
  1801. {
  1802. void *ret;
  1803. if (!memento.inited)
  1804. Memento_init();
  1805. MEMENTO_LOCK();
  1806. ret = do_malloc(s, Memento_EventType_malloc);
  1807. MEMENTO_UNLOCK();
  1808. return ret;
  1809. }
  1810. void *Memento_calloc(size_t n, size_t s)
  1811. {
  1812. void *block;
  1813. if (!memento.inited)
  1814. Memento_init();
  1815. MEMENTO_LOCK();
  1816. block = do_malloc(n*s, Memento_EventType_calloc);
  1817. if (block)
  1818. memset(block, 0, n*s);
  1819. MEMENTO_UNLOCK();
  1820. return block;
  1821. }
  1822. static void do_reference(Memento_BlkHeader *blk, int event)
  1823. {
  1824. #ifdef MEMENTO_DETAILS
  1825. Memento_storeDetails(blk, event);
  1826. #endif /* MEMENTO_DETAILS */
  1827. }
  1828. int Memento_checkPointerOrNull(void *blk)
  1829. {
  1830. if (blk == NULL)
  1831. return 0;
  1832. if (blk == MEMENTO_PREFILL_PTR)
  1833. fprintf(stderr, "Prefill value found as pointer - buffer underrun?\n");
  1834. else if (blk == MEMENTO_POSTFILL_PTR)
  1835. fprintf(stderr, "Postfill value found as pointer - buffer overrun?\n");
  1836. else if (blk == MEMENTO_ALLOCFILL_PTR)
  1837. fprintf(stderr, "Allocfill value found as pointer - use of uninitialised value?\n");
  1838. else if (blk == MEMENTO_FREEFILL_PTR)
  1839. fprintf(stderr, "Allocfill value found as pointer - use after free?\n");
  1840. else
  1841. return 0;
  1842. #ifdef MEMENTO_DETAILS
  1843. fprintf(stderr, "Current backtrace:\n");
  1844. Memento_bt();
  1845. fprintf(stderr, "History:\n");
  1846. Memento_info(blk);
  1847. #endif
  1848. return 1;
  1849. }
  1850. int Memento_checkBytePointerOrNull(void *blk)
  1851. {
  1852. unsigned char i;
  1853. if (blk == NULL)
  1854. return 0;
  1855. Memento_checkPointerOrNull(blk);
  1856. i = *(unsigned int *)blk;
  1857. if (i == MEMENTO_PREFILL_UBYTE)
  1858. fprintf(stderr, "Prefill value found - buffer underrun?\n");
  1859. else if (i == MEMENTO_POSTFILL_UBYTE)
  1860. fprintf(stderr, "Postfill value found - buffer overrun?\n");
  1861. else if (i == MEMENTO_ALLOCFILL_UBYTE)
  1862. fprintf(stderr, "Allocfill value found - use of uninitialised value?\n");
  1863. else if (i == MEMENTO_FREEFILL_UBYTE)
  1864. fprintf(stderr, "Allocfill value found - use after free?\n");
  1865. else
  1866. return 0;
  1867. #ifdef MEMENTO_DETAILS
  1868. fprintf(stderr, "Current backtrace:\n");
  1869. Memento_bt();
  1870. fprintf(stderr, "History:\n");
  1871. Memento_info(blk);
  1872. #endif
  1873. Memento_breakpoint();
  1874. return 1;
  1875. }
  1876. int Memento_checkShortPointerOrNull(void *blk)
  1877. {
  1878. unsigned short i;
  1879. if (blk == NULL)
  1880. return 0;
  1881. Memento_checkPointerOrNull(blk);
  1882. i = *(unsigned short *)blk;
  1883. if (i == MEMENTO_PREFILL_USHORT)
  1884. fprintf(stderr, "Prefill value found - buffer underrun?\n");
  1885. else if (i == MEMENTO_POSTFILL_USHORT)
  1886. fprintf(stderr, "Postfill value found - buffer overrun?\n");
  1887. else if (i == MEMENTO_ALLOCFILL_USHORT)
  1888. fprintf(stderr, "Allocfill value found - use of uninitialised value?\n");
  1889. else if (i == MEMENTO_FREEFILL_USHORT)
  1890. fprintf(stderr, "Allocfill value found - use after free?\n");
  1891. else
  1892. return 0;
  1893. #ifdef MEMENTO_DETAILS
  1894. fprintf(stderr, "Current backtrace:\n");
  1895. Memento_bt();
  1896. fprintf(stderr, "History:\n");
  1897. Memento_info(blk);
  1898. #endif
  1899. Memento_breakpoint();
  1900. return 1;
  1901. }
  1902. int Memento_checkIntPointerOrNull(void *blk)
  1903. {
  1904. unsigned int i;
  1905. if (blk == NULL)
  1906. return 0;
  1907. Memento_checkPointerOrNull(blk);
  1908. i = *(unsigned int *)blk;
  1909. if (i == MEMENTO_PREFILL_UINT)
  1910. fprintf(stderr, "Prefill value found - buffer underrun?\n");
  1911. else if (i == MEMENTO_POSTFILL_UINT)
  1912. fprintf(stderr, "Postfill value found - buffer overrun?\n");
  1913. else if (i == MEMENTO_ALLOCFILL_UINT)
  1914. fprintf(stderr, "Allocfill value found - use of uninitialised value?\n");
  1915. else if (i == MEMENTO_FREEFILL_UINT)
  1916. fprintf(stderr, "Allocfill value found - use after free?\n");
  1917. else
  1918. return 0;
  1919. #ifdef MEMENTO_DETAILS
  1920. fprintf(stderr, "Current backtrace:\n");
  1921. Memento_bt();
  1922. fprintf(stderr, "History:\n");
  1923. Memento_info(blk);
  1924. #endif
  1925. Memento_breakpoint();
  1926. return 1;
  1927. }
  1928. static void *do_takeRef(void *blk)
  1929. {
  1930. MEMENTO_LOCK();
  1931. do_reference(safe_find_block(blk), Memento_EventType_takeRef);
  1932. MEMENTO_UNLOCK();
  1933. return blk;
  1934. }
  1935. void *Memento_takeByteRef(void *blk)
  1936. {
  1937. if (!memento.inited)
  1938. Memento_init();
  1939. if (Memento_event()) Memento_breakpoint();
  1940. if (!blk)
  1941. return NULL;
  1942. (void)Memento_checkBytePointerOrNull(blk);
  1943. return do_takeRef(blk);
  1944. }
  1945. void *Memento_takeShortRef(void *blk)
  1946. {
  1947. if (!memento.inited)
  1948. Memento_init();
  1949. if (Memento_event()) Memento_breakpoint();
  1950. if (!blk)
  1951. return NULL;
  1952. (void)Memento_checkShortPointerOrNull(blk);
  1953. return do_takeRef(blk);
  1954. }
  1955. void *Memento_takeIntRef(void *blk)
  1956. {
  1957. if (!memento.inited)
  1958. Memento_init();
  1959. if (Memento_event()) Memento_breakpoint();
  1960. if (!blk)
  1961. return NULL;
  1962. (void)Memento_checkIntPointerOrNull(blk);
  1963. return do_takeRef(blk);
  1964. }
  1965. void *Memento_takeRef(void *blk)
  1966. {
  1967. if (!memento.inited)
  1968. Memento_init();
  1969. if (Memento_event()) Memento_breakpoint();
  1970. if (!blk)
  1971. return NULL;
  1972. return do_takeRef(blk);
  1973. }
  1974. static void *do_dropRef(void *blk)
  1975. {
  1976. MEMENTO_LOCK();
  1977. do_reference(safe_find_block(blk), Memento_EventType_dropRef);
  1978. MEMENTO_UNLOCK();
  1979. return blk;
  1980. }
  1981. void *Memento_dropByteRef(void *blk)
  1982. {
  1983. if (!memento.inited)
  1984. Memento_init();
  1985. if (Memento_event()) Memento_breakpoint();
  1986. if (!blk)
  1987. return NULL;
  1988. Memento_checkBytePointerOrNull(blk);
  1989. return do_dropRef(blk);
  1990. }
  1991. void *Memento_dropShortRef(void *blk)
  1992. {
  1993. if (!memento.inited)
  1994. Memento_init();
  1995. if (Memento_event()) Memento_breakpoint();
  1996. if (!blk)
  1997. return NULL;
  1998. Memento_checkShortPointerOrNull(blk);
  1999. return do_dropRef(blk);
  2000. }
  2001. void *Memento_dropIntRef(void *blk)
  2002. {
  2003. if (!memento.inited)
  2004. Memento_init();
  2005. if (Memento_event()) Memento_breakpoint();
  2006. if (!blk)
  2007. return NULL;
  2008. Memento_checkIntPointerOrNull(blk);
  2009. return do_dropRef(blk);
  2010. }
  2011. void *Memento_dropRef(void *blk)
  2012. {
  2013. if (!memento.inited)
  2014. Memento_init();
  2015. if (Memento_event()) Memento_breakpoint();
  2016. if (!blk)
  2017. return NULL;
  2018. return do_dropRef(blk);
  2019. }
  2020. void *Memento_adjustRef(void *blk, int adjust)
  2021. {
  2022. if (Memento_event()) Memento_breakpoint();
  2023. if (blk == NULL)
  2024. return NULL;
  2025. while (adjust > 0)
  2026. {
  2027. do_takeRef(blk);
  2028. adjust--;
  2029. }
  2030. while (adjust < 0)
  2031. {
  2032. do_dropRef(blk);
  2033. adjust++;
  2034. }
  2035. return blk;
  2036. }
  2037. void *Memento_reference(void *blk)
  2038. {
  2039. if (!blk)
  2040. return NULL;
  2041. if (!memento.inited)
  2042. Memento_init();
  2043. MEMENTO_LOCK();
  2044. do_reference(safe_find_block(blk), Memento_EventType_reference);
  2045. MEMENTO_UNLOCK();
  2046. return blk;
  2047. }
  2048. /* Treat blocks from the user with suspicion, and check them the slow
  2049. * but safe way. */
  2050. static int checkBlockUser(Memento_BlkHeader *memblk, const char *action)
  2051. {
  2052. #ifndef MEMENTO_LEAKONLY
  2053. BlkCheckData data;
  2054. memset(&data, 0, sizeof(data));
  2055. Memento_appBlockUser(&memento.used, Memento_Internal_checkAllocedBlock,
  2056. &data, memblk);
  2057. if (!data.found) {
  2058. /* Failure! */
  2059. fprintf(stderr, "Attempt to %s block ", action);
  2060. showBlock(memblk, 32);
  2061. fprintf(stderr, "\n");
  2062. Memento_breakpointLocked();
  2063. return 1;
  2064. } else if (data.preCorrupt || data.postCorrupt) {
  2065. fprintf(stderr, "Block ");
  2066. showBlock(memblk, ' ');
  2067. fprintf(stderr, " found to be corrupted on %s!\n", action);
  2068. if (data.preCorrupt) {
  2069. fprintf(stderr, "Preguard corrupted\n");
  2070. }
  2071. if (data.postCorrupt) {
  2072. fprintf(stderr, "Postguard corrupted\n");
  2073. }
  2074. fprintf(stderr, "Block last checked OK at allocation %d. Now %d.\n",
  2075. memblk->lastCheckedOK, memento.sequence);
  2076. if ((memblk->flags & Memento_Flag_Reported) == 0)
  2077. {
  2078. memblk->flags |= Memento_Flag_Reported;
  2079. Memento_breakpointLocked();
  2080. }
  2081. return 1;
  2082. }
  2083. #endif
  2084. return 0;
  2085. }
  2086. static int checkBlock(Memento_BlkHeader *memblk, const char *action)
  2087. {
  2088. #ifndef MEMENTO_LEAKONLY
  2089. BlkCheckData data;
  2090. #endif
  2091. if (memblk->child != MEMENTO_CHILD_MAGIC ||
  2092. memblk->sibling != MEMENTO_SIBLING_MAGIC)
  2093. {
  2094. /* Failure! */
  2095. fprintf(stderr, "Attempt to %s invalid block ", action);
  2096. showBlock(memblk, 32);
  2097. fprintf(stderr, "\n");
  2098. Memento_breakpointLocked();
  2099. return 1;
  2100. }
  2101. #ifndef MEMENTO_LEAKONLY
  2102. memset(&data, 0, sizeof(data));
  2103. Memento_appBlock(&memento.used, Memento_Internal_checkAllocedBlock,
  2104. &data, memblk);
  2105. if (!data.found) {
  2106. /* Failure! */
  2107. fprintf(stderr, "Attempt to %s block ", action);
  2108. showBlock(memblk, 32);
  2109. fprintf(stderr, "\n");
  2110. Memento_breakpointLocked();
  2111. return 1;
  2112. } else if (data.preCorrupt || data.postCorrupt) {
  2113. fprintf(stderr, "Block ");
  2114. showBlock(memblk, ' ');
  2115. fprintf(stderr, " found to be corrupted on %s!\n", action);
  2116. if (data.preCorrupt) {
  2117. fprintf(stderr, "Preguard corrupted\n");
  2118. }
  2119. if (data.postCorrupt) {
  2120. fprintf(stderr, "Postguard corrupted\n");
  2121. }
  2122. fprintf(stderr, "Block last checked OK at allocation %d. Now %d.\n",
  2123. memblk->lastCheckedOK, memento.sequence);
  2124. if ((memblk->flags & Memento_Flag_Reported) == 0)
  2125. {
  2126. memblk->flags |= Memento_Flag_Reported;
  2127. Memento_breakpointLocked();
  2128. }
  2129. return 1;
  2130. }
  2131. #endif
  2132. return 0;
  2133. }
  2134. static void do_free(void *blk, int eventType)
  2135. {
  2136. Memento_BlkHeader *memblk;
  2137. if (Memento_event()) Memento_breakpointLocked();
  2138. if (blk == NULL)
  2139. return;
  2140. memblk = MEMBLK_FROMBLK(blk);
  2141. VALGRIND_MAKE_MEM_DEFINED(memblk, sizeof(*memblk));
  2142. if (checkBlock(memblk, "free"))
  2143. return;
  2144. #ifdef MEMENTO_DETAILS
  2145. Memento_storeDetails(memblk, Memento_EventType_free);
  2146. #endif
  2147. VALGRIND_MAKE_MEM_DEFINED(memblk, sizeof(*memblk));
  2148. if (memblk->flags & Memento_Flag_BreakOnFree)
  2149. Memento_breakpointLocked();
  2150. memento.alloc -= memblk->rawsize;
  2151. memento.numFrees++;
  2152. Memento_removeBlock(&memento.used, memblk);
  2153. VALGRIND_MAKE_MEM_DEFINED(memblk, sizeof(*memblk));
  2154. if (Memento_Internal_makeSpace(MEMBLK_SIZE(memblk->rawsize))) {
  2155. VALGRIND_MAKE_MEM_DEFINED(memblk, sizeof(*memblk));
  2156. VALGRIND_MAKE_MEM_DEFINED(MEMBLK_TOBLK(memblk),
  2157. memblk->rawsize + Memento_PostSize);
  2158. #ifndef MEMENTO_LEAKONLY
  2159. memset(MEMBLK_TOBLK(memblk), MEMENTO_FREEFILL, memblk->rawsize);
  2160. #endif
  2161. memblk->flags |= Memento_Flag_Freed;
  2162. Memento_addBlockTail(&memento.free, memblk, 1);
  2163. } else {
  2164. free_block(memblk);
  2165. }
  2166. }
  2167. void Memento_free(void *blk)
  2168. {
  2169. if (!memento.inited)
  2170. Memento_init();
  2171. MEMENTO_LOCK();
  2172. do_free(blk, Memento_EventType_free);
  2173. MEMENTO_UNLOCK();
  2174. }
  2175. static void *do_realloc(void *blk, size_t newsize, int type)
  2176. {
  2177. Memento_BlkHeader *memblk, *newmemblk;
  2178. size_t newsizemem;
  2179. int flags;
  2180. if (Memento_failThisEventLocked())
  2181. return NULL;
  2182. memblk = MEMBLK_FROMBLK(blk);
  2183. VALGRIND_MAKE_MEM_DEFINED(memblk, sizeof(*memblk));
  2184. if (checkBlock(memblk, "realloc"))
  2185. return NULL;
  2186. #ifdef MEMENTO_DETAILS
  2187. Memento_storeDetails(memblk, type);
  2188. #endif
  2189. VALGRIND_MAKE_MEM_DEFINED(memblk, sizeof(*memblk));
  2190. if (memblk->flags & Memento_Flag_BreakOnRealloc)
  2191. Memento_breakpointLocked();
  2192. VALGRIND_MAKE_MEM_DEFINED(memblk, sizeof(*memblk));
  2193. if (memento.maxMemory != 0 && memento.alloc - memblk->rawsize + newsize > memento.maxMemory)
  2194. return NULL;
  2195. newsizemem = MEMBLK_SIZE(newsize);
  2196. Memento_removeBlock(&memento.used, memblk);
  2197. VALGRIND_MAKE_MEM_DEFINED(memblk, sizeof(*memblk));
  2198. flags = memblk->flags;
  2199. newmemblk = MEMENTO_UNDERLYING_REALLOC(memblk, newsizemem);
  2200. if (newmemblk == NULL)
  2201. {
  2202. Memento_addBlockHead(&memento.used, memblk, 2);
  2203. return NULL;
  2204. }
  2205. memento.numReallocs++;
  2206. memento.totalAlloc += newsize;
  2207. memento.alloc -= newmemblk->rawsize;
  2208. memento.alloc += newsize;
  2209. if (memento.peakAlloc < memento.alloc)
  2210. memento.peakAlloc = memento.alloc;
  2211. newmemblk->flags = flags;
  2212. #ifndef MEMENTO_LEAKONLY
  2213. if (newmemblk->rawsize < newsize) {
  2214. char *newbytes = ((char *)MEMBLK_TOBLK(newmemblk))+newmemblk->rawsize;
  2215. VALGRIND_MAKE_MEM_DEFINED(newbytes, newsize - newmemblk->rawsize);
  2216. memset(newbytes, MEMENTO_ALLOCFILL, newsize - newmemblk->rawsize);
  2217. VALGRIND_MAKE_MEM_UNDEFINED(newbytes, newsize - newmemblk->rawsize);
  2218. }
  2219. #endif
  2220. newmemblk->rawsize = newsize;
  2221. #ifndef MEMENTO_LEAKONLY
  2222. VALGRIND_MAKE_MEM_DEFINED(newmemblk->preblk, Memento_PreSize);
  2223. memset(newmemblk->preblk, MEMENTO_PREFILL, Memento_PreSize);
  2224. VALGRIND_MAKE_MEM_UNDEFINED(newmemblk->preblk, Memento_PreSize);
  2225. VALGRIND_MAKE_MEM_DEFINED(MEMBLK_POSTPTR(newmemblk), Memento_PostSize);
  2226. memset(MEMBLK_POSTPTR(newmemblk), MEMENTO_POSTFILL, Memento_PostSize);
  2227. VALGRIND_MAKE_MEM_UNDEFINED(MEMBLK_POSTPTR(newmemblk), Memento_PostSize);
  2228. #endif
  2229. Memento_addBlockHead(&memento.used, newmemblk, 2);
  2230. return MEMBLK_TOBLK(newmemblk);
  2231. }
  2232. void *Memento_realloc(void *blk, size_t newsize)
  2233. {
  2234. void *ret;
  2235. if (!memento.inited)
  2236. Memento_init();
  2237. if (blk == NULL)
  2238. {
  2239. MEMENTO_LOCK();
  2240. ret = do_malloc(newsize, Memento_EventType_realloc);
  2241. MEMENTO_UNLOCK();
  2242. return ret;
  2243. }
  2244. if (newsize == 0) {
  2245. MEMENTO_LOCK();
  2246. do_free(blk, Memento_EventType_realloc);
  2247. MEMENTO_UNLOCK();
  2248. return NULL;
  2249. }
  2250. MEMENTO_LOCK();
  2251. ret = do_realloc(blk, newsize, Memento_EventType_realloc);
  2252. MEMENTO_UNLOCK();
  2253. return ret;
  2254. }
  2255. int Memento_checkBlock(void *blk)
  2256. {
  2257. Memento_BlkHeader *memblk;
  2258. int ret;
  2259. if (blk == NULL)
  2260. return 0;
  2261. MEMENTO_LOCK();
  2262. memblk = MEMBLK_FROMBLK(blk);
  2263. ret = checkBlockUser(memblk, "check");
  2264. MEMENTO_UNLOCK();
  2265. return ret;
  2266. }
  2267. #ifndef MEMENTO_LEAKONLY
  2268. static int Memento_Internal_checkAllAlloced(Memento_BlkHeader *memblk, void *arg)
  2269. {
  2270. BlkCheckData *data = (BlkCheckData *)arg;
  2271. Memento_Internal_checkAllocedBlock(memblk, data);
  2272. if (data->preCorrupt || data->postCorrupt) {
  2273. if ((data->found & 2) == 0) {
  2274. fprintf(stderr, "Allocated blocks:\n");
  2275. data->found |= 2;
  2276. }
  2277. fprintf(stderr, " Block ");
  2278. showBlock(memblk, ' ');
  2279. if (data->preCorrupt) {
  2280. fprintf(stderr, " Preguard ");
  2281. }
  2282. if (data->postCorrupt) {
  2283. fprintf(stderr, "%s Postguard ",
  2284. (data->preCorrupt ? "&" : ""));
  2285. }
  2286. fprintf(stderr, "corrupted.\n "
  2287. "Block last checked OK at allocation %d. Now %d.\n",
  2288. memblk->lastCheckedOK, memento.sequence);
  2289. data->preCorrupt = 0;
  2290. data->postCorrupt = 0;
  2291. data->freeCorrupt = 0;
  2292. if ((memblk->flags & Memento_Flag_Reported) == 0)
  2293. {
  2294. memblk->flags |= Memento_Flag_Reported;
  2295. Memento_breakpointLocked();
  2296. }
  2297. }
  2298. else
  2299. memblk->lastCheckedOK = memento.sequence;
  2300. return 0;
  2301. }
  2302. static int Memento_Internal_checkAllFreed(Memento_BlkHeader *memblk, void *arg)
  2303. {
  2304. BlkCheckData *data = (BlkCheckData *)arg;
  2305. Memento_Internal_checkFreedBlock(memblk, data);
  2306. if (data->preCorrupt || data->postCorrupt || data->freeCorrupt) {
  2307. if ((data->found & 4) == 0) {
  2308. fprintf(stderr, "Freed blocks:\n");
  2309. data->found |= 4;
  2310. }
  2311. fprintf(stderr, " ");
  2312. showBlock(memblk, ' ');
  2313. if (data->freeCorrupt) {
  2314. fprintf(stderr, " index %d (address "FMTP") onwards", (int)data->index,
  2315. &((char *)MEMBLK_TOBLK(memblk))[data->index]);
  2316. if (data->preCorrupt) {
  2317. fprintf(stderr, "+ preguard");
  2318. }
  2319. if (data->postCorrupt) {
  2320. fprintf(stderr, "+ postguard");
  2321. }
  2322. } else {
  2323. if (data->preCorrupt) {
  2324. fprintf(stderr, " preguard");
  2325. }
  2326. if (data->postCorrupt) {
  2327. fprintf(stderr, "%s Postguard",
  2328. (data->preCorrupt ? "+" : ""));
  2329. }
  2330. }
  2331. VALGRIND_MAKE_MEM_DEFINED(memblk, sizeof(Memento_BlkHeader));
  2332. fprintf(stderr, " corrupted.\n"
  2333. " Block last checked OK at allocation %d. Now %d.\n",
  2334. memblk->lastCheckedOK, memento.sequence);
  2335. if ((memblk->flags & Memento_Flag_Reported) == 0)
  2336. {
  2337. memblk->flags |= Memento_Flag_Reported;
  2338. Memento_breakpointLocked();
  2339. }
  2340. VALGRIND_MAKE_MEM_NOACCESS(memblk, sizeof(Memento_BlkHeader));
  2341. data->preCorrupt = 0;
  2342. data->postCorrupt = 0;
  2343. data->freeCorrupt = 0;
  2344. }
  2345. else
  2346. memblk->lastCheckedOK = memento.sequence;
  2347. return 0;
  2348. }
  2349. #endif /* MEMENTO_LEAKONLY */
  2350. static int Memento_checkAllMemoryLocked(void)
  2351. {
  2352. #ifndef MEMENTO_LEAKONLY
  2353. BlkCheckData data;
  2354. memset(&data, 0, sizeof(data));
  2355. Memento_appBlocks(&memento.used, Memento_Internal_checkAllAlloced, &data);
  2356. Memento_appBlocks(&memento.free, Memento_Internal_checkAllFreed, &data);
  2357. return data.found;
  2358. #else
  2359. return 0;
  2360. #endif
  2361. }
  2362. int Memento_checkAllMemory(void)
  2363. {
  2364. #ifndef MEMENTO_LEAKONLY
  2365. int ret;
  2366. MEMENTO_LOCK();
  2367. ret = Memento_checkAllMemoryLocked();
  2368. MEMENTO_UNLOCK();
  2369. if (ret & 6) {
  2370. Memento_breakpoint();
  2371. return 1;
  2372. }
  2373. return 0;
  2374. #endif
  2375. }
  2376. int Memento_setParanoia(int i)
  2377. {
  2378. memento.paranoia = i;
  2379. if (memento.paranoia > 0)
  2380. memento.countdown = memento.paranoia;
  2381. else
  2382. memento.countdown = -memento.paranoia;
  2383. return i;
  2384. }
  2385. int Memento_paranoidAt(int i)
  2386. {
  2387. memento.paranoidAt = i;
  2388. return i;
  2389. }
  2390. int Memento_getBlockNum(void *b)
  2391. {
  2392. Memento_BlkHeader *memblk;
  2393. if (b == NULL)
  2394. return 0;
  2395. memblk = MEMBLK_FROMBLK(b);
  2396. return (memblk->sequence);
  2397. }
  2398. int Memento_check(void)
  2399. {
  2400. int result;
  2401. fprintf(stderr, "Checking memory\n");
  2402. result = Memento_checkAllMemory();
  2403. fprintf(stderr, "Memory checked!\n");
  2404. return result;
  2405. }
  2406. int Memento_find(void *a)
  2407. {
  2408. findBlkData data;
  2409. int s;
  2410. MEMENTO_LOCK();
  2411. data.addr = a;
  2412. data.blk = NULL;
  2413. data.flags = 0;
  2414. Memento_appBlocks(&memento.used, Memento_containsAddr, &data);
  2415. if (data.blk != NULL) {
  2416. fprintf(stderr, "Address "FMTP" is in %sallocated block ",
  2417. data.addr,
  2418. (data.flags == 1 ? "" : (data.flags == 2 ?
  2419. "preguard of " : "postguard of ")));
  2420. s = showBlock(data.blk, ' ');
  2421. fprintf(stderr, "\n");
  2422. MEMENTO_UNLOCK();
  2423. return s;
  2424. }
  2425. data.blk = NULL;
  2426. data.flags = 0;
  2427. Memento_appBlocks(&memento.free, Memento_containsAddr, &data);
  2428. if (data.blk != NULL) {
  2429. fprintf(stderr, "Address "FMTP" is in %sfreed block ",
  2430. data.addr,
  2431. (data.flags == 1 ? "" : (data.flags == 2 ?
  2432. "preguard of " : "postguard of ")));
  2433. s = showBlock(data.blk, ' ');
  2434. fprintf(stderr, "\n");
  2435. MEMENTO_UNLOCK();
  2436. return s;
  2437. }
  2438. MEMENTO_UNLOCK();
  2439. return 0;
  2440. }
  2441. void Memento_breakOnFree(void *a)
  2442. {
  2443. findBlkData data;
  2444. MEMENTO_LOCK();
  2445. data.addr = a;
  2446. data.blk = NULL;
  2447. data.flags = 0;
  2448. Memento_appBlocks(&memento.used, Memento_containsAddr, &data);
  2449. if (data.blk != NULL) {
  2450. fprintf(stderr, "Will stop when address "FMTP" (in %sallocated block ",
  2451. data.addr,
  2452. (data.flags == 1 ? "" : (data.flags == 2 ?
  2453. "preguard of " : "postguard of ")));
  2454. showBlock(data.blk, ' ');
  2455. fprintf(stderr, ") is freed\n");
  2456. VALGRIND_MAKE_MEM_DEFINED(data.blk, sizeof(Memento_BlkHeader));
  2457. data.blk->flags |= Memento_Flag_BreakOnFree;
  2458. VALGRIND_MAKE_MEM_NOACCESS(data.blk, sizeof(Memento_BlkHeader));
  2459. MEMENTO_UNLOCK();
  2460. return;
  2461. }
  2462. data.blk = NULL;
  2463. data.flags = 0;
  2464. Memento_appBlocks(&memento.free, Memento_containsAddr, &data);
  2465. if (data.blk != NULL) {
  2466. fprintf(stderr, "Can't stop on free; address "FMTP" is in %sfreed block ",
  2467. data.addr,
  2468. (data.flags == 1 ? "" : (data.flags == 2 ?
  2469. "preguard of " : "postguard of ")));
  2470. showBlock(data.blk, ' ');
  2471. fprintf(stderr, "\n");
  2472. MEMENTO_UNLOCK();
  2473. return;
  2474. }
  2475. fprintf(stderr, "Can't stop on free; address "FMTP" is not in a known block.\n", a);
  2476. MEMENTO_UNLOCK();
  2477. }
  2478. void Memento_breakOnRealloc(void *a)
  2479. {
  2480. findBlkData data;
  2481. MEMENTO_LOCK();
  2482. data.addr = a;
  2483. data.blk = NULL;
  2484. data.flags = 0;
  2485. Memento_appBlocks(&memento.used, Memento_containsAddr, &data);
  2486. if (data.blk != NULL) {
  2487. fprintf(stderr, "Will stop when address "FMTP" (in %sallocated block ",
  2488. data.addr,
  2489. (data.flags == 1 ? "" : (data.flags == 2 ?
  2490. "preguard of " : "postguard of ")));
  2491. showBlock(data.blk, ' ');
  2492. fprintf(stderr, ") is freed (or realloced)\n");
  2493. VALGRIND_MAKE_MEM_DEFINED(data.blk, sizeof(Memento_BlkHeader));
  2494. data.blk->flags |= Memento_Flag_BreakOnFree | Memento_Flag_BreakOnRealloc;
  2495. VALGRIND_MAKE_MEM_NOACCESS(data.blk, sizeof(Memento_BlkHeader));
  2496. MEMENTO_UNLOCK();
  2497. return;
  2498. }
  2499. data.blk = NULL;
  2500. data.flags = 0;
  2501. Memento_appBlocks(&memento.free, Memento_containsAddr, &data);
  2502. if (data.blk != NULL) {
  2503. fprintf(stderr, "Can't stop on free/realloc; address "FMTP" is in %sfreed block ",
  2504. data.addr,
  2505. (data.flags == 1 ? "" : (data.flags == 2 ?
  2506. "preguard of " : "postguard of ")));
  2507. showBlock(data.blk, ' ');
  2508. fprintf(stderr, "\n");
  2509. MEMENTO_UNLOCK();
  2510. return;
  2511. }
  2512. fprintf(stderr, "Can't stop on free/realloc; address "FMTP" is not in a known block.\n", a);
  2513. MEMENTO_UNLOCK();
  2514. }
  2515. int Memento_failAt(int i)
  2516. {
  2517. memento.failAt = i;
  2518. if ((memento.sequence > memento.failAt) &&
  2519. (memento.failing != 0))
  2520. Memento_startFailing();
  2521. return i;
  2522. }
  2523. size_t Memento_setMax(size_t max)
  2524. {
  2525. memento.maxMemory = max;
  2526. return max;
  2527. }
  2528. void Memento_startLeaking(void)
  2529. {
  2530. memento.leaking++;
  2531. }
  2532. void Memento_stopLeaking(void)
  2533. {
  2534. memento.leaking--;
  2535. }
  2536. int Memento_squeezing(void)
  2537. {
  2538. return memento.squeezing;
  2539. }
  2540. #endif /* MEMENTO_CPP_EXTRAS_ONLY */
  2541. #ifdef __cplusplus
  2542. /* Dumb overrides for the new and delete operators */
  2543. void *operator new(size_t size)
  2544. {
  2545. void *ret;
  2546. if (!memento.inited)
  2547. Memento_init();
  2548. if (size == 0)
  2549. size = 1;
  2550. MEMENTO_LOCK();
  2551. ret = do_malloc(size, Memento_EventType_new);
  2552. MEMENTO_UNLOCK();
  2553. return ret;
  2554. }
  2555. void operator delete(void *pointer)
  2556. {
  2557. if (!pointer)
  2558. return;
  2559. MEMENTO_LOCK();
  2560. do_free(pointer, Memento_EventType_delete);
  2561. MEMENTO_UNLOCK();
  2562. }
  2563. /* Some C++ systems (apparently) don't provide new[] or delete[]
  2564. * operators. Provide a way to cope with this */
  2565. #ifndef MEMENTO_CPP_NO_ARRAY_CONSTRUCTORS
  2566. void *operator new[](size_t size)
  2567. {
  2568. void *ret;
  2569. if (!memento.inited)
  2570. Memento_init();
  2571. if (size == 0)
  2572. size = 1;
  2573. MEMENTO_LOCK();
  2574. ret = do_malloc(size, Memento_EventType_newArray);
  2575. MEMENTO_UNLOCK();
  2576. return ret;
  2577. }
  2578. void operator delete[](void *pointer)
  2579. {
  2580. MEMENTO_LOCK();
  2581. do_free(pointer, Memento_EventType_deleteArray);
  2582. MEMENTO_UNLOCK();
  2583. }
  2584. #endif /* MEMENTO_CPP_NO_ARRAY_CONSTRUCTORS */
  2585. #endif /* __cplusplus */
  2586. #else
  2587. /* Just in case anyone has left some debugging code in... */
  2588. void (Memento_breakpoint)(void)
  2589. {
  2590. }
  2591. int (Memento_checkBlock)(void *b)
  2592. {
  2593. return 0;
  2594. }
  2595. int (Memento_checkAllMemory)(void)
  2596. {
  2597. return 0;
  2598. }
  2599. int (Memento_check)(void)
  2600. {
  2601. return 0;
  2602. }
  2603. int (Memento_setParanoia)(int i)
  2604. {
  2605. return 0;
  2606. }
  2607. int (Memento_paranoidAt)(int i)
  2608. {
  2609. return 0;
  2610. }
  2611. int (Memento_breakAt)(int i)
  2612. {
  2613. return 0;
  2614. }
  2615. int (Memento_getBlockNum)(void *i)
  2616. {
  2617. return 0;
  2618. }
  2619. int (Memento_find)(void *a)
  2620. {
  2621. return 0;
  2622. }
  2623. int (Memento_failAt)(int i)
  2624. {
  2625. return 0;
  2626. }
  2627. void (Memento_breakOnFree)(void *a)
  2628. {
  2629. }
  2630. void (Memento_breakOnRealloc)(void *a)
  2631. {
  2632. }
  2633. void *(Memento_takeRef)(void *a)
  2634. {
  2635. return a;
  2636. }
  2637. void *(Memento_dropRef)(void *a)
  2638. {
  2639. return a;
  2640. }
  2641. void *(Memento_adjustRef)(void *a, int adjust)
  2642. {
  2643. return a;
  2644. }
  2645. void *(Memento_reference)(void *a)
  2646. {
  2647. return a;
  2648. }
  2649. #undef Memento_malloc
  2650. #undef Memento_free
  2651. #undef Memento_realloc
  2652. #undef Memento_calloc
  2653. void *Memento_malloc(size_t size)
  2654. {
  2655. return MEMENTO_UNDERLYING_MALLOC(size);
  2656. }
  2657. void Memento_free(void *b)
  2658. {
  2659. MEMENTO_UNDERLYING_FREE(b);
  2660. }
  2661. void *Memento_realloc(void *b, size_t s)
  2662. {
  2663. return MEMENTO_UNDERLYING_REALLOC(b, s);
  2664. }
  2665. void *Memento_calloc(size_t n, size_t s)
  2666. {
  2667. return MEMENTO_UNDERLYING_CALLOC(n, s);
  2668. }
  2669. void (Memento_listBlocks)(void)
  2670. {
  2671. }
  2672. void (Memento_listNewBlocks)(void)
  2673. {
  2674. }
  2675. size_t (Memento_setMax)(size_t max)
  2676. {
  2677. return 0;
  2678. }
  2679. void (Memento_stats)(void)
  2680. {
  2681. }
  2682. void *(Memento_label)(void *ptr, const char *label)
  2683. {
  2684. return ptr;
  2685. }
  2686. void (Memento_info)(void *addr)
  2687. {
  2688. }
  2689. void (Memento_listBlockInfo)(void)
  2690. {
  2691. }
  2692. void (Memento_startLeaking)(void)
  2693. {
  2694. }
  2695. void (Memento_stopLeaking)(void)
  2696. {
  2697. }
  2698. int (Memento_squeezing)(void)
  2699. {
  2700. return 0;
  2701. }
  2702. #endif