This is a direct port of the linux shell script.
NB. the lack of documentation surrounding functions should be addressed in both linux shell script and windows bat script. This is meant to be bug for bug compatible.
Differential D31695
Windows asan_device_setup.bat port of linux shell script gpx1000 on Apr 4 2017, 6:40 PM. Authored by
Details
This is a direct port of the linux shell script. NB. the lack of documentation surrounding functions should be addressed in both linux shell script and windows bat script. This is meant to be bug for bug compatible.
Diff Detail Event Timeline
Comment Actions I have no skin in this game, so feel free to ignore me, but instead of forking the script like this, could we
? Comment Actions Yes, (2) would be nice. Comment Actions I certainly would be game for rewriting this as a gradle plugin. It would seem easier to skip to step 2 in that regard, and wholly agree that a fork here isn't necessarily the best solution. However, I don't work for Google and thus have no idea what the requirements are for their use case (which might make a gradle plugin less than ideal). Thus I have no way to really determine which direction, or which language I'd want to make this head in. When I originally offered to do this port, I offered either a batch port of the existing bash file or a gradle plugin; assuming the gradle plugin could work in all places. Batch port was requested and doesn't require 3rd party tools installed that allow bash to run on windows. Comment Actions completely understood. It's up to you guys, am happy to offer keeping it updated as time allows. Although I'm more comfortable with bash and *nix than I am with windows. Lemme know what direction you guys want to take this in and I'll see what I can do to help. Comment Actions While I imagine gradle plugin would be useful for developers, we also need a command line utility that can be used in continuous testing setup. Comment Actions Python is a potential option? Although that gets into requiring third party tools/runtime. Lemme know if you have a language you'd recommend. Gradle made sense to me as my assumption that all environments would have a JVM in some form so could support it and can be used from the command line via gradlew. Comment Actions Is windows more likely to have java runtime environment then python? Maybe Python is a better choice. Is it reasonable to expect that an android developers' windows workstation has python runtime installed? Comment Actions Oh, how I wish I could say "yes, most windows devs have python installed." Unfortunately, It's highly unlikely to already be there. The only reason why it would be there from a pure Android developer perspective is to support working with MonkeyScript and then only a subset of those testers are going to have it as MonkeyScript uses Jython (JVM version of python). I think batch files are horrible for scripting purposes but Microsoft never really spent a lot of time focusing in on command line automation so many of our favorite tools just aren't available. JVM is the only real hard requirement to exist, in which case I'd venture gradle with maven is a better option. However, if you want something that just works on any windows machine, whether Android Studio is somewhere on the machine or only a standalone tool chain used from Unity/Unreal; then batch script is really the way to go which is what this commit is. I've never touched Go, yet would be very eager to give that a try. Not that we couldn't create a pure static executable with good ole' C/C++; it isn't fun if it's not a challenge, and Go is new to me so would qualify as a challenge. :) Comment Actions I did have one other crazy thought. This might be entirely doable from a monkeyrunner script. You'd be pushing the requirement that the developers have Android SDK installed (which delivers both a monkeyrunner.bat and a monkeyrunner bash script. However, then you'd be able to rewrite this in python, and as a bonus eliminate a good portion of the function calls here as they are duplicated there. That might work. Comment Actions This is a pure python version. Tested on windows.
Comment Actions As an aside, I have found a way to use ASan in devices using wrap.sh. So long as the device has the ability to use su or is a eng dev build the following wrap will work: #!/system/bin/sh-from-zygote\n I'm using it with this gradle: if(abi == "armeabi" || abi == "armeabi-v7a") abi = "arm" wrapFile.withWriter { writer -> writer.write('#!/system/bin/sh-from-zygote\n') writer.write('ASAN_OPTIONS=start_deactivated=1,malloc_context_size=0\n') writer.write('ASAN_ACTIVATION_OPTIONS=include_if_exists=/data/local/tmp/asan.options.b\n') writer.write("LD_PRELOAD=libclang_rt.asan-${abi}-android.so\n") writer.write('su -c setenforcing 0\n') writer.write('\$@\n') writer.write('su -c setenforcing 1\n') } } def libDir = file("$rootProject.ext.ndkDir").absolutePath + "/toolchains/llvm/prebuilt/" if(System.properties['os.name'].toLowerCase(Locale.ROOT).contains('windows')) libDir += "windows-x86_64/lib64/clang" else libDir += "*/lib*/*" for (String abi : ["armeabi-v7a"]) { def dir = new File("app/wrap_add_dir/" + abi) dir.mkdirs() def wrapFile = new File(dir, "wrap.sh") writeWrapScriptToFullyCompileJavaApp(wrapFile, abi) println "write file " + wrapFile.path println "libdir = " + libDir if(abi == "armeabi" || abi == "armeabi-v7a") abi = "arm" copy { from fileTree(libDir).files into dir.absolutePath include "**/*asan*" + abi + "*.so" } } } I'd note that with doing this; I'm not entirely sure there's still a need for this script to exist. I'm creating a blog post / tutorial on how to use ASan using the above wrap implementation; complete with example project. However, I'll make the suggested changes and resubmit.
Comment Actions This is great! Wrap.sh is definitely a better approach for 99% of users. Why are you saying that it needs an eng dev build though? I thought the idea behind wrap.sh is that it works on regular user devices, as long as the app has DEBUGGABLE in the manifest.
As I mentioned in other comments, this script does not pass the variables to the child environment. It needs to be a one-liner or do explicit "export". Did you test it with actual ASan-instrumented code in the app?
The only reason for the script to exist is performance - any wrap-based solution would restart the entire VM for every new process, which takes at least a few seconds.
Comment Actions It actually doesn't need to be an eng or dev build. I'm saying it needs root (setenforce 0 / setenforce 1 are the keys). If you have root, either through su or through adb root, then the wrap method will work.
Yep, tested it with a PixelXL and with emulator. Will add in the explicit export (was wondering why it didn't need it tbh).
That makes quite a bit of sense. alright, will refactor this script too. Thanks for the code review, these are some great ideas! Expect me to have a bit of time over the weekend to do it. Comment Actions Wait... egg on my face time. I sent you the script from my work machine. At home where I tested it the script looked like this (just looked at it): #!/system/bin/sh-from-zygote\n All is right with the world of linux shell scripting, my bug. Comment Actions I see. That's still bad, we'd like ASan to work on non-rooted devices. Do you know why setenforce 0 is necessary? Comment Actions completely agreed. I'd much prefer to not have to root. It looks like it's at least a known issue. I've been told by other google employees that there's a plan to address this in the emulator in future revisions by having multiple zygote processes. |
I don't know the language at all, but some of this indents look strange. Could you double check? Ex. in the --lib case below, two SHIFTs are at different indentation levels.