Debug DART output not printing - dart

Output display user input integer, instead of Even or Odd
import 'dart:io';
void main() {
print('Enter your number: ');
int n = int.parse(stdin.readLineSync()!);
var result = n % 2 == 0 ? "Even" : "Odd";
print('Your number is : $result');
}

The problem is that your program is running inside the "Debug Console" in VS Code. The following explanation can be found in the Dart settings in VS Code:
The Debug Console has more functionality because the process is controlled by the debug adapter, but is unable to accept input from the user via stdin.
You can change this by going into File -> Preferences -> Settings. Here you go into Extensions -> Dart & Flutter. If you scroll down you can find "Dart: Cli Console". You can also just search for "Dart Cli console":
Instead of "debugConsole" set this to "terminal". Try start your program again and it should now be running inside the "Terminal" tab instead and you should be able to interact with your program and provide data to it though keyboard inputs.

Related

Running `.dart` files does not show logging messages

I just cannot figure out how to show logging messages when running dart files from terminal.
Example example.dart:
import 'dart:developer';
void main() {
print('print');
log('log');
}
Expected output:
print
log
Actual output:
print
I tried calling dart example.dart, dart run --all example.dart, dart run --verbosity=all example.dart, and different values instead of all (info, ...).
But non of these produced any helpful error messages let alone the out print I expect.
APIs from dart:developer (such as log) are intended to interact with debugging tools:
Interact with developer tools such as the debugger and inspector.
It's not explicit from the documentation for log, but I'd expect it to send a log message only to an attached debugger, not to the console.
If you want logging output that is independent of a debugger, use package:logging and add a listener that calls print, as shown by the example.

where to get the user input in vs code? using dart

I am building a dart program to get the user input. when running the program using the run button I get the output in the output window but I cannot type in it. tried using the terminal to run the program and it worked well. so I want to know what is the right way to take the input from the user?
import 'dart:io';
void main() {
print("enter your name: ");
var name = stdin.readLineSync();
print("hello mrs ${name}");
}
From file -> Preferences -> Settings
search for "Dart: Cli Console"
Dart: Cli Console
Then change the drop-down menu into -terminal-
now you can run again your code and check
you can type in the terminal and your code will work.
In fact the right way using terminal as you did. It's not a fail. It's just how it works.
The answer regarding using the correct vs-code console is correct but you should also check out the dcli package and it's ask function.
Disclaimer: I'm the author of dcli.

Apple unified logging - how to get file name and line number

