{"id":135674,"date":"2020-11-05T16:45:00","date_gmt":"2020-11-05T14:45:00","guid":{"rendered":"https:\/\/ruuvi.com\/debugging-ceedling-unit-tests-with-lldb-gdb\/"},"modified":"2026-06-11T07:31:50","modified_gmt":"2026-06-11T04:31:50","slug":"debugging-ceedling-unit-tests-with-lldb-gdb","status":"publish","type":"post","link":"https:\/\/ruuvi.com\/de\/debugging-ceedling-unit-tests-with-lldb-gdb\/","title":{"rendered":"Ceedling Unit-Tests mit LLDB \/GDB debuggen"},"content":{"rendered":"\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"702\" height=\"616\" src=\"https:\/\/ruuvi.com\/i\/u\/unit-test-failure.png\" alt=\"Unit-Test-Fehler\" class=\"wp-image-3362\" srcset=\"https:\/\/ruuvi.com\/i\/u\/unit-test-failure.png 702w, https:\/\/ruuvi.com\/i\/u\/unit-test-failure-450x395.png 450w, https:\/\/ruuvi.com\/i\/u\/unit-test-failure-600x526.png 600w\" sizes=\"auto, (max-width: 702px) 100vw, 702px\" \/><figcaption>Ugh. Ich wei\u00df, was schiefgelaufen ist, aber woher wei\u00df ich, warum es schiefgelaufen ist? <\/figcaption><\/figure><\/div>\n\n<p class=\"wp-block-paragraph\">Ich bin ein gro\u00dfer Fan von Unit-Tests bei der Entwicklung von APIs wie den Datenkodierungs- und -dekodierungsfunktionen von <a href=\"https:\/\/ruuvi.com\/de\/\">Ruuvi<\/a>. Die Tests erm\u00f6glichen es uns, die Dokumentation und die Ausgabe des Codes miteinander zu verkn\u00fcpfen, da die dokumentierten Normalf\u00e4lle, Grenzf\u00e4lle und Fehler als Tests ausgeschrieben werden. <\/p>\n\n<p class=\"wp-block-paragraph\">Der Nachteil ist, dass wir nicht dieselben Tools verwenden k\u00f6nnen, die wir von Integrationstests des gesamten Programms kennen, wie zum Beispiel unseren eingebetteten Ger\u00e4te-IDE-Debugger, wenn wir die Unit-Tests selbst debuggen wollen.<\/p>\n\n<p class=\"wp-block-paragraph\">Obwohl das Ausgeben von Nachrichten w\u00e4hrend der Programmausf\u00fchrung seinen Platz hat, z. B. bei der Ausf\u00fchrung von Code mit harten Echtzeitanforderungen, wo ein Debugger, der die Ausf\u00fchrung stoppt, zu einem Systemausfall f\u00fchrt, bevorzuge ich, wenn m\u00f6glich, einen richtigen Debugger zu verwenden.<\/p>\n\n<p class=\"wp-block-paragraph\">Das hier verwendete Codebeispiel sind in Arbeit befindliche Kommunikations-De-\/Encoder f\u00fcr die Ruuvi Gateway nRF52- und ESP32-Kommunikation, verf\u00fcgbar auf <a href=\"https:\/\/github.com\/ruuvi\/ruuvi.endpoints.c\/tree\/ruuviblog-ceedling\">GitHub<\/a> im Branch ruuviblog-ceedling.<\/p>\n\n<h2 class=\"wp-block-heading\">Struktur unseres Projekts<\/h2>\n\n<p class=\"wp-block-paragraph\">Die meisten meiner C-Projekte haben heutzutage dieselbe Struktur:<\/p>\n\n<ul class=\"wp-block-list\"><li>Der Ordner <strong>.github<\/strong>, in dem sich unsere GitHub Actions befinden, um die Tests, die Doxygen-Generierung, die Stilpr\u00fcfung usw. automatisch auszuf\u00fchren, bevor Code in den Master-Branch gemergt werden kann.<\/li><li>Der Ordner <strong>build<\/strong>, in dem die Ausgaben des Unit-Test-Frameworks <a href=\"https:\/\/www.google.com\/search?client=safari&amp;rls=en&amp;biw=2016&amp;bih=1033&amp;ei=P5W7X9n9IuCHwPAP_Juc-AI&amp;q=ceedling&amp;oq=ceedling&amp;gs_lcp=CgZwc3ktYWIQA1C6GFi6GGCHGWgAcAB4AIABfogBfpIBAzAuMZgBAKABAaoBB2d3cy13aXrAAQE&amp;sclient=psy-ab&amp;ved=0ahUKEwiZmeXQwJjtAhXgAxAIHfwNBy84ChDh1QMIDA&amp;uact=5\">Ceedling<\/a> gespeichert werden.<\/li><li>Der Ordner <strong>src<\/strong>, in dem sich der eigentliche Quellcode befindet.<\/li><li>Der Ordner <strong>test<\/strong> zum Speichern des Unit-Test-Codes.<\/li><li>Verschiedene Konfigurationsdateien f\u00fcr die Tools und die Dokumentation auf Root-Ebene<\/li><\/ul>\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"376\" height=\"726\" src=\"https:\/\/ruuvi.com\/i\/u\/folders.png\" alt=\"Ordnerverzeichnis\" class=\"wp-image-3360\" srcset=\"https:\/\/ruuvi.com\/i\/u\/folders.png 376w, https:\/\/ruuvi.com\/i\/u\/folders-233x450.png 233w\" sizes=\"auto, (max-width: 376px) 100vw, 376px\" \/><figcaption>Heute interessieren uns am meisten die Ordner build, src und test.<\/figcaption><\/figure><\/div>\n\n<h2 class=\"wp-block-heading\">Den Debugger ausf\u00fchren<\/h2>\n\n<p class=\"wp-block-paragraph\">Ceedling arbeitet intern, indem es f\u00fcr jeden Test eine ausf\u00fchrbare Datei erstellt und deren Ausgabe \u00fcberpr\u00fcft. Das gibt uns einen hervorragenden Einstiegspunkt in unseren Test. <\/p>\n\n<p class=\"wp-block-paragraph\">Nehmen wir den letzten fehlgeschlagenen Testfall, <em>test_ruuvi_endpoint_ca_uart_adv_decode<\/em>. Dieser bezieht sich auf die Dekodierung eines serialisierten Bluetooth-Werbescan-Berichts in ein strukturiertes Objekt mit MAC-Adresse des Senders, RSSI und Nutzlastdaten.<\/p>\n\n<pre class=\"wp-block-code\"><code>void test_ruuvi_endpoint_ca_uart_adv_decode (void)\n{\n    re_status_t err_code = RE_SUCCESS;\n    uint8_t data&#91;] =\n    {\n        RE_CA_UART_STX,\n        41U + CMD_IN_LEN,\n        RE_CA_UART_SET_PHY,\n        0xC9U, 0x44U, 0x54U, 0x29U, 0xE3U, 0x8DU, RE_CA_UART_FIELD_DELIMITER, \/\/!&lt; MAC\n        0x02U, 0x01U, 0x04U, 0x1BU, 0xFFU, 0x99U, 0x04U, 0x05U, 0x0FU, 0x27U, 0x40U, \n        0x35U, 0xC4U, 0x54U, 0x00U, 0x50U, 0x00U, 0xC8U, 0xFCU, 0x20U, 0xA4U, 0x56U, \n        0xF0U, 0x30U, 0xE5U, 0xC9U, 0x44U, 0x54U, 0x29U, 0xE3U, 0x8DU, \n        RE_CA_UART_FIELD_DELIMITER, \/\/!&lt; Data\n        0xD8U, RE_CA_UART_FIELD_DELIMITER, \/\/RSSI\n        RE_CA_UART_ETX\n    };\n    re_ca_uart_ble_adv_t expect_params =\n    {\n        { 0xC9U, 0x44U, 0x54U, 0x29U, 0xE3U, 0x8DU }, \/\/!&lt; MAC\n        {\n            0x02U, 0x01U, 0x04U, 0x1BU, 0xFFU, 0x99U, 0x04U, 0x05U, 0x0FU, 0x27U, 0x40U,\n            0x35U, 0xC4U, 0x54U, 0x00U, 0x50U, 0x00U, 0xC8U, 0xFCU, 0x20U, 0xA4U, 0x56U, \n            0xF0U, 0x30U, 0xE5U, 0xC9U, 0x44U, 0x54U, 0x29U, 0xE3U, 0x8DU\n        },   \/\/!&lt; Data\n        31U, \/\/!&lt; Data length\n        -40  \/\/RSSI\n    };\n    re_ca_uart_cmd_t expect_cmd = RE_CA_UART_ADV_RPRT;\n    re_ca_uart_payload_t payload = {0};\n    err_code = re_ca_uart_decode (data, &amp;payload);\n    TEST_ASSERT (RE_SUCCESS == err_code);\n    TEST_ASSERT (!memcmp (&amp;expect_params, &amp;payload.params.adv, sizeof (expect_params)));\n    TEST_ASSERT (!memcmp (&amp;expect_cmd, &amp;payload.cmd, sizeof (expect_cmd)));\n}<\/code><\/pre>\n\n<p class=\"has-text-align-center wp-block-paragraph\"><\/p>\n\n<p class=\"wp-block-paragraph\"><a href=\"https:\/\/gist.githubusercontent.com\/ojousima\/8b46de8b73b7194f55f5f5be32984791\/raw\/2e30bcb83996c20232cc1e057254155155b26f67\/ruuviblog-ceedling-testsnippet.c\">Roh anzeigen<\/a><\/p>\n\n<p class=\"has-text-align-center wp-block-paragraph\"><em>Unser Testfall definiert die Daten, die an den Decoder gehen, und die erwartete Ausgabe. Daten werden geparst und die geparsten Ausgaben mit unseren Erwartungen verglichen. <\/em><\/p>\n\n<pre class=\"wp-block-code\"><code>static re_status_t re_ca_uart_decode_adv_rprt (const uint8_t * const buffer,\n        re_ca_uart_payload_t * const payload)\n{\n    re_status_t err_code = RE_SUCCESS;\n\n    if (buffer&#91;RE_CA_UART_LEN_INDEX] != RE_CA_UART_CMD_PHY_LEN)\n    {\n        err_code |= RE_ERROR_DECODING;\n    }\n    else\n    {\n        payload-&gt;cmd = RE_CA_UART_ADV_RPRT;\n        memcpy (payload-&gt;params.adv.mac,\n                buffer + RE_CA_UART_PAYLOAD_INDEX, RE_CA_UART_MAC_BYTES);\n        payload-&gt;params.adv.adv_len = buffer&#91;RE_CA_UART_LEN_INDEX]\n                                      - RE_CA_UART_MAC_BYTES - RE_CA_UART_RSSI_BYTES;\n        memcpy (payload-&gt;params.adv.adv,\n                buffer + RE_CA_UART_PAYLOAD_INDEX + RE_CA_UART_MAC_BYTES,\n                payload-&gt;params.adv.adv_len);\n        payload-&gt;params.adv.rssi_db = u8toi8 (\n                                          buffer&#91;RE_CA_UART_PAYLOAD_INDEX\n                                                  + buffer&#91;RE_CA_UART_LEN_INDEX]\n                                                  - RE_CA_UART_RSSI_BYTES]);\n    }\n    return err_code;\n}\n\nre_status_t re_ca_uart_decode (const uint8_t * const buffer,\n                               re_ca_uart_payload_t * const payload)\n{\n    re_status_t err_code = RE_SUCCESS;\n\n    \/\/ Sanity check buffer format\n    if (NULL == buffer)\n    {\n        err_code |= RE_ERROR_NULL;\n    }\n    else if (NULL == payload)\n    {\n        err_code |= RE_ERROR_NULL;\n    }\n    else if (RE_CA_UART_STX != buffer&#91;RE_CA_UART_STX_INDEX])\n    {\n        err_code |= RE_ERROR_DECODING;\n    }\n    else if (RE_CA_UART_ETX != buffer&#91;buffer&#91;RE_CA_UART_LEN_INDEX] + RE_CA_UART_HEADER_SIZE])\n    {\n        err_code |= RE_ERROR_DECODING;\n    }\n    else if (RE_CA_UART_NOT_CODED != payload-&gt;cmd)\n    {\n        err_code |= RE_ERROR_INVALID_PARAM;\n    }\n    else\n    {\n        switch (buffer&#91;RE_CA_UART_CMD_INDEX])\n        {\n            case RE_CA_UART_SET_FLTR:\n                err_code |= re_ca_uart_decode_set_fltr (buffer, payload);\n                break;\n\n            case RE_CA_UART_CLR_FLTR:\n                err_code |= re_ca_uart_decode_clr_fltr (buffer, payload);\n                break;\n\n            case RE_CA_UART_SET_CH:\n                err_code |= re_ca_uart_decode_set_ch (buffer, payload);\n                break;\n\n            case RE_CA_UART_SET_PHY:\n                err_code |= re_ca_uart_decode_set_phy (buffer, payload);\n                break;\n\n            case RE_CA_UART_ADV_RPRT:\n                err_code |= re_ca_uart_decode_adv_rprt (buffer, payload);\n                break;\n\n            default:\n                err_code |= RE_ERROR_DECODING;\n                break;\n        }\n    }\n\n    return err_code;\n}<\/code><\/pre>\n\n<p class=\"has-text-align-center wp-block-paragraph\"><\/p>\n\n<p class=\"wp-block-paragraph\"><a href=\"https:\/\/gist.githubusercontent.com\/ojousima\/a0c9b5b68a97f4180dfe9a0b7b368125\/raw\/3268e5ec21d2952117657b3bd1f6d79a7694191c\/ruuviblog-ceedling-parser.c\">Roh anzeigen<\/a><\/p>\n\n<p class=\"has-text-align-center wp-block-paragraph\"><em>Unser Code f\u00fchrt einige Plausibilit\u00e4tspr\u00fcfungen durch und leitet die Daten dann an den korrekten Parser weiter, wie durch den in den Daten enthaltenen Nutzlasttyp bestimmt.<\/em><\/p>\n\n<p class=\"wp-block-paragraph\">Um eine bessere Vorstellung davon zu bekommen, was schiefgelaufen ist, f\u00fchren wir aus<\/p>\n\n<pre class=\"wp-block-code\"><code>lldb build\/test\/out\/test_ruuvi_endpoint_ca_uart.out<\/code><\/pre>\n\n<p class=\"wp-block-paragraph\">was die Testdatei in lldb \u00f6ffnet. GDB funktioniert genauso gut, wenn du das bevorzugst. <\/p>\n\n<pre class=\"wp-block-code\"><code>(lldb)type format add --format hex uint8_t<br>(lldb) breakpoint set --file ruuvi_endpoint_ca_uart.c --line 150<br>(lldb) breakpoint set --file test_ruuvi_endpoint_ca_uart.c --line 411<br>(lldb) run<\/code><\/pre>\n\n<p class=\"wp-block-paragraph\">Wir setzen Breakpoints in der Testdatei vor der Zeile, die den Decoder ausf\u00fchrt, und im Decoder am Anfang der Plausibilit\u00e4tspr\u00fcfungen.<\/p>\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"378\" src=\"https:\/\/ruuvi.com\/i\/u\/process-stopped-1024x378.png\" alt=\"Code, der den gestoppten Prozess anzeigt\" class=\"wp-image-3361\" srcset=\"https:\/\/ruuvi.com\/i\/u\/process-stopped-1024x378.png 1024w, https:\/\/ruuvi.com\/i\/u\/process-stopped-450x166.png 450w, https:\/\/ruuvi.com\/i\/u\/process-stopped-768x283.png 768w, https:\/\/ruuvi.com\/i\/u\/process-stopped-600x221.png 600w, https:\/\/ruuvi.com\/i\/u\/process-stopped.png 1176w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><figcaption>Hier sind wir, bereit, in unsere fehlerhafte Funktion einzusteigen.<\/figcaption><\/figure><\/div>\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"303\" src=\"https:\/\/ruuvi.com\/i\/u\/err-code-1024x303.png\" alt=\"Code, der den Fehler zeigt\" class=\"wp-image-3358\" srcset=\"https:\/\/ruuvi.com\/i\/u\/err-code-1024x303.png 1024w, https:\/\/ruuvi.com\/i\/u\/err-code-450x133.png 450w, https:\/\/ruuvi.com\/i\/u\/err-code-768x227.png 768w, https:\/\/ruuvi.com\/i\/u\/err-code-600x177.png 600w, https:\/\/ruuvi.com\/i\/u\/err-code.png 1170w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><figcaption>Und da ist der Fehler, wir steigen in den PHY-Nutzlast-Decoder ein, anstatt in den Werbebericht-Decoder.<\/figcaption><\/figure><\/div>\n\n<p class=\"wp-block-paragraph\">Der erste Fehler ist nun klar: In Zeile 8 der obigen Testfunktion haben wir falsche Daten eingerichtet, und der Parser gibt korrekterweise einen Fehlercode zur\u00fcck, der einen Assert ausl\u00f6st und den Test fehlschlagen l\u00e4sst.<\/p>\n\n<h2 class=\"wp-block-heading\">Die Fehler beheben<\/h2>\n\n<p class=\"wp-block-paragraph\">Von nun an ist die Fehlerbehebung ein iterativer Prozess. Wir korrigieren die Testdaten, f\u00fchren den Test erneut aus, nur um auf eine fehlerhafte L\u00e4ngenvalidierung im Decoder zu sto\u00dfen. Wir korrigieren die L\u00e4ngenvalidierung und sehen, dass das RSSI-Feld ein festes Trennzeichen anstelle des tats\u00e4chlichen RSSI-Wertes erh\u00e4lt. Wir korrigieren das RSSI-Feld, um festzustellen, dass die Werbel\u00e4nge falsch berechnet wird, was zu einem Puffer\u00fcberlauf f\u00fchrt und das RSSI-Feld immer noch \u00fcberschreibt. Wir beheben den \u00dcberlauf usw. usw. &#8230; Bis der Test schlie\u00dflich bestanden wird.    <\/p>\n\n<p class=\"wp-block-paragraph\">Nur weil der Test bestanden wird, hei\u00dft das nicht, dass der Code perfekt ist. Wir f\u00fcgen einen Testfall hinzu, der die Trennzeichen nicht in den Daten hat, und beginnen, neue Puffer\u00fcberl\u00e4ufe zu beheben. Schlie\u00dflich sind wir mit den getesteten Randf\u00e4llen zufrieden und bereit zu \u00fcberpr\u00fcfen, ob die Funktion von unseren Testf\u00e4llen abgedeckt wird.  <\/p>\n\n<pre class=\"wp-block-code\"><code>ceedling gcov:all utils:gcov<\/code><\/pre>\n\n<p class=\"wp-block-paragraph\">Mit diesem Befehl haben wir einen HTML-Bericht unserer Testausf\u00fchrung erstellt und k\u00f6nnen \u00fcberpr\u00fcfen, ob unsere Tests tats\u00e4chlich das abdecken, was wir von ihnen erwarten.<\/p>\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"899\" src=\"https:\/\/ruuvi.com\/i\/u\/err-codes-1024x899.png\" alt=\"Debugger zeigt Fehler an\" class=\"wp-image-3359\" srcset=\"https:\/\/ruuvi.com\/i\/u\/err-codes-1024x899.png 1024w, https:\/\/ruuvi.com\/i\/u\/err-codes-450x395.png 450w, https:\/\/ruuvi.com\/i\/u\/err-codes-768x674.png 768w, https:\/\/ruuvi.com\/i\/u\/err-codes-1536x1348.png 1536w, https:\/\/ruuvi.com\/i\/u\/err-codes-600x527.png 600w, https:\/\/ruuvi.com\/i\/u\/err-codes.png 1944w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><figcaption>Oh-oh, ein Test testet nicht das, was er soll.<\/figcaption><\/figure><\/div>\n\n<p class=\"wp-block-paragraph\">Es stellt sich heraus, dass das Entfernen des letzten Trennzeichens unsere Annahmen \u00fcber die Positionierung der Elemente innerhalb der Daten bricht und eine fr\u00fchere \u00dcberpr\u00fcfung die Dekodierung stoppt, und unser Test \u00fcberpr\u00fcft keine Bitfehler am letzten Trennzeichen. Das beheben wir auch. <\/p>\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"891\" src=\"https:\/\/ruuvi.com\/i\/u\/decoder-fully-tested-1024x891.png\" alt=\"Decoder vollst&#xE4;ndig getestet\" class=\"wp-image-3357\" srcset=\"https:\/\/ruuvi.com\/i\/u\/decoder-fully-tested-1024x891.png 1024w, https:\/\/ruuvi.com\/i\/u\/decoder-fully-tested-450x391.png 450w, https:\/\/ruuvi.com\/i\/u\/decoder-fully-tested-768x668.png 768w, https:\/\/ruuvi.com\/i\/u\/decoder-fully-tested-1536x1336.png 1536w, https:\/\/ruuvi.com\/i\/u\/decoder-fully-tested-600x522.png 600w, https:\/\/ruuvi.com\/i\/u\/decoder-fully-tested.png 1966w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><figcaption>Schlie\u00dflich ist unser Decoder vollst\u00e4ndig getestet und unsere Annahmen \u00fcber das Datenformat werden durch die Code-Eingabepr\u00fcfung verifiziert.<\/figcaption><\/figure><\/div>\n\n<h2 class=\"wp-block-heading\">Fazit<\/h2>\n\n<p class=\"wp-block-paragraph\">Unit-Tests sind ein m\u00e4chtiges Werkzeug zur Reduzierung von Fehlern in unserem Code, aber um den vollen Nutzen von Unit-Tests zu ziehen, ben\u00f6tigen wir einen separaten Satz von Tools, um zu \u00fcberpr\u00fcfen, ob unsere Tests tats\u00e4chlich das testen, was wir erwarten, und um die Tests selbst zu debuggen.<\/p>\n\n<p class=\"wp-block-paragraph\">Hier haben wir durchgesprochen, wie man LLDB oder GDB verwendet, um die Fehler in Ceedling zu debuggen. Wenn du an weiteren Beitr\u00e4gen zur Codequalit\u00e4t interessiert bist, lass es mich in <a href=\"http:\/\/slack.ruuvi.com\">Ruuvi Slack<\/a> oder den <a href=\"http:\/\/f.ruuvi.com\">Foren<\/a> wissen, und ich werde Folgebeitr\u00e4ge schreiben. <\/p>\n\n<p class=\"wp-block-paragraph\">Diese Beitr\u00e4ge werden durch deine K\u00e4ufe von RuuviTags unterst\u00fctzt. Wenn sie dir gefallen, <strong>miss deine Welt<\/strong>!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Ich bin ein gro\u00dfer Fan von Unit-Tests bei der Entwicklung von APIs wie den Datenkodierungs- und -dekodierungsfunktionen von Ruuvi. Die Tests erm\u00f6glichen es uns, die Dokumentation und die Ausgabe des Codes miteinander zu verkn\u00fcpfen, da die dokumentierten Normalf\u00e4lle, Grenzf\u00e4lle und Fehler als Tests ausgeschrieben werden. Der Nachteil ist, dass wir nicht dieselben Tools verwenden k\u00f6nnen, [&hellip;]<\/p>\n","protected":false},"author":6,"featured_media":135679,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[324],"tags":[],"class_list":["post-135674","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-ruuvi-software-artikel"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.8 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Ceedling Unit-Tests mit LLDB \/GDB debuggen - Ruuvi<\/title>\n<meta name=\"description\" content=\"Ceedling Unit-Tests mit LLDB \/GDB f\u00fcr eine bessere Entwicklung debuggen. Erfahre mehr dar\u00fcber, wie Unit-Tests und Softwaretests bei Ruuvi durchgef\u00fchrt werden.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/ruuvi.com\/de\/debugging-ceedling-unit-tests-with-lldb-gdb\/\" \/>\n<meta property=\"og:locale\" content=\"de_DE\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Ceedling Unit-Tests mit LLDB \/GDB debuggen - Ruuvi\" \/>\n<meta property=\"og:description\" content=\"Ceedling Unit-Tests mit LLDB \/GDB f\u00fcr eine bessere Entwicklung debuggen. Erfahre mehr dar\u00fcber, wie Unit-Tests und Softwaretests bei Ruuvi durchgef\u00fchrt werden.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/ruuvi.com\/de\/debugging-ceedling-unit-tests-with-lldb-gdb\/\" \/>\n<meta property=\"og:site_name\" content=\"Ruuvi\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/ruuvi.cc\" \/>\n<meta property=\"article:published_time\" content=\"2020-11-05T14:45:00+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2026-06-11T04:31:50+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/ruuvi.com\/i\/u\/unit-test-failure.png\" \/>\n\t<meta property=\"og:image:width\" content=\"702\" \/>\n\t<meta property=\"og:image:height\" content=\"616\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Otso Jousimaa\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@ruuvicom\" \/>\n<meta name=\"twitter:site\" content=\"@ruuvicom\" \/>\n<meta name=\"twitter:label1\" content=\"Verfasst von\" \/>\n\t<meta name=\"twitter:data1\" content=\"Otso Jousimaa\" \/>\n\t<meta name=\"twitter:label2\" content=\"Gesch\u00e4tzte Lesezeit\" \/>\n\t<meta name=\"twitter:data2\" content=\"8\u00a0Minute\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/ruuvi.com\\\/de\\\/debugging-ceedling-unit-tests-with-lldb-gdb\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/ruuvi.com\\\/de\\\/debugging-ceedling-unit-tests-with-lldb-gdb\\\/\"},\"author\":{\"name\":\"Otso Jousimaa\",\"@id\":\"https:\\\/\\\/ruuvi.com\\\/de\\\/#\\\/schema\\\/person\\\/143b8e2a095f1e6484b9186673c9ec00\"},\"headline\":\"Ceedling Unit-Tests mit LLDB \\\/GDB debuggen\",\"datePublished\":\"2020-11-05T14:45:00+00:00\",\"dateModified\":\"2026-06-11T04:31:50+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/ruuvi.com\\\/de\\\/debugging-ceedling-unit-tests-with-lldb-gdb\\\/\"},\"wordCount\":872,\"image\":{\"@id\":\"https:\\\/\\\/ruuvi.com\\\/de\\\/debugging-ceedling-unit-tests-with-lldb-gdb\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/ruuvi.com\\\/i\\\/u\\\/unit-test-failure.png\",\"articleSection\":[\"Ruuvi-Software-Artikel\"],\"inLanguage\":\"de\"},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/ruuvi.com\\\/de\\\/debugging-ceedling-unit-tests-with-lldb-gdb\\\/\",\"url\":\"https:\\\/\\\/ruuvi.com\\\/de\\\/debugging-ceedling-unit-tests-with-lldb-gdb\\\/\",\"name\":\"Ceedling Unit-Tests mit LLDB \\\/GDB debuggen - Ruuvi\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/ruuvi.com\\\/de\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/ruuvi.com\\\/de\\\/debugging-ceedling-unit-tests-with-lldb-gdb\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/ruuvi.com\\\/de\\\/debugging-ceedling-unit-tests-with-lldb-gdb\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/ruuvi.com\\\/i\\\/u\\\/unit-test-failure.png\",\"datePublished\":\"2020-11-05T14:45:00+00:00\",\"dateModified\":\"2026-06-11T04:31:50+00:00\",\"author\":{\"@id\":\"https:\\\/\\\/ruuvi.com\\\/de\\\/#\\\/schema\\\/person\\\/143b8e2a095f1e6484b9186673c9ec00\"},\"description\":\"Ceedling Unit-Tests mit LLDB \\\/GDB f\u00fcr eine bessere Entwicklung debuggen. Erfahre mehr dar\u00fcber, wie Unit-Tests und Softwaretests bei Ruuvi durchgef\u00fchrt werden.\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/ruuvi.com\\\/de\\\/debugging-ceedling-unit-tests-with-lldb-gdb\\\/#breadcrumb\"},\"inLanguage\":\"de\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/ruuvi.com\\\/de\\\/debugging-ceedling-unit-tests-with-lldb-gdb\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"de\",\"@id\":\"https:\\\/\\\/ruuvi.com\\\/de\\\/debugging-ceedling-unit-tests-with-lldb-gdb\\\/#primaryimage\",\"url\":\"https:\\\/\\\/ruuvi.com\\\/i\\\/u\\\/unit-test-failure.png\",\"contentUrl\":\"https:\\\/\\\/ruuvi.com\\\/i\\\/u\\\/unit-test-failure.png\",\"width\":702,\"height\":616,\"caption\":\"Ugh. Ich wei\u00df, was schiefgelaufen ist, aber woher wei\u00df ich, warum es schiefgelaufen ist?\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/ruuvi.com\\\/de\\\/debugging-ceedling-unit-tests-with-lldb-gdb\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/ruuvi.com\\\/de\\\/front\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Ceedling Unit-Tests mit LLDB \\\/GDB debuggen\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/ruuvi.com\\\/de\\\/#website\",\"url\":\"https:\\\/\\\/ruuvi.com\\\/de\\\/\",\"name\":\"Ruuvi\",\"description\":\"Measure Your World\",\"potentialAction\":[],\"inLanguage\":\"de\"},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/ruuvi.com\\\/de\\\/#\\\/schema\\\/person\\\/143b8e2a095f1e6484b9186673c9ec00\",\"name\":\"Otso Jousimaa\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"de\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/fd52303e35b8b23c01cfeec7bb2636768de567cd33604f794ae86dd971e61645?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/fd52303e35b8b23c01cfeec7bb2636768de567cd33604f794ae86dd971e61645?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/fd52303e35b8b23c01cfeec7bb2636768de567cd33604f794ae86dd971e61645?s=96&d=mm&r=g\",\"caption\":\"Otso Jousimaa\"},\"url\":\"https:\\\/\\\/ruuvi.com\\\/de\\\/author\\\/ojousima\\\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Ceedling Unit-Tests mit LLDB \/GDB debuggen - Ruuvi","description":"Ceedling Unit-Tests mit LLDB \/GDB f\u00fcr eine bessere Entwicklung debuggen. Erfahre mehr dar\u00fcber, wie Unit-Tests und Softwaretests bei Ruuvi durchgef\u00fchrt werden.","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:\/\/ruuvi.com\/de\/debugging-ceedling-unit-tests-with-lldb-gdb\/","og_locale":"de_DE","og_type":"article","og_title":"Ceedling Unit-Tests mit LLDB \/GDB debuggen - Ruuvi","og_description":"Ceedling Unit-Tests mit LLDB \/GDB f\u00fcr eine bessere Entwicklung debuggen. Erfahre mehr dar\u00fcber, wie Unit-Tests und Softwaretests bei Ruuvi durchgef\u00fchrt werden.","og_url":"https:\/\/ruuvi.com\/de\/debugging-ceedling-unit-tests-with-lldb-gdb\/","og_site_name":"Ruuvi","article_publisher":"https:\/\/www.facebook.com\/ruuvi.cc","article_published_time":"2020-11-05T14:45:00+00:00","article_modified_time":"2026-06-11T04:31:50+00:00","og_image":[{"width":702,"height":616,"url":"https:\/\/ruuvi.com\/i\/u\/unit-test-failure.png","type":"image\/png"}],"author":"Otso Jousimaa","twitter_card":"summary_large_image","twitter_creator":"@ruuvicom","twitter_site":"@ruuvicom","twitter_misc":{"Verfasst von":"Otso Jousimaa","Gesch\u00e4tzte Lesezeit":"8\u00a0Minute"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/ruuvi.com\/de\/debugging-ceedling-unit-tests-with-lldb-gdb\/#article","isPartOf":{"@id":"https:\/\/ruuvi.com\/de\/debugging-ceedling-unit-tests-with-lldb-gdb\/"},"author":{"name":"Otso Jousimaa","@id":"https:\/\/ruuvi.com\/de\/#\/schema\/person\/143b8e2a095f1e6484b9186673c9ec00"},"headline":"Ceedling Unit-Tests mit LLDB \/GDB debuggen","datePublished":"2020-11-05T14:45:00+00:00","dateModified":"2026-06-11T04:31:50+00:00","mainEntityOfPage":{"@id":"https:\/\/ruuvi.com\/de\/debugging-ceedling-unit-tests-with-lldb-gdb\/"},"wordCount":872,"image":{"@id":"https:\/\/ruuvi.com\/de\/debugging-ceedling-unit-tests-with-lldb-gdb\/#primaryimage"},"thumbnailUrl":"https:\/\/ruuvi.com\/i\/u\/unit-test-failure.png","articleSection":["Ruuvi-Software-Artikel"],"inLanguage":"de"},{"@type":"WebPage","@id":"https:\/\/ruuvi.com\/de\/debugging-ceedling-unit-tests-with-lldb-gdb\/","url":"https:\/\/ruuvi.com\/de\/debugging-ceedling-unit-tests-with-lldb-gdb\/","name":"Ceedling Unit-Tests mit LLDB \/GDB debuggen - Ruuvi","isPartOf":{"@id":"https:\/\/ruuvi.com\/de\/#website"},"primaryImageOfPage":{"@id":"https:\/\/ruuvi.com\/de\/debugging-ceedling-unit-tests-with-lldb-gdb\/#primaryimage"},"image":{"@id":"https:\/\/ruuvi.com\/de\/debugging-ceedling-unit-tests-with-lldb-gdb\/#primaryimage"},"thumbnailUrl":"https:\/\/ruuvi.com\/i\/u\/unit-test-failure.png","datePublished":"2020-11-05T14:45:00+00:00","dateModified":"2026-06-11T04:31:50+00:00","author":{"@id":"https:\/\/ruuvi.com\/de\/#\/schema\/person\/143b8e2a095f1e6484b9186673c9ec00"},"description":"Ceedling Unit-Tests mit LLDB \/GDB f\u00fcr eine bessere Entwicklung debuggen. Erfahre mehr dar\u00fcber, wie Unit-Tests und Softwaretests bei Ruuvi durchgef\u00fchrt werden.","breadcrumb":{"@id":"https:\/\/ruuvi.com\/de\/debugging-ceedling-unit-tests-with-lldb-gdb\/#breadcrumb"},"inLanguage":"de","potentialAction":[{"@type":"ReadAction","target":["https:\/\/ruuvi.com\/de\/debugging-ceedling-unit-tests-with-lldb-gdb\/"]}]},{"@type":"ImageObject","inLanguage":"de","@id":"https:\/\/ruuvi.com\/de\/debugging-ceedling-unit-tests-with-lldb-gdb\/#primaryimage","url":"https:\/\/ruuvi.com\/i\/u\/unit-test-failure.png","contentUrl":"https:\/\/ruuvi.com\/i\/u\/unit-test-failure.png","width":702,"height":616,"caption":"Ugh. Ich wei\u00df, was schiefgelaufen ist, aber woher wei\u00df ich, warum es schiefgelaufen ist?"},{"@type":"BreadcrumbList","@id":"https:\/\/ruuvi.com\/de\/debugging-ceedling-unit-tests-with-lldb-gdb\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/ruuvi.com\/de\/front\/"},{"@type":"ListItem","position":2,"name":"Ceedling Unit-Tests mit LLDB \/GDB debuggen"}]},{"@type":"WebSite","@id":"https:\/\/ruuvi.com\/de\/#website","url":"https:\/\/ruuvi.com\/de\/","name":"Ruuvi","description":"Measure Your World","potentialAction":[],"inLanguage":"de"},{"@type":"Person","@id":"https:\/\/ruuvi.com\/de\/#\/schema\/person\/143b8e2a095f1e6484b9186673c9ec00","name":"Otso Jousimaa","image":{"@type":"ImageObject","inLanguage":"de","@id":"https:\/\/secure.gravatar.com\/avatar\/fd52303e35b8b23c01cfeec7bb2636768de567cd33604f794ae86dd971e61645?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/fd52303e35b8b23c01cfeec7bb2636768de567cd33604f794ae86dd971e61645?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/fd52303e35b8b23c01cfeec7bb2636768de567cd33604f794ae86dd971e61645?s=96&d=mm&r=g","caption":"Otso Jousimaa"},"url":"https:\/\/ruuvi.com\/de\/author\/ojousima\/"}]}},"_links":{"self":[{"href":"https:\/\/ruuvi.com\/de\/wp-json\/wp\/v2\/posts\/135674","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/ruuvi.com\/de\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/ruuvi.com\/de\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/ruuvi.com\/de\/wp-json\/wp\/v2\/users\/6"}],"replies":[{"embeddable":true,"href":"https:\/\/ruuvi.com\/de\/wp-json\/wp\/v2\/comments?post=135674"}],"version-history":[{"count":1,"href":"https:\/\/ruuvi.com\/de\/wp-json\/wp\/v2\/posts\/135674\/revisions"}],"predecessor-version":[{"id":135680,"href":"https:\/\/ruuvi.com\/de\/wp-json\/wp\/v2\/posts\/135674\/revisions\/135680"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/ruuvi.com\/de\/wp-json\/wp\/v2\/media\/135679"}],"wp:attachment":[{"href":"https:\/\/ruuvi.com\/de\/wp-json\/wp\/v2\/media?parent=135674"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/ruuvi.com\/de\/wp-json\/wp\/v2\/categories?post=135674"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/ruuvi.com\/de\/wp-json\/wp\/v2\/tags?post=135674"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}