{"id":3375,"date":"2013-09-30T06:52:53","date_gmt":"2013-09-30T06:52:53","guid":{"rendered":"http:\/\/www.cloudcomp.ch\/?p=3375"},"modified":"2013-09-30T06:52:53","modified_gmt":"2013-09-30T06:52:53","slug":"hunting-down-memory-leaks","status":"publish","type":"post","link":"https:\/\/blog.zhaw.ch\/icclab\/hunting-down-memory-leaks\/","title":{"rendered":"Hunting down memory leaks"},"content":{"rendered":"<p>I assume you are confident using a shell, installing software and generally building software from source.<\/p>\n<p>While writing C code for a networking library I did some simple stability tests by setting up a simple server replying to a client query, no magic at all just hard coded strings. Obviously in such situations you will a have an eye on a process monitor like <a href=\"http:\/\/htop.sourceforge.net\/\" title=\"htop - an interactive process viewer for Linux\">htop<\/a>.<\/p>\n<p>So I just ran the server and three clients in a endless loop:<\/p>\n<pre><code>while true; do binary; done\n<\/code><\/pre>\n<p>\n<a href=\"http:\/\/blog.zhaw.ch\/icclab\/files\/2013\/09\/server-and-three-clients.png\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/blog.zhaw.ch\/icclab\/files\/2013\/09\/server-and-three-clients-300x203.png\" alt=\"server and three clients\" width=\"300\" height=\"203\" class=\"aligncenter size-medium wp-image-3378\" srcset=\"https:\/\/blog.zhaw.ch\/icclab\/files\/2013\/09\/server-and-three-clients-300x203.png 300w, https:\/\/blog.zhaw.ch\/icclab\/files\/2013\/09\/server-and-three-clients-441x300.png 441w, https:\/\/blog.zhaw.ch\/icclab\/files\/2013\/09\/server-and-three-clients.png 721w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a>\n<\/p>\n<p>A quick look in htop revealed that my code leaked memory, not much per loop (around 20-30 Bytes) but still: In code which shall be once shipped in productive environment this is fatal. You can easily recognize such problems by looking at the RES column, if this value increases without clear reason you have somewhere a memory leak.<\/p>\n<p>\n<a href=\"http:\/\/blog.zhaw.ch\/icclab\/files\/2013\/09\/htop.png\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/blog.zhaw.ch\/icclab\/files\/2013\/09\/htop-300x203.png\" alt=\"htop\" width=\"300\" height=\"203\" class=\"aligncenter size-medium wp-image-3377\" srcset=\"https:\/\/blog.zhaw.ch\/icclab\/files\/2013\/09\/htop-300x203.png 300w, https:\/\/blog.zhaw.ch\/icclab\/files\/2013\/09\/htop-441x300.png 441w, https:\/\/blog.zhaw.ch\/icclab\/files\/2013\/09\/htop.png 721w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a>\n<\/p>\n<p>For this type of problem you take <a href=\"http:\/\/valgrind.org\/\" title=\"Valgrind - a dynamic code analysis tool\">valgrind<\/a>. But since valgrind warns that their support on Mac OS X being broken I had to switch over to Linux. For such cases I recommend the <a href=\"http:\/\/spins.fedoraproject.org\/security\/\" title=\"Fedora Security Spin - a modified Fedora with a lot of handy preinstalled tools\">Fedora Security Spin<\/a> which comes with a huge load of tools aimed at security, auditing, research, rescue and obviously developper.<\/p>\n<p>But before analyzing you need to tweak a few things: If you compile third party libraries by yourself consider passing the compiler flags <code>-g -O0<\/code> to make sure the compiler produces debug symbols and doesn&#8217;t optimize too much making it harder to find the leaks. So make sure you invoke the configure script as follows:<\/p>\n<p><pre><code>make clean\n.\/configure CFLAGS=\"$CFLAGS -g -O0\" CXXFLAGS=\"$CXXFLAGS -g -O0\"\nmake all\nsudo make install\n<\/code><\/pre>\n<\/p>\n<p>And evidently your code has also to be built with debug symbols and optimizations turned off, I&#8217;ll show you how this looks like in my Makefile:<\/p>\n<p><pre><code>CC = clang\nBASICOPTS = -g -O0\nCFLAGS = $(BASICOPTS) -pedantic -Wall -std=c11\n<\/code><\/pre>\n<\/p>\n<p>Using <code>-pedantic -Wall<\/code> allows the compiler to warn you about every little mistake you write, always a good idea. Personally I recommend <a href=\"http:\/\/clang.llvm.org\/\" title=\"clang: a C language family frontend for LLVM\"><code>clang<\/code><\/a> since it produces better error output.<\/p>\n<p>Then you are ready to go hunting memory leaks! Start <code>valgrind<\/code> as following:<\/p>\n<p><pre><code>valgrind --tool=memcheck --leak-check=full \n    --show-possibly-lost=no your-binary\n<\/code><\/pre>\n<\/p>\n<p>Then after one I killed my server binary with <code>ctrl-c<\/code> and got a nice output:<\/p>\n<p><pre><code>==3955== \n==3955== HEAP SUMMARY:\n==3955==     in use at exit: 58,693 bytes in 76 blocks\n==3955==   total heap usage: 162 allocs, 86 frees, 104,671 bytes all\nocated\n==3955== \n==3955== 25 bytes in 1 blocks are definitely lost in loss record 13 \nof 71\n==3955==    at 0x4A06409: malloc (in \/usr\/lib64\/valgrind\/vgpreload_m\nemcheck-amd64-linux.so)\n==3955==    by 0x4EB2717: zframe_strdup (zframe.c:246)\n==3955==    by 0x4014B9: _recv_message (kt_server.c:119)\n            [snip] \n==3955== 36 bytes in 1 blocks are definitely lost in loss record 15 \nof 71\n==3955==    at 0x4A08121: calloc (in \/usr\/lib64\/valgrind\/vgpreload_me\nmcheck-amd64-linux.so)\n==3955==    by 0x4EB2117: safe_malloc (czmq_prelude.h:445)\n==3955==    by 0x4EB21BB: zframe_new (zframe.c:59)\n==3955==    by 0x4EB231A: zframe_recv (zframe.c:115)\n==3955==    by 0x4EB780D: zmsg_recv (zmsg.c:101)\n==3955==    by 0x40144E: _recv_message (kt_server.c:115)\n==3955== \n==3955== LEAK SUMMARY:\n==3955==    definitely lost: 61 bytes in 2 blocks\n==3955==    indirectly lost: 0 bytes in 0 blocks\n==3955==      possibly lost: 1,256 bytes in 12 blocks\n==3955==    still reachable: 57,376 bytes in 62 blocks\n==3955==         suppressed: 0 bytes in 0 blocks\n==3955== Reachable blocks (those to which a pointer was found) are n\not shown.\n==3955== To see them, rerun with: --leak-check=full --show-reachable\n=yes\n==3955== \n==3955== For counts of detected and suppressed errors, rerun with: -v\n==3955== ERROR SUMMARY: 14 errors from 14 contexts (suppressed: 2 fro\nm 2)\nKilled\n<\/code><\/pre>\n<p><p>Which shows I&#8217;m leaking memory in my code in two places. Reading the stack-trace when we go up a few stack frames while skipping the internal calls of zeromq we see two matching lines: <code>kt_server.c:115<\/code> and <code>kt_server.c:119<\/code>. Let&#8217;s first tackle the bigger leak at <code>kt_server.c:119<\/code>:<\/p>\n<pre><code>msg-&gt;msgData = zframe_strdup(zmsg_pop(m));\n<\/code><\/pre>\n<p>That for I have to look closely what my code does and consult the <a href=\"http:\/\/czmq.zeromq.org\/manual:zmsg\">API reference of czmq<\/a>:<\/p>\n<p><pre><code>\/\/  Remove first frame from message, if any. Returns frame, or NULL.\n\/\/ Caller now owns frame and must destroy it when finished with it.\nCZMQ_EXPORT zframe_t *\n    zmsg_pop (zmsg_t *self);\n<\/code><\/pre>\n<\/p>\n<p>And that&#8217;s what I forgot: &#8220;Caller now owns frame and must destroy it when finished with it.&#8221; I simply popped memory but didn&#8217;t care about freeing it. After changing the line to<\/p>\n<pre><code>msg-&gt;msgData = zmsg_popstr (m);\n<\/code><\/pre>\n<p>I was left with the first memory leak at <code>kt_server.c:115<\/code>. My code calls <code>_recv_message()<\/code> and receives a struct with a <code>char*<\/code> to the received message. Then I simply added a new response message and called <code>_send_message()<\/code>:<\/p>\n<p><pre><code>msg = _recv_message ();\n\nchar *response = malloc(sizeof(char) * 128);\nmemcpy (response, \"Hello World\", 12);\nprintf (\"Request: %sn\", msg-&gt;msgData);\nmsg-&gt;msgData = response;\n\n_send_message (msg);\n<\/code><\/pre>\n<\/p>\n<p>The problem here is also pretty obvious: <code>char *msgData<\/code> formerly pointing to the received message is newly pointing to my freshly <code>malloc<\/code>-ed memory without freeing the old memory. So adding <code>free (msg-&gt;msgData);<\/code> solved this leak. I&#8217;ll leave figuring out where this statement goes in as an exercise to the reader.<\/p>\n<p>Also an easy mistake is to forget freeing memory in <code>_send_message()<\/code> since <code>zframe_send()<\/code> requires you to destroy the passed <code>zframe_t<\/code>.<\/p>\n<p><pre><code>int _send_message (message_t msg)\n{\n    zframe_t *frame_reply = zframe_new (msg-&gt;msgData,\n        strlen(msg-&gt;msgData));\n    zframe_send (&amp;frame_reply, sock, ZFRAME_REUSE);\n    zframe_destroy (&amp;frame_reply);\n    free (msg);\n    return 0;\n}\n<\/code><\/pre>\n<\/p>\n<p>Did you see what&#8217;s wrong here? Let&#8217;s have a look at the struct <code>message_t<\/code> which I simplified down to the relevant:<\/p>\n<p><pre><code>typedef struct message_t {\n    char *msgData;\n} message_t;\n<\/code><\/pre>\n<\/p>\n<p>Correct: I call <code>free (msg);<\/code> which indicates that <code>msg<\/code> is a struct on the heap (allocated by <code>malloc()<\/code>) but the member <code>char *msgData<\/code> is simply a pointer on an other memory which waits to be free&#8217;d too. Let&#8217;s assume I was tired and put it after the first <code>free<\/code>:<\/p>\n<p><pre><code>free (msg);\nfree (msg-&gt;msgData);\n<\/code><\/pre>\n<\/p>\n<p>What would happen? Well yes, your code would probably just segfault. But why? <code>msg<\/code> points after the <code>free()<\/code> to a probably otherwise used memory or is even NULL. The manpage of <code>free(3)<\/code> clearly says that &#8221; \u2026 the behavior is undefined if the memory area referred to by ptr has already been deallocated \u2026 &#8221; so eventually I cannot access <code>msgData<\/code> anymore. Correct would be to deallocate the memory from inside out:<\/p>\n<p><pre><code>free (msg-&gt;msgData);\nfree (msg);\n<\/code><\/pre>\n<\/p>\n<p>A final run of <code>valgrind<\/code> shows now: My code is memory leak free!<\/p>\n<p>\n<a href=\"http:\/\/blog.zhaw.ch\/icclab\/files\/2013\/09\/using-valgrind-in-my-VM.png\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/blog.zhaw.ch\/icclab\/files\/2013\/09\/using-valgrind-in-my-VM-300x242.png\" alt=\"using valgrind in my VM\" width=\"300\" height=\"242\" class=\"aligncenter size-medium wp-image-3379\" srcset=\"https:\/\/blog.zhaw.ch\/icclab\/files\/2013\/09\/using-valgrind-in-my-VM-300x242.png 300w, https:\/\/blog.zhaw.ch\/icclab\/files\/2013\/09\/using-valgrind-in-my-VM-1024x827.png 1024w, https:\/\/blog.zhaw.ch\/icclab\/files\/2013\/09\/using-valgrind-in-my-VM-371x300.png 371w, https:\/\/blog.zhaw.ch\/icclab\/files\/2013\/09\/using-valgrind-in-my-VM.png 1095w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>I assume you are confident using a shell, installing software and generally building software from source. While writing C code for a networking library I did some simple stability tests by setting up a simple server replying to a client query, no magic at all just hard coded strings. Obviously in such situations you will [&hellip;]<\/p>\n","protected":false},"author":61,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"ngg_post_thumbnail":0,"footnotes":""},"categories":[15],"tags":[],"features":[],"class_list":["post-3375","post","type-post","status-publish","format-standard","hentry","category-howtos"],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v27.2 (Yoast SEO v27.2) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>Hunting down memory leaks - Service Engineering (ICCLab &amp; SPLab)<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/blog.zhaw.ch\/icclab\/hunting-down-memory-leaks\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Hunting down memory leaks\" \/>\n<meta property=\"og:description\" content=\"I assume you are confident using a shell, installing software and generally building software from source. While writing C code for a networking library I did some simple stability tests by setting up a simple server replying to a client query, no magic at all just hard coded strings. Obviously in such situations you will [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/blog.zhaw.ch\/icclab\/hunting-down-memory-leaks\/\" \/>\n<meta property=\"og:site_name\" content=\"Service Engineering (ICCLab &amp; SPLab)\" \/>\n<meta property=\"article:published_time\" content=\"2013-09-30T06:52:53+00:00\" \/>\n<meta property=\"og:image\" content=\"http:\/\/blog.zhaw.ch\/icclab\/files\/2013\/09\/server-and-three-clients-300x203.png\" \/>\n<meta name=\"author\" content=\"habl\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"habl\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"5 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/blog.zhaw.ch\/icclab\/hunting-down-memory-leaks\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/blog.zhaw.ch\/icclab\/hunting-down-memory-leaks\/\"},\"author\":{\"name\":\"habl\",\"@id\":\"https:\/\/blog.zhaw.ch\/icclab\/#\/schema\/person\/db8c433b7da8ab174c359b95d38c34ac\"},\"headline\":\"Hunting down memory leaks\",\"datePublished\":\"2013-09-30T06:52:53+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/blog.zhaw.ch\/icclab\/hunting-down-memory-leaks\/\"},\"wordCount\":661,\"commentCount\":0,\"image\":{\"@id\":\"https:\/\/blog.zhaw.ch\/icclab\/hunting-down-memory-leaks\/#primaryimage\"},\"thumbnailUrl\":\"http:\/\/blog.zhaw.ch\/icclab\/files\/2013\/09\/server-and-three-clients-300x203.png\",\"articleSection\":[\"HowTos\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/blog.zhaw.ch\/icclab\/hunting-down-memory-leaks\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/blog.zhaw.ch\/icclab\/hunting-down-memory-leaks\/\",\"url\":\"https:\/\/blog.zhaw.ch\/icclab\/hunting-down-memory-leaks\/\",\"name\":\"Hunting down memory leaks - Service Engineering (ICCLab &amp; SPLab)\",\"isPartOf\":{\"@id\":\"https:\/\/blog.zhaw.ch\/icclab\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/blog.zhaw.ch\/icclab\/hunting-down-memory-leaks\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/blog.zhaw.ch\/icclab\/hunting-down-memory-leaks\/#primaryimage\"},\"thumbnailUrl\":\"http:\/\/blog.zhaw.ch\/icclab\/files\/2013\/09\/server-and-three-clients-300x203.png\",\"datePublished\":\"2013-09-30T06:52:53+00:00\",\"author\":{\"@id\":\"https:\/\/blog.zhaw.ch\/icclab\/#\/schema\/person\/db8c433b7da8ab174c359b95d38c34ac\"},\"breadcrumb\":{\"@id\":\"https:\/\/blog.zhaw.ch\/icclab\/hunting-down-memory-leaks\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/blog.zhaw.ch\/icclab\/hunting-down-memory-leaks\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/blog.zhaw.ch\/icclab\/hunting-down-memory-leaks\/#primaryimage\",\"url\":\"https:\/\/blog.zhaw.ch\/icclab\/files\/2013\/09\/server-and-three-clients.png\",\"contentUrl\":\"https:\/\/blog.zhaw.ch\/icclab\/files\/2013\/09\/server-and-three-clients.png\",\"width\":721,\"height\":490},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/blog.zhaw.ch\/icclab\/hunting-down-memory-leaks\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Startseite\",\"item\":\"https:\/\/blog.zhaw.ch\/icclab\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Hunting down memory leaks\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/blog.zhaw.ch\/icclab\/#website\",\"url\":\"https:\/\/blog.zhaw.ch\/icclab\/\",\"name\":\"Service Engineering (ICCLab &amp; SPLab)\",\"description\":\"A Blog of the ZHAW Zurich University of Applied Sciences\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/blog.zhaw.ch\/icclab\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\/\/blog.zhaw.ch\/icclab\/#\/schema\/person\/db8c433b7da8ab174c359b95d38c34ac\",\"name\":\"habl\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/secure.gravatar.com\/avatar\/c97d6aa6e5a0ea4cea97629d05d3d278bb904dabc955d75727ec9c45b1251ea7?s=96&d=mm&r=g\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/c97d6aa6e5a0ea4cea97629d05d3d278bb904dabc955d75727ec9c45b1251ea7?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/c97d6aa6e5a0ea4cea97629d05d3d278bb904dabc955d75727ec9c45b1251ea7?s=96&d=mm&r=g\",\"caption\":\"habl\"},\"url\":\"https:\/\/blog.zhaw.ch\/icclab\/author\/habl\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Hunting down memory leaks - Service Engineering (ICCLab &amp; SPLab)","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/blog.zhaw.ch\/icclab\/hunting-down-memory-leaks\/","og_locale":"en_US","og_type":"article","og_title":"Hunting down memory leaks","og_description":"I assume you are confident using a shell, installing software and generally building software from source. While writing C code for a networking library I did some simple stability tests by setting up a simple server replying to a client query, no magic at all just hard coded strings. Obviously in such situations you will [&hellip;]","og_url":"https:\/\/blog.zhaw.ch\/icclab\/hunting-down-memory-leaks\/","og_site_name":"Service Engineering (ICCLab &amp; SPLab)","article_published_time":"2013-09-30T06:52:53+00:00","og_image":[{"url":"http:\/\/blog.zhaw.ch\/icclab\/files\/2013\/09\/server-and-three-clients-300x203.png","type":"","width":"","height":""}],"author":"habl","twitter_card":"summary_large_image","twitter_misc":{"Written by":"habl","Est. reading time":"5 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/blog.zhaw.ch\/icclab\/hunting-down-memory-leaks\/#article","isPartOf":{"@id":"https:\/\/blog.zhaw.ch\/icclab\/hunting-down-memory-leaks\/"},"author":{"name":"habl","@id":"https:\/\/blog.zhaw.ch\/icclab\/#\/schema\/person\/db8c433b7da8ab174c359b95d38c34ac"},"headline":"Hunting down memory leaks","datePublished":"2013-09-30T06:52:53+00:00","mainEntityOfPage":{"@id":"https:\/\/blog.zhaw.ch\/icclab\/hunting-down-memory-leaks\/"},"wordCount":661,"commentCount":0,"image":{"@id":"https:\/\/blog.zhaw.ch\/icclab\/hunting-down-memory-leaks\/#primaryimage"},"thumbnailUrl":"http:\/\/blog.zhaw.ch\/icclab\/files\/2013\/09\/server-and-three-clients-300x203.png","articleSection":["HowTos"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/blog.zhaw.ch\/icclab\/hunting-down-memory-leaks\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/blog.zhaw.ch\/icclab\/hunting-down-memory-leaks\/","url":"https:\/\/blog.zhaw.ch\/icclab\/hunting-down-memory-leaks\/","name":"Hunting down memory leaks - Service Engineering (ICCLab &amp; SPLab)","isPartOf":{"@id":"https:\/\/blog.zhaw.ch\/icclab\/#website"},"primaryImageOfPage":{"@id":"https:\/\/blog.zhaw.ch\/icclab\/hunting-down-memory-leaks\/#primaryimage"},"image":{"@id":"https:\/\/blog.zhaw.ch\/icclab\/hunting-down-memory-leaks\/#primaryimage"},"thumbnailUrl":"http:\/\/blog.zhaw.ch\/icclab\/files\/2013\/09\/server-and-three-clients-300x203.png","datePublished":"2013-09-30T06:52:53+00:00","author":{"@id":"https:\/\/blog.zhaw.ch\/icclab\/#\/schema\/person\/db8c433b7da8ab174c359b95d38c34ac"},"breadcrumb":{"@id":"https:\/\/blog.zhaw.ch\/icclab\/hunting-down-memory-leaks\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/blog.zhaw.ch\/icclab\/hunting-down-memory-leaks\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/blog.zhaw.ch\/icclab\/hunting-down-memory-leaks\/#primaryimage","url":"https:\/\/blog.zhaw.ch\/icclab\/files\/2013\/09\/server-and-three-clients.png","contentUrl":"https:\/\/blog.zhaw.ch\/icclab\/files\/2013\/09\/server-and-three-clients.png","width":721,"height":490},{"@type":"BreadcrumbList","@id":"https:\/\/blog.zhaw.ch\/icclab\/hunting-down-memory-leaks\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Startseite","item":"https:\/\/blog.zhaw.ch\/icclab\/"},{"@type":"ListItem","position":2,"name":"Hunting down memory leaks"}]},{"@type":"WebSite","@id":"https:\/\/blog.zhaw.ch\/icclab\/#website","url":"https:\/\/blog.zhaw.ch\/icclab\/","name":"Service Engineering (ICCLab &amp; SPLab)","description":"A Blog of the ZHAW Zurich University of Applied Sciences","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/blog.zhaw.ch\/icclab\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/blog.zhaw.ch\/icclab\/#\/schema\/person\/db8c433b7da8ab174c359b95d38c34ac","name":"habl","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/c97d6aa6e5a0ea4cea97629d05d3d278bb904dabc955d75727ec9c45b1251ea7?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/c97d6aa6e5a0ea4cea97629d05d3d278bb904dabc955d75727ec9c45b1251ea7?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/c97d6aa6e5a0ea4cea97629d05d3d278bb904dabc955d75727ec9c45b1251ea7?s=96&d=mm&r=g","caption":"habl"},"url":"https:\/\/blog.zhaw.ch\/icclab\/author\/habl\/"}]}},"_links":{"self":[{"href":"https:\/\/blog.zhaw.ch\/icclab\/wp-json\/wp\/v2\/posts\/3375","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.zhaw.ch\/icclab\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.zhaw.ch\/icclab\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.zhaw.ch\/icclab\/wp-json\/wp\/v2\/users\/61"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.zhaw.ch\/icclab\/wp-json\/wp\/v2\/comments?post=3375"}],"version-history":[{"count":0,"href":"https:\/\/blog.zhaw.ch\/icclab\/wp-json\/wp\/v2\/posts\/3375\/revisions"}],"wp:attachment":[{"href":"https:\/\/blog.zhaw.ch\/icclab\/wp-json\/wp\/v2\/media?parent=3375"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.zhaw.ch\/icclab\/wp-json\/wp\/v2\/categories?post=3375"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.zhaw.ch\/icclab\/wp-json\/wp\/v2\/tags?post=3375"},{"taxonomy":"features","embeddable":true,"href":"https:\/\/blog.zhaw.ch\/icclab\/wp-json\/wp\/v2\/features?post=3375"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}