Apple's Unified Logging documentation states:
Don’t include symbolication information or source file line numbers in messages. The system automatically captures this information.
But in Console I don't see a filename, class name, function name, or line numbers.
How can I have those in my logs?
Indeed, even macOS Catalina beta (build 19A501i) does not show source lines in Console.app.
However, the log command line tool does show source information for simulated devices (macOS 10.14 onwards).
The following command will show log information for all simulated devices currently booted (running) in the simulator. If no simulated devices are currently running the command will fail.
xcrun simctl spawn booted log stream --level debug --color always --source
You can filter out everything which does not come from your program by using a subsystem in os_log calls, and applying a predicate to the streamed logged data. For example, if your subsystem is com.subsystem.my, you can use
xcrun simctl spawn booted log stream --level debug --color always --predicate '(subsystem BEGINSWITH "com.subsystem.my")' --source
The source code information will be shown after the TTL column.
You can also filter by process (i.e. the name of your target), in case you didn't set up a subsystem
xcrun simctl spawn booted log stream --level debug --color always --predicate '(process == "MyProcess")' --source
However, this will normally result in too many log messages since information logged by other frameworks will also be included.
Also, instead of booted, you can use the name of the actual simulated device (to stream log data from that device alone).
os_log doesn't currently give line numbers/function names for Swift code in Console.app, or through the log stream command.
If you really need it - you can use Literal Expressions to pass the information manually via NSLog or os_log like this:
os_log(.info, "Log message from file: %s, line: %i, column: %i", #file, #line, #column)
It may be tempting to wrap os_log to always include this information, but Apple suggests not doing so for performance reasons.
Till apple fixes this issue,
I've created a simple extension
import os
extension Logger {
init(subsystem: String = Bundle.main.bundleIdentifier ?? "", file: String = #file, function: String = #function, line: Int = #line, context: String) {
let category = "\(file):\(line):\(function), \(context)"
self.init(subsystem: subsystem, category: category )
}
}
Usages:
Logger(context: "LoginFLow").debug("Hello World")
We can even remove param name to make it more cleaner:
import os
extension Logger {
init(subsystem: String = Bundle.main.bundleIdentifier ?? "", file: String = #file, function: String = #function, line: Int = #line, _ context: String) {
let category = "\(file):\(line):\(function), \(context)"
self.init(subsystem: subsystem, category: category )
}
}
Usages:
Logger("LoginFLow").debug("Hello World")
Note: If you wish to use the original Logger, just remove the context param and it will use its original init provided by apple.
Logger().debug("Hello World")

Move execution point in Xcode/lldb

Is there a way to set the execution point while debugging Xcode/lldb? To be more specific, after hitting a breakpoint, moving the execution point manually to another line of code?
If you're looking at moving it up or down with in a method you can click and drag the green arrow to a specific point. so if you want to back up a line before the breakpoint. click on the green arrow that is produced and drag it up. If you hit run you'll hit your breakpoint again
In Xcode 6, you can use j lineNumber - see documentation below:
(lldb) help j
Sets the program counter to a new address. This command takes 'raw' input
(no need to quote stuff).
Syntax: _regexp-jump [<line>]
_regexp-jump [<+-lineoffset>]
_regexp-jump [<file>:<line>]
_regexp-jump [*<addr>]
'j' is an abbreviation for '_regexp-jump'
One of the great things about lldb is that it's easy to extend it with a little bit of python scripting. For instance, I threw together a new jump command without much trouble:
import lldb
def jump(debugger, command, result, dict):
"""Usage: jump LINE-NUMBER
Jump to a specific source line of the current frame.
Finds the first code address for a given source line, sets the pc to that value.
Jumping across any allocation/deallocation boundaries (may not be obvious with ARC!), or with optimized code, quickly leads to undefined/crashy behavior. """
if lldb.frame and len(command) >= 1:
line_num = int(command)
context = lldb.frame.GetSymbolContext (lldb.eSymbolContextEverything)
if context and context.GetCompileUnit():
compile_unit = context.GetCompileUnit()
line_index = compile_unit.FindLineEntryIndex (0, line_num, compile_unit.GetFileSpec(), False)
target_line = compile_unit.GetLineEntryAtIndex (line_index)
if target_line and target_line.GetStartAddress().IsValid():
addr = target_line.GetStartAddress().GetLoadAddress (lldb.target)
if addr != lldb.LLDB_INVALID_ADDRESS:
if lldb.frame.SetPC (addr):
print "PC has been set to 0x%x for %s:%d" % (addr, target_line.GetFileSpec().GetFilename(), target_line.GetLine())
def __lldb_init_module (debugger, dict):
debugger.HandleCommand('command script add -f %s.jump jump' % __name__)
I put this in a directory where I keep Python commands for lldb, ~/lldb/, and I load it in my ~/.lldbinit file with
command script import ~/lldb/jump.py
and now I have a command jump (j works) which will jump to a given line number. e.g.
(lldb) j 5
PC has been set to 0x100000f0f for a.c:5
(lldb)
This new jump command will be available both in command-line lldb and in Xcode if you load it in your ~/.lldbinit file -- you'll need to use the debugger console pane in Xcode to move the pc instead of moving the indicator in the editor window.
You can move the program counter (pc) in lldb using the lldb command register write pc. But it's instruction based.
There's an excellent lldb/gdb comparison here that is useful as an lldb overview.

Help embedding FSI

Starting here - Embedding F# interactive - I've been trying to embed FSI in my application.
However, I'm getting weird stuff back from StandardOutput.
for example, in standard FSI, if I send this:
let a = 3;;
I get this back:
[empty line here]
val a : int = 3
[empty line here]
> |
(with Pipe representing the input position)
But if I send let a = 3;; to StandardInput, I get this back on StandardOutput:
>
val a : int = 3
|
Has anyone else tried this? Is there something I'm doing wrong, and if not is there any way to work around this? None of the things I've tried so far work, and before I try the 'worse' thing I can think of (set a timer after sending stuff, add the > myself on timeout), I'd like to know if there is a better way!
When embedding F# Interactive, Visual Studio uses the --fsi-server:<some value> parameter.
As far as I know, this does two things:
Changes the way output is printed (instead of printing >, it prints SERVER-PROMPT> on a separate line, so it should be easier to remove it from the output and detect state when input is expected)
It also starts some .NET Remoting channel that you can use to stop execution of commands in F# Interactive (e.g. if it runs into an infinite loop) and it can also provide some completion information.
The F# Interactive pad in MonoDevelop F# plugin uses the flag (see source code on GitHub). I think it works mostly right, but I believe it sometimes prints additional \n in the output.

Resources