GithubHelp home page GithubHelp logo

Comments (10)

xandro0777 avatar xandro0777 commented on May 31, 2024

after fixing the issue with the permission the file is created - but println() still writes to syslog instead of writing to my file :(

Any idea what did go wrong there or how to debug?

from vab.

xandro0777 avatar xandro0777 commented on May 31, 2024

after digging into it I am a bit surprised that the output of VAB apps goes into system logs at all. Stackoverflow and other places mention that stdout and stderr from NDK apps goes to /dev/null - which would be the behaviour I see with C.perror()

from vab.

Larpon avatar Larpon commented on May 31, 2024

Only thing I know is that we override printf in a macro

from vab.

xandro0777 avatar xandro0777 commented on May 31, 2024

from vab.

Larpon avatar Larpon commented on May 31, 2024

It was made initially to speed up development on Android - since otherwise I had to work "in the dark" which wasn't fun 😅 I'm still not sure what we should do to make a better solution.

It's nice for developers to be able to use println and eprintln seamlessly on Android while developing apps. Maybe we can use some compiletime define to switch it off 🤔

from vab.

xandro0777 avatar xandro0777 commented on May 31, 2024

Not sure either.

Redirecting stdin and stderr to a file on /sdcard like I did is easy and has the advantage that the output can be examined without adb and all low-level io output routines work as well.

To send stdout etc to syslog properly people do complicated things like https://codelab.wordpress.com/2014/11/03/how-to-use-standard-output-streams-for-logging-in-android-apps/ This has the advantage that it catches all output unlike the current macro hack and if someone like me wants to redirect it to a file it should work just like on Linux. The only disadvantage is complexity.. never tried it myself and not sure how robust that is.

The current hack is good enough most of the time but it would be nice if it would switch real printf and android logging based for example on a global c variable. The way the macro interacts with the print definition in builtin/buitlin.c.v is fairly convoluted so I am not sure how to do it but perhaps something like

	#define printf(...) {if (_use_log_io){__android_log_print(ANDROID_LOG_INFO, V_ANDROID_LOG_TAG_NAME, __VA_ARGS__)}else{printf(__VA_ARGS)}}
	#define fprintf(a, ...)  {if (_use_log_io){__android_log_print(ANDROID_LOG_ERROR, V_ANDROID_LOG_TAG_NAME, __VA_ARGS__)}else{fprintf(a,__VA_ARGS)}}

This would have the advantage that something would always work and is easy enough to revert to "normal" behavior.

from vab.

xandro0777 avatar xandro0777 commented on May 31, 2024

I did test the last variant - use a global c variable to switch between current redirect to log macro and normal stdout/stderr output which can be redirected as expected. So unless the developer does C._use_log_io = 0 in his app the behavior will stay as before. It would have been slightly easier to achieve with conditional compilation but I believe switching the behavior at runtime is more useful as it can catch errors happening before the redirection is established.

The patch bellow does that, the only little problem is that it generates an innocent warning which I haven't yet figured out how to fix. Please feel free to reuse and improve, no copyright considerations attached.

diff --git a/thirdparty/sokol/sokol_v.h b/thirdparty/sokol/sokol_v.h
index cc086789..2880ba9a 100644
--- a/thirdparty/sokol/sokol_v.h
+++ b/thirdparty/sokol/sokol_v.h
@@ -13,8 +13,11 @@
 
        #define V_ANDROID_LOG_TAG_NAME V_ANDROID_LOG_NAME(V_ANDROID_LOG_TAG)
 
+        extern int _use_log_io;
        #include <android/log.h>
-       #define printf(...) __android_log_print(ANDROID_LOG_INFO, V_ANDROID_LOG_TAG_NAME, __VA_ARGS__)
-       #define fprintf(a, ...) __android_log_print(ANDROID_LOG_ERROR, V_ANDROID_LOG_TAG_NAME, __VA_ARGS__)
+#define printf(...) {if (_use_log_io){__android_log_print(ANDROID_LOG_INFO, V_ANDROID_LOG_TAG_NAME, __VA_ARGS__);}else{printf(__VA_ARGS__);}}
+#define fprintf(a, ...)  {if (_use_log_io){__android_log_print(ANDROID_LOG_ERROR, V_ANDROID_LOG_TAG_NAME, __VA_ARGS__);}else{fprintf(a,__VA_ARGS__);}}
+//#define printf(...) __android_log_print(ANDROID_LOG_INFO, V_ANDROID_LOG_TAG_NAME, __VA_ARGS__)
+//#define fprintf(a, ...) __android_log_print(ANDROID_LOG_ERROR, V_ANDROID_LOG_TAG_NAME, __VA_ARGS__)
 #endif
 
diff --git a/vlib/builtin/builtin.c.v b/vlib/builtin/builtin.c.v
index 0379c833..8a52c4d3 100644
--- a/vlib/builtin/builtin.c.v
+++ b/vlib/builtin/builtin.c.v
@@ -5,6 +5,10 @@ type FnExitCb = fn ()
 fn C.atexit(f FnExitCb) int
 fn C.strerror(int) &char
 
+$if android {
+       C._use_log_io = 1
+}
+
 [noreturn]
 fn vhalt() {
        for {}

To redirect stdout/stderr from an app to a file on SDCARD you could do something like

	file := C.freopen('/sdcard/v-log.txt'.str, c'w', C.stdout)
	if file == C.NULL {
		err := C.errno
		println('problem reopening: $err')
	}

	C.dup2(1, 2)
	C._use_log_io = 0

from vab.

Larpon avatar Larpon commented on May 31, 2024

@xandro0777 - I'm trying to figure out how we fix it the best way. My initial idea is to disable it in V itself and then enable it in vab per default - and then add a flag to vab: vab --no-printf-hijack to let you bypass the default behaviour.

The reason for not disabling it per default is that it's used a lot by developers and is somewhat expected for end-users that println('...') will end up in the android logs - and not in some black hole where they have to resort to reading the docs :)

Later I can add it as an ENV flag (maybe when I get to #125 ) and via .vab files etc.

from vab.

xandro0777 avatar xandro0777 commented on May 31, 2024

from vab.

Larpon avatar Larpon commented on May 31, 2024

Right. 🤔 let's start out with just the define/flag switch. I've PR'ed the initial changes to V - we'll see if anyone has any better ideas 👍

from vab.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.