{"id":18836,"date":"2025-06-13T11:19:24","date_gmt":"2025-06-13T11:19:24","guid":{"rendered":"http:\/\/www.max-sperling.bplaced.net\/?p=18836"},"modified":"2025-08-08T08:58:40","modified_gmt":"2025-08-08T08:58:40","slug":"show-frames-in-stack-gdb","status":"publish","type":"post","link":"http:\/\/www.max-sperling.bplaced.net\/?p=18836","title":{"rendered":"Print stack frames (GDB)"},"content":{"rendered":"<h2>Scenario<\/h2>\n<h3>Application code<\/h3>\n<pre class=\"brush: cpp; title: main.cpp; notranslate\" title=\"main.cpp\">\r\n#include &lt;cstdio&gt;\r\n\r\nint add(int n1, int n2)\r\n{\r\n    int sum = n1 + n2;\r\n    printf(&quot;%d&quot;, sum);\r\n    return sum;\r\n}\r\n\r\nint main()\r\n{\r\n    int n1 = 3;\r\n    int n2 = 8;\r\n    int sum = add(n1, n2);\r\n    printf(&quot;%d&quot;, sum);\r\n    return 0;\r\n}\r\n<\/pre>\n<h3>Print frame script<\/h3>\n<pre class=\"brush: python; gutter: false; title: stackframe_printer.py; notranslate\" title=\"stackframe_printer.py\">\r\nimport gdb\r\n\r\nclass StackframePrinter(gdb.Command):\r\n    def __init__(self):\r\n        super().__init__(&quot;print-stackframe&quot;, gdb.COMMAND_USER)\r\n\r\n    def invoke(self, arg, from_tty):\r\n        cur = gdb.selected_frame()\r\n\r\n        try:\r\n            sp = int(cur.read_register(&quot;rsp&quot;))\r\n            print(f&quot;[Debug] Current SP: 0x{sp:x}&quot;)\r\n        except gdb.error as e:\r\n            print(f&quot;[Error] Cannot read current SP: {e}&quot;)\r\n            return\r\n\r\n        prev_sp = None\r\n        caller = cur.older()\r\n        if caller:\r\n            saved = gdb.selected_frame()\r\n            try:\r\n                prev_sp = int(caller.read_register(&quot;rsp&quot;))\r\n                print(f&quot;[Debug] Caller SP: 0x{prev_sp:x}&quot;)\r\n            except gdb.error as e:\r\n                print(f&quot;[Warn] Could not read caller SP: {e}&quot;)\r\n\r\n        if prev_sp and sp &lt; prev_sp:\r\n            count = (prev_sp - sp) \/\/ 8\r\n            addr = sp\r\n            print(f&quot;[Debug] Print {count} stack entries at 0x{addr:x}&quot;)\r\n            try:\r\n                gdb.execute(f&quot;x\/{count}gx {addr}&quot;)\r\n            except gdb.error as e:\r\n                print(f&quot;[Error] Memory dump failed: {e}&quot;)\r\n        elif prev_sp == sp:\r\n            print(&quot;[Info] Frame optimized.&quot;)\r\n        else:\r\n            print(&quot;[Error] Corrupted stack.&quot;)\r\n\r\nStackframePrinter()\r\n<\/pre>\n<hr>\n<h2>Analysis<\/h2>\n<h3>GDB session<\/h3>\n<pre class=\"brush: plain; gutter: false; title: ; notranslate\" title=\"\">\r\n$ lscpu | grep Arch\r\nArchitecture:                         x86_64\r\n$ g++ -g main.cpp\r\n$ gdb a.out \r\nGNU gdb (Debian 10.1-1.7) 10.1.90.20210103-git\r\n...\r\n(gdb) b 7\r\nBreakpoint 1 at 0x1164: file main.cpp, line 7.\r\n(gdb) r\r\nStarting program: \/home\/max.sperling\/Develop\/test\/a.out \r\n\r\nBreakpoint 1, add (n1=3, n2=8) at main.cpp:7\r\n7\t    return sum;\r\n(gdb) info frame\r\nStack level 0, frame at 0x7fffffffe270:\r\n rip = 0x555555555164 in add (main.cpp:7); saved rip = 0x55555555518e\r\n called by frame at 0x7fffffffe290\r\n source language c++.\r\n Arglist at 0x7fffffffe260, args: n1=3, n2=8\r\n Locals at 0x7fffffffe260, Previous frame&#039;s sp is 0x7fffffffe270\r\n Saved registers:\r\n  rbp at 0x7fffffffe260, rip at 0x7fffffffe268\r\n(gdb) info frame 1\r\nStack frame at 0x7fffffffe290:\r\n rip = 0x55555555518e in main (main.cpp:14); saved rip = 0x7ffff7e01d7a\r\n caller of frame at 0x7fffffffe270\r\n source language c++.\r\n Arglist at 0x7fffffffe280, args: \r\n Locals at 0x7fffffffe280, Previous frame&#039;s sp is 0x7fffffffe290\r\n Saved registers:\r\n  rbp at 0x7fffffffe280, rip at 0x7fffffffe288\r\n(gdb) source stackframe_printer.py \r\n(gdb) print-stackframe\r\n[Debug] Current SP: 0x7fffffffe240\r\n[Debug] Caller SP: 0x7fffffffe270\r\n[Debug] Print 6 stack entries at 0x7fffffffe240\r\n0x7fffffffe240:\t0x0000555555554040\t0x0000000300000008\r\n0x7fffffffe250:\t0x0000000000000000\t0x0000000b00000000\r\n0x7fffffffe260:\t0x00007fffffffe280\t0x000055555555518e\r\n<\/pre>\n<h3>Frame 0<\/h3>\n<pre>\r\n0x7fffffffe240:\t<font color=\"olive\">0x0000555555554040<\/font>\t0x<font color=\"blue\">00000003<\/font><font color=\"orange\">00000008<\/font>\r\n0x7fffffffe250:\t<font color=\"olive\">0x0000000000000000<\/font>\t<font color=\"brown\">0x0000000b<\/font><font color=\"olive\">00000000<\/font>\r\n0x7fffffffe260:\t<font color=\"green\">0x00007fffffffe280<\/font>\t<font color=\"purple\">0x000055555555518e<\/font>\r\n\r\n<font color=\"olive\">Unused preallocated uninitialized memory<\/font>\r\n<font color=\"blue\">Local Var 2<\/font>\r\n<font color=\"orange\">Local Var 1<\/font>\r\n<font color=\"brown\">Local Var 0<\/font>\r\n<font color=\"green\">Caller RBP<\/font>\r\n<font color=\"purple\">Caller RIP<\/font>\r\n<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>Scenario Application code Print frame script Analysis GDB session Frame 0 0x7fffffffe240: 0x0000555555554040 0x0000000300000008 0x7fffffffe250: 0x0000000000000000 0x0000000b00000000 0x7fffffffe260: 0x00007fffffffe280 0x000055555555518e<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"inline_featured_image":false},"categories":[28],"tags":[],"_links":{"self":[{"href":"http:\/\/www.max-sperling.bplaced.net\/index.php?rest_route=\/wp\/v2\/posts\/18836"}],"collection":[{"href":"http:\/\/www.max-sperling.bplaced.net\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/www.max-sperling.bplaced.net\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/www.max-sperling.bplaced.net\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/www.max-sperling.bplaced.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=18836"}],"version-history":[{"count":46,"href":"http:\/\/www.max-sperling.bplaced.net\/index.php?rest_route=\/wp\/v2\/posts\/18836\/revisions"}],"predecessor-version":[{"id":18984,"href":"http:\/\/www.max-sperling.bplaced.net\/index.php?rest_route=\/wp\/v2\/posts\/18836\/revisions\/18984"}],"wp:attachment":[{"href":"http:\/\/www.max-sperling.bplaced.net\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=18836"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/www.max-sperling.bplaced.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=18836"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/www.max-sperling.bplaced.net\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=18836"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}