{"id":1883,"date":"2016-04-20T10:42:29","date_gmt":"2016-04-20T17:42:29","guid":{"rendered":"http:\/\/visualgdb.com\/w\/?p=1883"},"modified":"2016-04-20T10:42:56","modified_gmt":"2016-04-20T17:42:56","slug":"debugging-native-code-with-devices-with-the-run-as-bug","status":"publish","type":"post","link":"https:\/\/visualgdb.com\/tutorials\/android\/run-as\/","title":{"rendered":"Debugging native code on Android devices with the &#8216;run-as&#8217; bug"},"content":{"rendered":"<p>This tutorial shows how to debug the native code in your Android apps on devices that do not support the &#8216;run-as&#8217; command. We will first demonstrate how to reproduce the &#8216;run-as&#8217; problem and then explain the workaround VisualGDB supports. Before you begin, install VisualGDB 5.1r5 or later.<\/p>\n<ol>\n<li>Start Visual Studio and open the VisualGDB Android Project Wizard:<a href=\"http:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/04\/01-wizard.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-1884\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/04\/01-wizard.png\" alt=\"01-wizard\" width=\"786\" height=\"469\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/04\/01-wizard.png 786w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/04\/01-wizard-300x179.png 300w\" sizes=\"(max-width: 786px) 100vw, 786px\" \/><\/a><\/li>\n<li>Proceed with the default &#8220;Create a new App&#8221; selection:<a href=\"http:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/04\/02-newapp.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-1885\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/04\/02-newapp.png\" alt=\"02-newapp\" width=\"717\" height=\"610\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/04\/02-newapp.png 717w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/04\/02-newapp-300x255.png 300w\" sizes=\"(max-width: 717px) 100vw, 717px\" \/><\/a><\/li>\n<li>On the next page proceed with the default app name and the package name:<a href=\"http:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/04\/03-appname.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-1886\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/04\/03-appname.png\" alt=\"03-appname\" width=\"717\" height=\"610\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/04\/03-appname.png 717w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/04\/03-appname-300x255.png 300w\" sizes=\"(max-width: 717px) 100vw, 717px\" \/><\/a><\/li>\n<li>Select your Android platform and press &#8220;Finish&#8221; to generate the project:<a href=\"http:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/04\/04-platform.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-1887\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/04\/04-platform.png\" alt=\"04-platform\" width=\"717\" height=\"610\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/04\/04-platform.png 717w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/04\/04-platform-300x255.png 300w\" sizes=\"(max-width: 717px) 100vw, 717px\" \/><\/a><\/li>\n<li>Once the project is generated, press Ctrl-Shift-B to build it:<a href=\"http:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/04\/05-build.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-1888\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/04\/05-build.png\" alt=\"05-build\" width=\"891\" height=\"740\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/04\/05-build.png 891w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/04\/05-build-300x249.png 300w\" sizes=\"(max-width: 891px) 100vw, 891px\" \/><\/a><\/li>\n<li>If you try to debug it now on a device with the run-as bug without testing the toolchain, you will get the following error:\n<pre class=\"\">run-as: Package 'com.visualgdb.example.AndroidProject1' is unknown<\/pre>\n<p><a href=\"http:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/04\/06-err.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-1889\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/04\/06-err.png\" alt=\"06-err\" width=\"658\" height=\"481\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/04\/06-err.png 658w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/04\/06-err-300x219.png 300w\" sizes=\"(max-width: 658px) 100vw, 658px\" \/><\/a>If you let VisualGDB test the toolchain, it will detect that the device needs the workaround and direct you to this page.<\/li>\n<li>The problem happens because debugging native code in your app requires running gdbserver &#8211; a special tool that runs on the Android device and exposes the internals of your app to the debugger. If your Android device has too restrictive rights on the <strong>\/data\/system\/packages.list<\/strong> file, the run-as tool won&#8217;t be able to read the file and launch gdbserver with the correct permissions. VisualGDB provides a workaround that allows launching the gdbserver directly from your app and connecting to it automatically. Open VisualGDB Project Properties, go to the Debug Settings page and select &#8220;Start gdbserver &#8211; manually from the app&#8221;:<a href=\"http:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/04\/07-runas.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-1890\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/04\/07-runas.png\" alt=\"07-runas\" width=\"1020\" height=\"675\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/04\/07-runas.png 1020w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/04\/07-runas-300x199.png 300w\" sizes=\"(max-width: 1020px) 100vw, 1020px\" \/><\/a><\/li>\n<li>This will automatically add a new file to your project that will be responsible for launching gdbserver. Before we look into that file, go to the Makefile Settings page of VisualGDB Project Properties and add &#8220;-DLAUNCH_GDBSERVER_FROM_APP&#8221; to both CFLAGS and CXXFLAGS and also add &#8220;-llog&#8221; to the System Library Names:<a href=\"http:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/04\/08-launcher.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-1891\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/04\/08-launcher.png\" alt=\"08-launcher\" width=\"823\" height=\"568\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/04\/08-launcher.png 823w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/04\/08-launcher-300x207.png 300w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/04\/08-launcher-392x272.png 392w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/04\/08-launcher-130x90.png 130w\" sizes=\"(max-width: 823px) 100vw, 823px\" \/><\/a><\/li>\n<li>When you press OK, VisualGDB will add a file called gdbserver_launcher.c to your project. The main role of that file is to launch the gdbserver executable shipped with your app and redirect its output to a socket so that VisualGDB can display any errors it reports:\n<pre class=\"\">static void DoLaunchGDBServer(const struct ControlBlock *pBlock, int socket)\r\n{\r\n\u00a0\u00a0\u00a0 char pid[32], port[32];\r\n\u00a0\u00a0\u00a0 sprintf(pid, \"%d\", getpid());\r\n\u00a0\u00a0\u00a0 sprintf(port, \":%d\", pBlock-&gt;GDBServerPort);\r\n\u00a0\u00a0 \u00a0\r\n\u00a0\u00a0\u00a0 if (fork() == 0)\r\n\u00a0\u00a0\u00a0 {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 dup2(socket, STDOUT_FILENO);\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 dup2(socket, STDERR_FILENO);\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 int r = execl(pBlock-&gt;GDBServerPath,\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \"gdbserver\",\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 port,\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \"--attach\",\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 pid,\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 NULL);\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \/\/if execl() succeeds, control will never reach here\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 __android_log_print(ANDROID_LOG_ERROR, AppName, \"Failed to launch %s: error %d\", pBlock-&gt;GDBServerPath, r);\r\n\u00a0\u00a0\u00a0 }\r\n}<\/pre>\n<\/li>\n<li>The logic responsible\u00a0 for launching gdbserver will be automatically triggered when the library using the gdbserver_launcher.c is loaded:\n<pre class=\"\">__attribute__((constructor)) void GDBServerInitializer()\r\n{\r\n\u00a0\u00a0\u00a0 LaunchGDBServer();\r\n}<\/pre>\n<p>As the native library does not have access to the Java environment and cannot determine the gdbserver location, it will simply open a socket and rely on VisualGDB to tell it the location of the gdbserver and the port to use. VisualGDB will do it automatically as long as you have the workaround enabled in Debug Settings.<\/li>\n<li>Before you can debug your application, add the &#8220;android.permission.INTERNET&#8221; permission to the AndroidManifest.xml file. This will ensure that the application (and gdbserver) can actually open sockets and accept connections:<a href=\"http:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/04\/09-perm.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-1892\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/04\/09-perm.png\" alt=\"09-perm\" width=\"934\" height=\"750\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/04\/09-perm.png 934w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/04\/09-perm-300x241.png 300w\" sizes=\"(max-width: 934px) 100vw, 934px\" \/><\/a><\/li>\n<li>If you press F5 now, VisualGDB will automatically take care of locating and launching gdbserver and will start debugging for you:<a href=\"http:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/04\/10-debug.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-1893\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/04\/10-debug.png\" alt=\"10-debug\" width=\"934\" height=\"750\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/04\/10-debug.png 934w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/04\/10-debug-300x241.png 300w\" sizes=\"(max-width: 934px) 100vw, 934px\" \/><\/a>The only differences from the regular debugging will be:\n<ul>\n<li>Your app will always launch gdbserver and wait for the debugger when it is started. If you want to launch the app without debugging, build a separate configuration of it without the LAUNCH_GDBSERVER_FROM_APP macro so that the gdbserver_launcher won&#8217;t engage.<\/li>\n<li>If your app uses several native libraries, the gdbserver_launcher.c will need to be included in the one that is loaded the first. Otherwise you won&#8217;t be able to debug any code that runs before gdbserver is launched.<\/li>\n<\/ul>\n<\/li>\n<li>If you encounter any problems with the gdbserver launcher, observe the logcat output of your Android device. The gdbserver launcher will report any errors it encounters there:<a href=\"http:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/04\/11-adb.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-1894\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/04\/11-adb.png\" alt=\"11-adb\" width=\"934\" height=\"750\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/04\/11-adb.png 934w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/04\/11-adb-300x241.png 300w\" sizes=\"(max-width: 934px) 100vw, 934px\" \/><\/a><\/li>\n<\/ol>\n","protected":false},"excerpt":{"rendered":"<p>This tutorial shows how to debug the native code in your Android apps on devices that do not support the<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[11],"tags":[31],"_links":{"self":[{"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/posts\/1883"}],"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=1883"}],"version-history":[{"count":2,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/posts\/1883\/revisions"}],"predecessor-version":[{"id":1896,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/posts\/1883\/revisions\/1896"}],"wp:attachment":[{"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/media?parent=1883"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/categories?post=1883"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/tags?post=1883"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}