I am importing some legacy code into an iOS app that uses stdout for some diagnostic output. Of course, iOS does not like you to write to stdout at all, and I need to get that output anyway. I would like to redirect this output to a file, then use the same legacy code again, redirecting the output to a different file. Does anyone know of a way to do this?
I've tried the simplistic
freopen(p, "w", stderr);
This does work--but only once. After using this call, all output to stdout is forever redirected. That's OK, but subsequent calls to redirect the output to a new location cause system instability that eventually leads to a crash. (I have tested this running from XCode, but not directly from a rebooted iPad. I don't know for sure the instability persists if not running in XCode using DEBUG mode.)
I've also tried the method in this post. This works, too, but does not return the system to its original state, and again, only works once. (If you try this at home, include Apple's <unisys.h> instead of <io.h>, and leave the _ off of calls like _dup and _dup2.)
I really don't want to have to go through the code and replace all uses of printf, etc to use an explicit file. In addition to being time consuming, error prone, and ugly, the code is open source. I don't expect the original authors would appreciate my changes, and I don't really want to have to reintegrate the changes each time the original project is updated.
Thoughts?
Related
I would like to build a IDE in the browser. Basically a WebApp where you choose which language you want to write code in, then you submit it to an endpoint, and get back the output.
I could not find any docker images that existed and I tried to use Judge but it seems like it is going to cause issues and there is no customer support.
Has anyone built something like this before?
I'm out of my wits. I'm trying to set up remote debugging of lua code in dockerized openresty. I use PHPStorm with EmmyLua extension, and the mobdebug library on the Lua end. I have been reading and hearing reports of this working for people, but for me stopping on a breakpoint (or immediately after mobdebug.start()) works about 15% of the time (evidence that I am not completely misconfiguring the thing), including exactly 0% of those places in my code that I actually want to debug.
I will not be debugging this issue. I intend to work around it by using an exact setup that is known to work, so I need someone for whom it does work to tell me what their setup is:
OS version
openresty version
mobdebug version
any custom patches or hacks you might have applied to get the debugging working
luasocket version (probably relevant)
PHPStorm version
EmmyLua version
docker and docker-compose version, if applicable
whatever you may suspect to be relevant
I am willing to completely raze my development environment and rebuild it exactly to the working spec, just to have working Lua debugging.
EDIT: for those interested, here are my detailed symptoms:
I can't stop at actual breakpoints, ever (i.e. after I initially stop after mobdebug.start() and then "Resume program" and a line with a breakpoint is hit, but it doesn't stop there)
I can stop after mobdebug.start() in code executed from init_by_lua_block, i.e. once per server start / config reload
I can't stop after mobdebug.start() in any code executed during handling a request, i.e. ssl_certificate_by_lua_block, rewrite_by_lua_block etc. This is probably understandable because coroutines are involved
All my attempts at enabling coroutine debugging in request handling code either error out or have no effect:
mobdebug.coro() in init_worker_by_lua_block() errors out with "API disabled in current context" somewhere in mobdebug.lua
mobdebug.on() in the function I want to debug either has no effect, or errors out with "attempt to yield across C-call boundary"; I haven't discerned the pattern yet.
stopping on a breakpoint (or immediately after mobdebug.start()) works about 15% of the time
Stopping after mobdebug.start() should work under all circumstances, except when there is a connection already established to the same debugger controller, so the fact that it doesn't usually points to the system that tries to establish multiple debugging sessions to the same controller/IDE (or no connection can be established at all).
Similarly, there are several reasons why breakpoints may not be working, but if they work in a file as part of a specific setup, then I'd expect them to always work in that case. Some of the reasons why breakpoints may not be working are listed in the documentation: https://studio.zerobrane.com/doc-faq#why-breakpoints-are-not-triggered.
mobdebug provides a command line-based controller, so for troubleshooting purposes it may be easier to use that instead of a more complex setup.
Is there a way to view the iphone console logs without having a mac ?
It used to be possible using the iPhone Configuration Utility but it does not seem to be available any longer.
I saw a tool called iTools but it seems to require a 32bit version of itunes which is also not available any more.
Given an iPhone device + windows + linux, Is there any workaround / tool to view the iphone console logs?
Realizing it is over half a year ago you asked this, but since it does not have an accepted answer yet:
I ran into this very same issue over and over, and got fed up with it, so I decided to have a go at writing a script that displays console messages in HTML, so you can just view everything in the webpage itself, without having to resort to a console-replacement or a tedious remote debugger (for which you, indeed, require a Mac), without having to modify each console call in existing code.
The key lies in 'replacing' the four main functions in window.console: log, warn, error and trace. This is done by redifining each method, adding own code to that, and calling the original method in the end. Jakub Fiala wrote the basic script for that, on which I built the rest: https://gist.github.com/jakubfiala/8fe3461ab6508f46003d
I dubbed it 'MobileConsole'. It is quite unobtrusive and will 'catch' all console.log (or .warn, .error or .trace) events, and even bind to window.onerror.
I have created a separate page for this script with an elaborate explanation on how it works, including a demo, over here.
Download this from the app store onto the iphone, you can then view logs directly on the phone:
https://itunes.apple.com/us/app/console/id317676250?mt=8
Please note, this is an old app, it will crash when launched, then on reopening it will show you the device logs.
If that fails, here is a link to the iPhone configuration utility for windows:
http://download.cnet.com/iPhone-Configuration-Utility-for-Windows/3000-20432_4-10969175.html
I like to use these to debug (can you tell I'm a noob?) and have left them in my code as is when deploying to the app store. Are there any negative implications for this you can personally think of?
I have looked at these resources and I am getting the feeling it's not a good idea:
http://doing-it-wrong.mikeweller.com/2012/07/youre-doing-it-wrong-1-nslogdebug-ios.html
https://developer.apple.com/library/mac/documentation/MacOSX/Conceptual/BPSystemStartup/Chapters/LoggingErrorsAndWarnings.html#//apple_ref/doc/uid/10000172i-SW8-SW7
This was also a good resource:
http://www.theonlylars.com/blog/2012/07/03/ditching-nslog-advanced-ios-logging-part-1/
That said, when you ship to the store and DO keep NSLogs in there, what have you logged?
Create a snippet with the above settings. Where it says "debug statement", replace that with:
<#debug statement#>
Now, since the completion shortcut is set to "NSLog", every time you start typing NSLog, it will autocomplete to this snippet and you will have the "debug statement" part selected and ready to type over.
You'll never have to worry about commenting out your NSLog statements again, and you'll never have to forget about using #if DEBUG since the completion shortcut is what you would type anyway.
Apple's Official Documentation for creating a Snippet (I've included this link because I think it's really kind of sad that this is apparently the only way to do it?)...
And my explanation...
Copy and paste the following code into Xcode:
#if DEBUG
NSLog(<#debug statement#>);
#endif
Select the entire code block you just copy-pasted. Click, hold, and drag this code block down to the snippets section (usually in the bottom right corner).
Select this snippet to get a screen like this:
Click "Edit" and fill out the details. Give it a title and description. Leave platform on "All", and language on "Objective-C". Set the completion shortcut to "NSLog", and leave the completion scope on "Function or Method" (what this option defauts to may depend on where you pasted the code to originally and where you dragged it from).
As Aaron Brager's answer points out, NSLog could be a performance concern, particularly in loops (also in places that don't seem very much like loops but actually are, like cellForRowAtIndexPath...).
But more importantly, you may be exposing information you don't necessarily want to be made publicly available.
I'm not saying there doesn't exist something that might be useful to include to present to the end user in the log statements, but personally, I've yet to find it. How many times have you ever investigated the output of an app's log statements to diagnose an issue you were having with it? How many times have you contacted an app developer and they asked you to check these statements to help diagnose a technical issue you were having?
The Mike Weller post you linked makes the right call. NSLog is for user-facing warnings.
There also might be performance issues, especially within loops, since it uses a string formatter.
You can and should use DDLog or other tools to ignore the debug messages when you make your release build.
Is is possible to open a text file and read the contents while another application is updating the file, in such a way that it does not cause a lock conflict?
I need to monitor a log file from one application which is updated by another application each time an event occurs.
I do check if the file is in use before I try to read it, but that does not seem to work in all cases.
Thanks, Pieter
it depends on how the first app open that file.
i.e when calling CreateFile API to open a file, there is dwShareMode param which tells the api how to open it (if this was given 0, it can't be accessed from other applications IIRC).
otherwise there should be no problem with reading from that file.
if im not mistaken, to check if that file is being opened read only u can call
something like
CreateFile(pchar(fName), GENERIC_READ or GENERIC_WRITE, 0, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0) ;
Download Process Monitor from Sysinternals.
Open the filter dialog and add a "path" filter for your log file.
Start the log-writing application (I'll call this "logwriter").
Look for and click on the event where logwriter does a CreateFile.
Under "Detail", it should have "Desired Access: Generic Write". And it should have "ShareMode: Read", which corresponds to FILE_SHARE_READ in the call to CreateFile. What it means is, "I, logwriter, permit others to read my file".
Now run your log-reading application ("logreader"), and do the same exercise.
The Detail should have "Desired Access: Generic Read". And it should have "ShareMode: Read, Write", which means, "I, logreader, permit others, including logwriter, to read and write to the log file".
Those are the most sensible values, I think, and they will prevent locking. Other combinations may be permissible. There is a table here.
Now, you haven't said what happens when it "does not seem to work in all cases". What to do next will really depend on the details. Hopefully the above will give you enough information to work out what is going wrong.
You won't get a lock conflict because the writing application is very unlikely to have locked the file. Doing what you suggest generally works without problems (it's what the UNIX tail -f command does) and those minor glitches that do occur can be ignored. I've written a couple of log monitoring apps in te past that worked like this, with no problems.
Try using FileSystemWatcher to get events when a file is updated.
A more delphi friendly link
Quite apart from getting the file sharing to work right which may be impossible depending on what the other program requests, some programs will close the file between accesses.
I have had success in the past with my program waiting for the file to become available, then quickly opening it, grabbing the needed data and closing it. At least in DOS an attempt to access a locked file caused a few retries, and I bumped up this setting, so that if the other program tried for the file while I had it they would simply be delayed and never see an error.
I was even able to update the file (I made sure NOT to close it in between!) without the other program ever knowing a thing.
Ugly as sin but we couldn't change the other program so it was the only way to get the job done. It was deployed in-house for years, I never heard a peep from the users of that system. It finally went away when the machinery the other program controlled was retired.
XpoLog will do the trick without changing your env or code, XpoLog log monitor
Avar is right - you are at the mercy of the writing program here. If they are locking the file, then there are a couple of things you can do:
1 - Check for a change in the "last modified" date time - if that changes, then you know something has happened.
2 - If the mod datetime did change, then (depending on the size of the file) it might be good enough to create a copy of the file and check that.
we use "Tail for win32",
i know its not delphi but it might be useful
http://tailforwin32.sourceforge.net/