1
0

heap.h 29 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052
  1. /*
  2. * heap.h
  3. */
  4. /**
  5. \ingroup lub
  6. \defgroup lub_heap heap
  7. @{
  8. \brief This is a generic heap manager which incorporates a memory leak detection system
  9. which can monitor and report the dynamic memory which is in use for each heap.
  10. A client creates an instance of heap; providing it with memory segments
  11. to manage. Subsequent operations can then be invoked to obtain memory
  12. from those registered segments.
  13. \section static_allocs Static allocation
  14. Static memory allocations are those which are for the lifetime of the
  15. heap from which they are allocated. Because they do not need to be freed
  16. there is zero overhead required for such blocks; they can be exactly butted
  17. up against each other in memory. There is also zero fragmentation as they
  18. are never freed.
  19. \section dynamic_allocs Dynamic allocation
  20. Dynamic memory allocations have a lifetime less than that of the heap
  21. from which they are allocated. In order to manage the reuse of this blocks
  22. once they are released, there will be a slight "housekeeping" overhead
  23. associated with each block. They are also suceptible to fragmentation, which
  24. can occur when the lifetimes of blocks differ from one another.
  25. \section leak_detection Leak Detection
  26. It monitors the dynamic allocation which are performed and maintains
  27. statistics to help identify and isolation memory leaks.
  28. It detects two types of leak by scanning the BSS and DATA segments and identifying
  29. any nodes referenced from there. Then each of these referenced nodes is scanned to
  30. look for further references.
  31. \subsection full_leak Full Leak
  32. there is no reference to a block of memory or to any memory within that block in the system.
  33. \subsection partial_leak Partial Leak
  34. there is no reference to the start of a block of memory. NB. there
  35. may be circumstances where this is not a real leak, e.g. memory allocation
  36. systems typically hand out references just beyond a control header to their
  37. clients. However there may also be instances where this is a real leak
  38. and someone just happens to have a reference to some contained data.
  39. \section tainting Memory Tainting
  40. Memory is deliberately dirtied in the following ways:
  41. - Initial heap space - 0xBBBBBBBB
  42. - Allocated memory - 0xAAAAAAAA
  43. - Freed memory - 0xFFFFFFFF
  44. - Dead Stack memory - 0xCCCCCCCC (done before leak scan)
  45. \section usage Utility functions
  46. Currently the following utility functions are available:
  47. - leakScan [0|1|2] - provides a dump of the currently allocated blocks of
  48. memory in the system pool.
  49. argument values have the following meanings:
  50. - 0 - display stats for just memory leaks.
  51. - 1 - display stats for memory leaks and partial leaks.
  52. - 2 - display stats for all currently allocation memory
  53. blocks.
  54. - leakEnable [framecount] - enables leak detection and causes the current statistics to be
  55. cleared out.
  56. Even if there are memory blocks in use, this
  57. command will cause future "leakShow" invocations
  58. to behave as if monitoring started from this new
  59. point in time.
  60. The optional 'framecount' argument can be used
  61. to change the number of levels of backtrace
  62. recorded. By default this number is 16. The
  63. number of contexts stored will be affected by
  64. this number. If the value is small then a
  65. limited number of contexts will exist and the
  66. memory overhead of monitoring will be reduced.
  67. If the number is large (can support a maximum
  68. of 16 levels) then the granularity of the
  69. contexts will be finer i.e. more of them, but
  70. the memory overhead in monitoring will be
  71. increased.
  72. With no specified framecount the maximum will be assumed.
  73. - leakDisable - Disabled the leak detection.
  74. \section implementation Implementation
  75. Static and dynamic blocks are allocated from opposite ends of a memory
  76. segment. As static blocks are allocated the end of the last
  77. "free block" migrates downwards in memory. Dynamic blocks are allocated
  78. from the start of the appropriately sized free block, hence leaving
  79. space for static allocations at the end of the heap memory.
  80. The heap implements a "best fit" model, for allocation of dynamic memory.
  81. This means that free blocks are maintained in size order and hence
  82. the most appropriate one can be used to satisfy client requests.
  83. This minimises fragmentation of the dynamically allocated memory.
  84. The free blocks are held in a binary tree (using \ref lub_bintree) which provide
  85. fast searching for the appropriate block.
  86. \author Graeme McKerrell
  87. \date Created On : Wed Dec 14 10:20:00 2005
  88. \version UNTESTED
  89. */
  90. #ifndef _lub_heap_h
  91. #define _lub_heap_h
  92. #include <stddef.h>
  93. #include "lub/types.h"
  94. #include "lub/c_decl.h"
  95. _BEGIN_C_DECL
  96. /**
  97. * This type is used to reference an instance of a heap.
  98. */
  99. typedef struct lub_heap_s lub_heap_t;
  100. /**
  101. * This type is used to reference an instance of a free block
  102. */
  103. typedef struct lub_heap_free_block_s lub_heap_free_block_t;
  104. /**
  105. * This type defines the statistics available for each heap.
  106. */
  107. typedef struct lub_heap_stats_s lub_heap_stats_t;
  108. struct lub_heap_stats_s
  109. {
  110. /*----------------------------------------------------- */
  111. /**
  112. * Number of segments comprising this heap.
  113. */
  114. size_t segs;
  115. /**
  116. * Number of bytes available in all the segments.
  117. */
  118. size_t segs_bytes;
  119. /**
  120. * Number of bytes used in housekeeping overheads
  121. */
  122. size_t segs_overhead;
  123. /*----------------------------------------------------- */
  124. /**
  125. * Number of free blocks. This is indication
  126. * the fragmentation state of a heap.
  127. */
  128. size_t free_blocks;
  129. /**
  130. * Number of bytes available in a heap.
  131. */
  132. size_t free_bytes;
  133. /**
  134. * Number of bytes used in housekeeping overheads
  135. */
  136. size_t free_overhead;
  137. /*----------------------------------------------------- */
  138. /**
  139. * Number of dynamically allocated blocks currently
  140. * held by clients of a heap.
  141. */
  142. size_t alloc_blocks;
  143. /**
  144. * Number of dynamically allocated bytes currently
  145. * held by clients of a heap.
  146. */
  147. size_t alloc_bytes;
  148. /**
  149. * Number of bytes used in housekeeping overheads
  150. */
  151. size_t alloc_overhead;
  152. /*----------------------------------------------------- */
  153. /**
  154. * Cumulative number of dynamically allocated blocks
  155. * given to clients of a heap.
  156. */
  157. size_t alloc_total_blocks;
  158. /**
  159. * Cumulative number of dynamically allocated bytes
  160. * given to clients of a heap.
  161. */
  162. size_t alloc_total_bytes;
  163. /*----------------------------------------------------- */
  164. /**
  165. * Number of dynamically allocated blocks
  166. * given to clients when the memory usage was at it's highest.
  167. */
  168. size_t alloc_hightide_blocks;
  169. /**
  170. * Number of dynamically allocated bytes
  171. * given to clients of a heap when the memory usage was at it's
  172. * highest
  173. */
  174. size_t alloc_hightide_bytes;
  175. /**
  176. * Number of bytes of overhead in use when the memory usage
  177. * was at it's highest
  178. */
  179. size_t alloc_hightide_overhead;
  180. /**
  181. * Number of free blocks when the memory usage was at it's
  182. * highest
  183. */
  184. size_t free_hightide_blocks;
  185. /**
  186. * Number of free bytes when the memory usage was at it's highest.
  187. */
  188. size_t free_hightide_bytes;
  189. /**
  190. * Number of housekeeping overhead bytes when the memory
  191. * usage was at it's highest.
  192. */
  193. size_t free_hightide_overhead;
  194. /*----------------------------------------------------- */
  195. /**
  196. * Number of statically allocated blocks currently
  197. * held by clients of a heap.
  198. */
  199. size_t static_blocks;
  200. /**
  201. * Number of statically allocated bytes currently
  202. * held by clients of a heap.
  203. */
  204. size_t static_bytes;
  205. /**
  206. * Number of dynamically allocated bytes currently
  207. * held by clients of a heap.
  208. */
  209. size_t static_overhead;
  210. /*----------------------------------------------------- */
  211. };
  212. /**
  213. * This type is used to indicate the result of a dynamic
  214. * memory allocation
  215. */
  216. typedef enum
  217. {
  218. /**
  219. * The allocation was successful
  220. */
  221. LUB_HEAP_OK,
  222. /**
  223. * There was insufficient resource to satisfy the request
  224. */
  225. LUB_HEAP_FAILED,
  226. /**
  227. * An attempt has been made to release an already freed block
  228. * of memory.
  229. */
  230. LUB_HEAP_DOUBLE_FREE,
  231. /**
  232. * A memory corruption has been detected. e.g. someone writing
  233. * beyond the bounds of an allocated block of memory.
  234. */
  235. LUB_HEAP_CORRUPTED,
  236. /**
  237. * The client has passed in an invalid pointer
  238. * i.e. one which lies outside the bounds of the current heap.
  239. */
  240. LUB_HEAP_INVALID_POINTER
  241. } lub_heap_status_t;
  242. typedef struct {void *ptr;} struct_void_ptr;
  243. /**
  244. * This type is used to indicate the alignment required
  245. * for a memory allocation.
  246. */
  247. typedef enum
  248. {
  249. /**
  250. * This is the "native" alignment required for the current
  251. * CPU architecture.
  252. */
  253. LUB_HEAP_ALIGN_NATIVE = sizeof(struct_void_ptr),
  254. /**
  255. * 4 byte alignment
  256. */
  257. LUB_HEAP_ALIGN_2_POWER_2 = 0x00000004,
  258. /**
  259. * 8 byte alignment
  260. */
  261. LUB_HEAP_ALIGN_2_POWER_3 = 0x00000008,
  262. /**
  263. * 16 byte alignment
  264. */
  265. LUB_HEAP_ALIGN_2_POWER_4 = 0x00000010,
  266. /**
  267. * 32 byte alignment
  268. */
  269. LUB_HEAP_ALIGN_2_POWER_5 = 0x00000020,
  270. /**
  271. * 64 byte alignment
  272. */
  273. LUB_HEAP_ALIGN_2_POWER_6 = 0x00000040,
  274. /**
  275. * 128 byte alignment
  276. */
  277. LUB_HEAP_ALIGN_2_POWER_7 = 0x00000080,
  278. /**
  279. * 256 byte alignment
  280. */
  281. LUB_HEAP_ALIGN_2_POWER_8 = 0x00000100,
  282. /**
  283. * 512 byte alignment
  284. */
  285. LUB_HEAP_ALIGN_2_POWER_9 = 0x00000200,
  286. /**
  287. * 1024 byte alignment (1KB)
  288. */
  289. LUB_HEAP_ALIGN_2_POWER_10 = 0x00000400,
  290. /**
  291. * 2048 byte alignment (2KB)
  292. */
  293. LUB_HEAP_ALIGN_2_POWER_11 = 0x00000800,
  294. /**
  295. * 4096 byte alignment (4KB)
  296. */
  297. LUB_HEAP_ALIGN_2_POWER_12 = 0x00001000,
  298. /**
  299. * 8192 byte alignment (8KB)
  300. */
  301. LUB_HEAP_ALIGN_2_POWER_13 = 0x00002000,
  302. /**
  303. * 16384 byte alignment (16KB)
  304. */
  305. LUB_HEAP_ALIGN_2_POWER_14 = 0x00004000,
  306. /**
  307. * 32768 byte alignment (32KB)
  308. */
  309. LUB_HEAP_ALIGN_2_POWER_15 = 0x00008000,
  310. /**
  311. * 65536 byte alignment (64KB)
  312. */
  313. LUB_HEAP_ALIGN_2_POWER_16 = 0x00010000,
  314. /**
  315. * 131072 byte alignment (128KB)
  316. */
  317. LUB_HEAP_ALIGN_2_POWER_17 = 0x00020000,
  318. /**
  319. * 262144 byte alignment (256KB)
  320. */
  321. LUB_HEAP_ALIGN_2_POWER_18 = 0x00040000,
  322. /**
  323. * 524288 byte alignment (512KB)
  324. */
  325. LUB_HEAP_ALIGN_2_POWER_19 = 0x00080000,
  326. /**
  327. * 1048576 byte alignment (1MB)
  328. */
  329. LUB_HEAP_ALIGN_2_POWER_20 = 0x00100000,
  330. /**
  331. * 2097152 byte alignment (2MB)
  332. */
  333. LUB_HEAP_ALIGN_2_POWER_21 = 0x00200000,
  334. /**
  335. * 4194304 byte alignment (4MB)
  336. */
  337. LUB_HEAP_ALIGN_2_POWER_22 = 0x00400000,
  338. /**
  339. * 8388608 byte alignment (8MB)
  340. */
  341. LUB_HEAP_ALIGN_2_POWER_23 = 0x00800000,
  342. /**
  343. * 16777216 byte alignment (16MB)
  344. */
  345. LUB_HEAP_ALIGN_2_POWER_24 = 0x01000000,
  346. /**
  347. * 33554432 byte alignment (32MB)
  348. */
  349. LUB_HEAP_ALIGN_2_POWER_25 = 0x02000000,
  350. /**
  351. * 67108864 byte alignment (64MB)
  352. */
  353. LUB_HEAP_ALIGN_2_POWER_26 = 0x04000000,
  354. /**
  355. * 134217728 byte alignment (128MB)
  356. */
  357. LUB_HEAP_ALIGN_2_POWER_27 = 0x08000000
  358. } lub_heap_align_t;
  359. /**
  360. * This type defines how leak details should be displayed
  361. */
  362. typedef enum
  363. {
  364. /**
  365. * Only show allocations which have no reference elsewhere
  366. * in the system
  367. */
  368. LUB_HEAP_SHOW_LEAKS,
  369. /**
  370. * Only show allocations which have no direct reference elsewhere
  371. * in the system, but do have their contents referenced.
  372. */
  373. LUB_HEAP_SHOW_PARTIALS,
  374. /**
  375. * Show all the current allocations in the system.
  376. */
  377. LUB_HEAP_SHOW_ALL
  378. } lub_heap_show_e;
  379. /**
  380. * This type defines a function prototype to be used to
  381. * iterate around each of a number of things in the system.
  382. */
  383. typedef void
  384. lub_heap_foreach_fn(
  385. /**
  386. * The current entity
  387. */
  388. void *block,
  389. /**
  390. * A simple 1-based identifier for this entity
  391. */
  392. unsigned index,
  393. /**
  394. * The number of bytes available in this entity
  395. */
  396. size_t size,
  397. /**
  398. * Client specific argument
  399. */
  400. void *arg);
  401. /**
  402. * This operation is a diagnostic which can be used to
  403. * iterate around all the segments in the specified heap.
  404. * For example it may be desirable to output information about
  405. * each of the segments present.
  406. *
  407. * \pre
  408. * - The heap needs to have been create with an initial memory segment.
  409. *
  410. * \return
  411. * - none
  412. *
  413. * \post
  414. * -The specified function will have been called once for every segment
  415. * in the specified heap
  416. */
  417. void
  418. lub_heap_foreach_segment(
  419. /**
  420. * The heap instance on which to operate
  421. */
  422. lub_heap_t *instance,
  423. /**
  424. * The client provided function to call for each free block
  425. */
  426. lub_heap_foreach_fn *fn,
  427. /**
  428. * Some client specific data to pass through to the callback
  429. * function.
  430. */
  431. void *arg);
  432. /**
  433. * This operation is a diagnostic which can be used to
  434. * iterate around all the free blocks in the specified heap.
  435. * For example it may be desirable to output information about
  436. * each of the free blocks present.
  437. *
  438. * \pre
  439. * - The heap needs to have been create with an initial memory segment.
  440. *
  441. * \return
  442. * - none
  443. *
  444. * \post
  445. * -The specified function will have been called once for every free
  446. * block in the specified heap
  447. */
  448. void
  449. lub_heap_foreach_free_block(
  450. /**
  451. * The heap instance on which to operate
  452. */
  453. lub_heap_t *instance,
  454. /**
  455. * The client provided function to call for each free block
  456. */
  457. lub_heap_foreach_fn *fn,
  458. /**
  459. * Some client specific data to pass through to the callback
  460. * function.
  461. */
  462. void *arg);
  463. /**
  464. * This operation creates a dynamic heap from the provided
  465. * memory segment.
  466. *
  467. * \pre
  468. * - none
  469. *
  470. * \return
  471. * - a reference to a heap object which can be used to allocate
  472. * memory from the segments associated with this heap.
  473. *
  474. * \post
  475. * - memory allocations can be invoked on the returned intance.
  476. * - further memory segements can be augmented to the heap using
  477. * the lub_heap_add_segment() operation.
  478. */
  479. lub_heap_t *
  480. lub_heap_create(
  481. /**
  482. * The begining of the first memory segment to associate with
  483. * this heap
  484. */
  485. void *start,
  486. /**
  487. * The number of bytes available for use in the first segment.
  488. */
  489. size_t size
  490. );
  491. /**
  492. * This operation creates a dynamic heap from the provided
  493. * memory segment.
  494. *
  495. * \pre
  496. * - The heap needs to have been create with an initial memory segment.
  497. *
  498. * \return
  499. * - none
  500. *
  501. * \post
  502. * - The heap is no longer valid for use.
  503. * - The memory segment(s) previously given to the heap
  504. * may now be reused.
  505. * - Any extra resources used for leak detection will have been released.
  506. */
  507. void
  508. lub_heap_destroy(
  509. /**
  510. * The heap instance on which to operate
  511. */
  512. lub_heap_t *instance
  513. );
  514. /**
  515. * This operation augments an existing heap with
  516. * some more memory to manage.
  517. * NB. if the memory happens to be follow on from the initial memory segment
  518. * then the two will merge into a single larger segment. This means that a heap
  519. * which is expanded with a sbrk() like mechanism will contain a single
  520. * expandible segment.
  521. *
  522. * \pre
  523. * - The heap needs to have been create with an initial memory segment.
  524. *
  525. * \return
  526. * - none
  527. *
  528. * \post
  529. * - The new segment of memory becomes available for use by this heap.
  530. */
  531. void
  532. lub_heap_add_segment(
  533. /**
  534. * The heap instance on which to operate
  535. */
  536. lub_heap_t *instance,
  537. /**
  538. * The beginning of the memory segment to be managed
  539. */
  540. void *start,
  541. /**
  542. * The number of bytes available for use in this segment
  543. */
  544. size_t size
  545. );
  546. /**
  547. * This operation allocates some "static" memory from a heap. This is
  548. * memory which will remain allocted for the lifetime of the heap instance.
  549. * "static" memory allocation has zero overhead and causes zero fragmentation.
  550. *
  551. * NB. static allocation are only handed out from the first memory segment
  552. *
  553. * \pre
  554. * - The heap needs to have been created with an initial memory segment.
  555. *
  556. * \return
  557. * - a pointer to some "static" memory which will be fixed for the
  558. * remaining lifetime of this heap.
  559. *
  560. * \post
  561. * - The client cannot ever free this memory although if the heap is
  562. * managing memory which itself has been dynamically allocated, then
  563. * the memory will be recovered when the heap is released.
  564. */
  565. void *
  566. lub_heap_static_alloc(
  567. /**
  568. * The heap instance on which to operate
  569. */
  570. lub_heap_t *instance,
  571. /**
  572. * The number of bytes to allocate
  573. */
  574. size_t size
  575. );
  576. /**
  577. * This operation changes the size of the object referenced by a passed in
  578. * pointer to "size". The contents will be unchanged up to the minimum of the old
  579. * and new sizes. If the new size is larger, the new space is uninitialised.
  580. *
  581. * \pre
  582. * - The heap needs to have been created with an initial memory segment.
  583. * - If "*ptr" contains a non-NULL value then this MUST have
  584. * been allocated using this operation, from the same heap instance.
  585. *
  586. * \return
  587. * - the status of the operation.
  588. *
  589. * \post
  590. * - The client takes responsiblity for releasing any allocated memory when they
  591. * are finished with it.
  592. * - If *ptr contains a non-NULL value, then after a succesfull call, the
  593. * initial memory referenced by it may have been released for reuse,
  594. * and the pointer modified to reference some new memory.
  595. * - *ptr may contain NULL in which case no memory will be released back to the
  596. * heap for reuse, and the pointer is filled out with the allocated memory.
  597. * - (size == 0) No new memory will be allocated, *ptr will be set to NULL,
  598. * and any original memory referenced by it will have been released.
  599. */
  600. lub_heap_status_t
  601. lub_heap_realloc(
  602. /**
  603. * The heap instance on which to operate
  604. */
  605. lub_heap_t *instance,
  606. /**
  607. * Reference to a pointer containing previously allocated memory
  608. * or NULL.
  609. */
  610. char **ptr,
  611. /**
  612. * The number of bytes required for the object
  613. */
  614. size_t size,
  615. /**
  616. * The alignement required for a new allocations.
  617. */
  618. lub_heap_align_t alignment
  619. );
  620. /**
  621. * This operation controls the tainted memory facility.
  622. * This means that during certain heap operations memory can
  623. * be filled with some well defined bit patterns. This causes
  624. * a slight performance overhead but can be used to shake out
  625. * bugs such and free-memory-reads and uninitialised-memory-reads
  626. *
  627. * By default tainting is switched off.
  628. *
  629. * \pre
  630. * - none
  631. *
  632. * \return
  633. * - last tainted status
  634. *
  635. * \post
  636. * - (enabled) when a memory segment is given to a heap (either at creation or later)
  637. * the contents will be set to 0xBB
  638. * - (enabled) when some dynamically allocated memory is released back to a heap
  639. * the contents will be set to 0xFF
  640. * - (enabled) when some dynamic or static memory is allocated the contents will
  641. * be set to 0xAA as the "uninitialised" value.
  642. * - (disabled) no memory tainting will occur.
  643. */
  644. bool_t
  645. lub_heap_taint(
  646. /**
  647. * BOOL_TRUE to enable tainting or BOOL_FALSE to disable
  648. */
  649. bool_t enable
  650. );
  651. /**
  652. * This operation indicates the current status of the memory tainting
  653. * facility
  654. *
  655. * \pre
  656. * none
  657. *
  658. * \return
  659. * - BOOL_TRUE if memory tainting is enabled.
  660. * - BOOL_FALSE if memory tainting is disabled.
  661. *
  662. * \post
  663. * none
  664. */
  665. bool_t
  666. lub_heap_is_tainting(void);
  667. /**
  668. * This operation controls runtime heap corruption detection.
  669. * This means that during every heap operation a full check is
  670. * done of the specified heap, before any allocations/free are
  671. * performed.
  672. * This has a performance overhead but provides a valuable
  673. * aid in finding a memory corrupting client.
  674. * Corruption will be spotted the first time a memory operation
  675. * is performed AFTER it has occured.
  676. *
  677. * By default checking is switched off.
  678. *
  679. * \pre
  680. * - none
  681. *
  682. * \return
  683. * - last checking status
  684. *
  685. * \post
  686. * - (enabled) the heap will have been scanned for any corruption and if found the
  687. * return status of the invoking heap operation will be LUB_HEAP_CORRUPTED.
  688. * - (disabled) no entire heap memory checking will occur.
  689. */
  690. bool_t
  691. lub_heap_check(
  692. /**
  693. * BOOL_TRUE to enable checking or BOOL_FALSE to disable
  694. */
  695. bool_t enable
  696. );
  697. /**
  698. * This operation indicates the current status of the full memory checking
  699. * facility.
  700. *
  701. * \pre
  702. * none
  703. *
  704. * \return
  705. * - BOOL_TRUE if full memory checking is enabled.
  706. * - BOOL_FALSE if full memory checking is disabled.
  707. *
  708. * \post
  709. * none
  710. */
  711. bool_t
  712. lub_heap_is_checking(void);
  713. /**
  714. * This operation checks the integrety of the memory in the specified
  715. * heap.
  716. * Corruption will be spotted the first time a check is performed AFTER
  717. * it has occured.
  718. * \pre
  719. * - the specified heap will have been created
  720. *
  721. * \return
  722. * - BOOL_TRUE if the heap is OK
  723. * - BOOL_FALSE if the heap is corrupted.
  724. *
  725. * \post
  726. * - none
  727. */
  728. extern bool_t
  729. lub_heap_check_memory(lub_heap_t *instance);
  730. /**
  731. * This function is invoked whenever a call to lub_heap_realloc() fails.
  732. * It is provided as a debugging aid; simple set a breakpoint to
  733. * stop execution of the program and any failures will be caught in context.
  734. */
  735. void
  736. lub_heap_stop_here(
  737. /**
  738. * The failure status of the the call to realloc
  739. */
  740. lub_heap_status_t status,
  741. /**
  742. * The old value of the pointer passed in
  743. */
  744. char *old_ptr,
  745. /**
  746. * The requested number of bytes
  747. */
  748. size_t new_size
  749. );
  750. /**
  751. * This operation fills out a statistics structure with the details for the
  752. * specified heap.
  753. *
  754. * \pre
  755. * - none
  756. *
  757. * \post
  758. * - the results filled out are a snapshot of the statistics as the time
  759. * of the call.
  760. */
  761. void
  762. lub_heap__get_stats(
  763. /**
  764. * The instance on which to operate
  765. */
  766. lub_heap_t *instance,
  767. /**
  768. * A client provided structure to fill out with the heap details
  769. */
  770. lub_heap_stats_t *stats
  771. );
  772. /**
  773. * This operation dumps the salient details of the specified heap to stdout
  774. */
  775. void
  776. lub_heap_show(
  777. /**
  778. * The instance on which to operate
  779. */
  780. lub_heap_t *instance,
  781. /**
  782. * Whether to be verbose or not
  783. */
  784. bool_t verbose
  785. );
  786. /**
  787. * This method provides the size, in bytes, of the largest allocation
  788. * which can be performed.
  789. * \pre
  790. * - The heap needs to have been created with an initial memory segment.
  791. *
  792. * \return
  793. * - size of largest possible allocation.
  794. *
  795. * \post
  796. * - none
  797. */
  798. size_t
  799. lub_heap__get_max_free(
  800. /**
  801. * The instance on which to operate
  802. */
  803. lub_heap_t *instance
  804. );
  805. extern size_t
  806. lub_heap__get_block_overhead(lub_heap_t *instance,
  807. const void *ptr);
  808. extern size_t
  809. lub_heap__get_block_size(lub_heap_t *instance,
  810. const void *ptr);
  811. /**
  812. * This function scans memory to identify memory leaks
  813. *
  814. * NB. if tainting is switched off then this function may miss some leaks as
  815. * references may remain in freed memory.
  816. *
  817. */
  818. extern void
  819. lub_heap_leak_scan(void);
  820. /**
  821. * This function dumps all the context details for the heap
  822. * to stdout.
  823. * 'how' is one of the following values:
  824. * 0 - show only leaks
  825. * 1 - show partial leaks (no references to the start of the block)
  826. * 2 - show all allocations (VERY VERBOSE)
  827. *
  828. * NB. if tainting is switched off then this function will not perform
  829. * any memory scanning and will simply show all the allocated blocks.
  830. *
  831. * \return
  832. * - a boolean indicating whether any leaks were displayed or not.
  833. */
  834. extern bool_t
  835. lub_heap_leak_report(
  836. /**
  837. * how to display the details
  838. */
  839. lub_heap_show_e how,
  840. /**
  841. * an optional substring to use to filter contexts.
  842. * Only contexts which contain the substring will be displayed
  843. */
  844. const char *substring
  845. );
  846. void
  847. lub_heap__set_framecount(
  848. /**
  849. * The new framecount to use
  850. */
  851. unsigned framecount
  852. );
  853. unsigned
  854. lub_heap__get_framecount(void);
  855. extern bool_t
  856. lub_heap_validate_pointer(lub_heap_t *instance,
  857. char *ptr);
  858. /**
  859. * This 'magic' pointer is returned when a client requests zero bytes
  860. * The client can see that the allocation has succeeded, but cannot use
  861. * the "memory" returned. This pointer may be passed transparently back
  862. * to lub_heap_realloc() without impact.
  863. */
  864. #define LUB_HEAP_ZERO_ALLOC ((void*)-1)
  865. /**
  866. * This operation is used to initialise the heap management
  867. * subsystem
  868. * \pre
  869. * - none
  870. *
  871. * \post
  872. * - The POSIX specific subsystem will be initialised to load
  873. * the debugging symbols for the current executable. This
  874. * enables the backtraces used for leak detection to show
  875. * the full detail in the stack traces.
  876. * - If the system is configured at build time without GPL
  877. * support (disabled by default) then only the address of
  878. * each stack frame will be shown.
  879. */
  880. extern void
  881. lub_heap_init(
  882. /**
  883. * The full pathname of the current executable
  884. * This is typically obtained from argv[0] in main()
  885. */
  886. const char *program_name
  887. );
  888. #if defined(__CYGWIN__)
  889. /**
  890. * CYGWIN requires a specialised initialisation to account for
  891. * argv[0] not containing the trailing ".exe" of the executable.
  892. */
  893. extern void
  894. cygwin_lub_heap_init(const char *file_name);
  895. #define lub_heap_init(arg0) cygwin_lub_heap_init(arg0)
  896. #endif /* __CYGWIN__ */
  897. /**
  898. * This operation adds a cache to the current heap, which speeds up
  899. * the allocation and releasing of smaller block sizes.
  900. *
  901. * \pre
  902. * - The heap must have been initialised
  903. * - This call must not have been made on this heap before
  904. *
  905. * \return
  906. * - LUB_HEAP_OK if the cache was successfully set up.
  907. * - LUB_HEAP_FAILED if the cache was not set up for whatever reason
  908. *
  909. * \post
  910. * - memory allocations for smaller block sizes may come from the
  911. * cache.
  912. */
  913. lub_heap_status_t
  914. lub_heap_cache_init(
  915. /**
  916. * The instance on which to operate
  917. */
  918. lub_heap_t *instance,
  919. /**
  920. * The maximum block size for the cache
  921. */
  922. lub_heap_align_t max_block_size,
  923. /**
  924. * The number of maximum sized blocks to make available.
  925. */
  926. size_t num_max_blocks
  927. );
  928. /**
  929. * This operation signals the start of a section of code which
  930. * should not have any of it's heap usage monitored by the leak
  931. * detection code.
  932. *
  933. * \pre
  934. * - The heap must have been initialised
  935. *
  936. * \return
  937. * - none
  938. *
  939. * \post
  940. * - If leak detection is enabled then no subsequent allocations will
  941. * be monitored until the lub_heap_leak_restore_detection() is called.
  942. */
  943. void
  944. lub_heap_leak_suppress_detection(
  945. /**
  946. * The instance on which to operate
  947. */
  948. lub_heap_t *instance
  949. );
  950. /**
  951. * This operation signals the end of a section of code which
  952. * should not have any of it's heap usage monitored by the leak
  953. * detection code.
  954. *
  955. * NB. you may nest the usage of lub_heap_leak_suppress_detection() and
  956. * lub_heap_leak_restore_detection() in which case only when the outermost
  957. * section has been terminated will monitoring commence again.
  958. *
  959. * \pre
  960. * - The heap must have been initialised
  961. * - lub_heap_start_unmonitored_section() must have been called.
  962. *
  963. * \return
  964. * - none
  965. *
  966. * \post
  967. * - If leak detection is enabled then no subsequent allocations will
  968. * be monitored until the lub_heap_end_unmonitored_section() is called.
  969. */
  970. void
  971. lub_heap_leak_restore_detection(
  972. /**
  973. * The instance on which to operate
  974. */
  975. lub_heap_t *instance
  976. );
  977. /**
  978. * This operation returns the overhead, in bytes, which is required
  979. * to implement a heap instance. This provide clients the means of
  980. * calculating how much memory they need to assign for a heap instance
  981. * to manage.
  982. *
  983. * \pre
  984. * - none
  985. *
  986. * \return
  987. * - size in bytes of the overhead required by a lub_heap instance.
  988. *
  989. * \post
  990. * - none
  991. */
  992. size_t
  993. lub_heap_overhead_size(
  994. /**
  995. * The maximum block size for the cache
  996. */
  997. lub_heap_align_t max_block_size,
  998. /**
  999. * The number of maximum sized blocks to make available.
  1000. */
  1001. size_t num_max_blocks
  1002. );
  1003. _END_C_DECL
  1004. #endif /* _lub_heap_h */
  1005. /** @} */