{"id":6761,"date":"2020-10-06T17:30:37","date_gmt":"2020-10-07T00:30:37","guid":{"rendered":"https:\/\/visualgdb.com\/w\/?p=6761"},"modified":"2020-10-06T17:30:37","modified_gmt":"2020-10-07T00:30:37","slug":"startup-code-debugging-workaround","status":"publish","type":"post","link":"https:\/\/visualgdb.com\/documentation\/startupdebug\/","title":{"rendered":"Startup Code Debugging Workaround"},"content":{"rendered":"<p>VisualGDB supports a special workaround for embedded targets that do not properly implement halt-after-reset behavior. If after loading the memory and restarting, the target immediately starts running, and gets past <strong>main()<\/strong> before the debugger can set any breakpoints, follow the steps below to work around this behavior:<\/p>\n<ol>\n<li>Add the following code to your main source file:\n<pre class=\"\">static int SysprogsDebuggerIsAttached;\r\n\r\nvoid __attribute__((noinline)) WaitForSysprogsDebugger()\r\n{\r\n    while (!SysprogsDebuggerIsAttached)\r\n    {\r\n    }\r\n}<\/pre>\n<\/li>\n<li>Call <strong>WaitForSysprogsDebugger()<\/strong> from <strong>main()<\/strong>.<\/li>\n<li>Enable <strong>VisualGDB Project Properties -&gt; Embedded Debug Tweaking -&gt; Enable a workaround for debugging startup code<\/strong>:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/10\/startup-2.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-6764\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/10\/startup-2.png\" alt=\"\" width=\"1009\" height=\"701\" \/><\/a>Then, select one of the following modes as the startup debugging workaround mode:\n<ul>\n<li><strong>Hardcoded breakpoint instruction.<\/strong> In this mode VisualGDB will start debugging and wait for a hardcoded breakpoint to trigger inside <strong>WaitForSysprogsDebugger()<\/strong>. Once the breakpoint triggers, VisualGDB will set <strong>SysprogsDebuggerIsAttached<\/strong> to 1 and will continue executing. You can hardcode the breakpoint (and script skipping over it) as shown below:<br \/>\n<table style=\"border-collapse: collapse; width: 100%;\" border=\"1\">\n<tbody>\n<tr>\n<td style=\"width: 33.3333%;\">Platform<\/td>\n<td style=\"width: 33.3333%;\">Line at the beginning of WaitForSysprogsDebugger()<\/td>\n<td style=\"width: 33.3333%;\">Additional debugger command<\/td>\n<\/tr>\n<tr>\n<td style=\"width: 33.3333%;\">ARM<\/td>\n<td style=\"width: 33.3333%;\">\n<pre class=\"\">asm(\"bkpt 255\");<\/pre>\n<\/td>\n<td style=\"width: 33.3333%;\">\n<pre class=\"\">set $pc = $pc + 2;<\/pre>\n<\/td>\n<\/tr>\n<tr>\n<td style=\"width: 33.3333%;\">ESP8266\/ESP32<\/td>\n<td style=\"width: 33.3333%;\">\n<pre class=\"\">asm(\"break 1, 1\");<\/pre>\n<\/td>\n<td style=\"width: 33.3333%;\">\n<pre class=\"\">set $epc2 = $pc + 3;<\/pre>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/li>\n<li><strong>Timed break-in.<\/strong>\u00a0 VisualGDB will let the program start, then will stop GDB and check the call stack. If the program was stopped in <strong>WaitForSysprogsDebugger()<\/strong>, VisualGDB will set <strong>SysprogsDebuggerIsAttached<\/strong> to 1 and will continue execution.<\/li>\n<li><strong>Software\/hardware breakpoint in wait function.<\/strong> In this mode VisualGDB will set a breakpoint in <strong>WaitForSysprogsDebugger()<\/strong>. And will set <strong>SysprogsDebuggerIsAttached<\/strong> to 1 once it triggers. This mode can be used for backward compatibility where the breakpoints work from the beginning, but <strong>WaitForSysprogsDebugger()<\/strong> cannot be removed from the executable for compatibility reasons.<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>VisualGDB supports a special workaround for embedded targets that do not properly implement halt-after-reset behavior. If after loading the memory<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[197],"tags":[],"_links":{"self":[{"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/posts\/6761"}],"collection":[{"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/comments?post=6761"}],"version-history":[{"count":2,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/posts\/6761\/revisions"}],"predecessor-version":[{"id":6766,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/posts\/6761\/revisions\/6766"}],"wp:attachment":[{"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/media?parent=6761"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/categories?post=6761"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/tags?post=6761"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}