In Python, I can insert a breakpoint() keyword on any line of code, and when I run the script from the command-line, it will stop when it reaches that line, and I'll have an opportunity to interact with or access any previously-defined variables.
I was looking for a way to do this in the Dart language but so far without success.
I've seen references to the debugger keyword provided by the dart:developer library, but instead of allowing me to interact, the script just hangs:
// bin/my_script.dart
import "dart:developer"; // source of debugger();
main() {
var x = 5;
print("X: ${x}"); //> X: 5
debugger(); // ... just hangs
print("END");
}
I've also seen references to the console package, but I'm not seeing it do anything:
// bin/my_script.dart
import "package:console/console.dart"; // source of Console.init()
main() {
var x = 5;
print("X: ${x}"); //> X: 5
Console.init(); // ... nothing happens
print("END");
}
FYI: I'm running this script via dart bin/my_script.dart, and a command-line solution would be ideal, but a solution using the VS Code text editor would also be sufficient.
You can't debug without a debugger attached, that's why running from the command line will hang in the breakpoint, since you can step on the next instruction.
If you use VS Code or Intellij and use the debugger() while in debug mode Shift+Cmd+R, it will trigger a breakpoint there and you can analyze your variables and step forward to the next instructions.
Related
I am new to OpenUI5/QUnit testing. Sorry for the newbie question.
I have added a very basic async QUnit test into my OpenUI5 project:
QUnit.test( "Test async", function( assert ) {
var done = assert.async();
setTimeout(function() {
assert.ok(true);
done();
});
});
This test passes without errors as expected.
Then I have commented out everything except for
var done = assert.async();
The test runs indefinitely without failing. I would expect that it fails after some timeout.
Pressing the "Abort" button just changes the label to "Aborting" but does not fail the test.
I have search the QUnit documentation, that suggest adding
assert.timeout( 1000 ); // Timeout of 1 second
that should be an equivalent to global setting
QUnit.config.testTimeout( 1000 );
But using either crash my test with
assert.timeout is not a function
or
QUnit.config.testTimeout is not a function
I have tried running the test in Chrome, Firefox and IE11 with the same results.
Can anyone tell me what I am doing wrong?
I have found the answer myself. The correct syntax is:
QUnit.config.testTimeout = 1000;
It is then valid for all the subsequent tests. Alternatively I can write
assert.timeout(1000);
at the beginning of the test method - must be before assert.async()
I'm currently trying to write an VS Code extension and it's a bit frustrating. I did everything as said here:
https://code.visualstudio.com/docs/extensions/example-hello-world
But after using yo code and entering all necessary information, I opened the respective folder VS Code hit F5 and VS Code says I should configure my launch.json (this should be done by yo code, shouldn't it?). However, when I press the debug start button, a extension-host window opens as described in that tutorial. BUT: When I try to execute the extension the command palette won't find it.
I tried several command names such as "hello world" "helloworld" or variants of the name of the extension that I gave in yo code. I also noticed the
"commands": [{
"command":"extension.sayHello",
"title":"Hello World"
}]
section of the package.json, but somehow I don't manage it to put it all together in order to get a simple, working vs code extension. In tutorial videos on youtube everyone can simply hit F5 after launching VS Code, what I cannot. Pretty weird somehow.
Any help is appreciated!
Thanks in advance.
EDIT: Additional information.
When I activated vs code to show all exceptions (even handled) vs code stops at the following point (see default:)
at internal/process/stdio.js (core module)
// ...
case 'PIPE':
case 'TCP':
var net = require('net');
stream = new net.Socket({
fd: fd,
readable: false,
writable: true
});
stream._type = 'pipe';
break;
default:
// VS CODE STOPS AT THE LINE FOLLOWING!
// Probably an error on in uv_guess_handle()
throw new Error('Implement me. Unknown stream file type!');
}
// Ignore stream errors.stream.on('error', function() {});
} catch (error) {
stream = createDevNull();
}
//...
Hopefully it helps :(
I solved my problem by reading the tutorial with more attention. The tutorial tells you to activate the command palette by Hitting F1 not CTRL P. This solved my Problem.
I did not change anything in the code; rather it seems to be important to hit F1 instad of [CTRL] + [P] despite it actually brings up the same input. I'm still wondering why to differenciate between CTRL + P and F1 if both bring up the same control. :/
Hope it helps other beginners, too.
cheers!
I had the same issue (though didn't debug to see if it failed on the same line) and I resolved it by restarting VSCode.
I have an All Exceptions breakpoint configured in Xcode:
Sometimes Xcode will stop on a line like:
[managedObjectContext save:&error];
with the following backtrace:
but the program continues on as if nothing happened if you click Continue.
How can I ignore these "normal" exceptions, but still have the debugger stop on exceptions in my own code?
(I understand that this happens because Core Data internally throws and catches exceptions, and that Xcode is simply honoring my request to pause the program whenever an exception is thrown. However, I want to ignore these so I can get back to debugging my own code!)
Moderators: this is similar to "Xcode 4 exception breakpoint filtering", but I think that question takes too long to get around to the point and doesn't have any useful answers. Can they be linked?
For Core Data exceptions, what I typically do is remove the "All Exceptions" breakpoint from Xcode and instead:
Add a Symbolic Breakpoint on objc_exception_throw
Set a Condition on the Breakpoint to (BOOL)(! (BOOL)[[(NSException *)$x0 className] hasPrefix:#"_NSCoreData"])
The configured breakpoint should look something like this:
This will ignore any private Core Data exceptions (as determined by the class name being prefixed by _NSCoreData) that are used for control flow. Note that the appropriate register is going to be dependent on the target device / simulator that you are running in. Take a look at this table for reference.
Note that this technique can be adapted easily to other conditionals. The tricky part was in crafting the BOOL and NSException casts to get lldb happy with the condition.
I wrote an lldb script that lets you selectively ignore Objective-C exceptions with a much simpler syntax, and it handles both OS X, iOS Simulator, and both 32bit and 64bit ARM.
Installation
Put this script in ~/Library/lldb/ignore_specified_objc_exceptions.py or somewhere useful.
import lldb
import re
import shlex
# This script allows Xcode to selectively ignore Obj-C exceptions
# based on any selector on the NSException instance
def getRegister(target):
if target.triple.startswith('x86_64'):
return "rdi"
elif target.triple.startswith('i386'):
return "eax"
elif target.triple.startswith('arm64'):
return "x0"
else:
return "r0"
def callMethodOnException(frame, register, method):
return frame.EvaluateExpression("(NSString *)[(NSException *)${0} {1}]".format(register, method)).GetObjectDescription()
def filterException(debugger, user_input, result, unused):
target = debugger.GetSelectedTarget()
frame = target.GetProcess().GetSelectedThread().GetFrameAtIndex(0)
if frame.symbol.name != 'objc_exception_throw':
# We can't handle anything except objc_exception_throw
return None
filters = shlex.split(user_input)
register = getRegister(target)
for filter in filters:
method, regexp_str = filter.split(":", 1)
value = callMethodOnException(frame, register, method)
if value is None:
output = "Unable to grab exception from register {0} with method {1}; skipping...".format(register, method)
result.PutCString(output)
result.flush()
continue
regexp = re.compile(regexp_str)
if regexp.match(value):
output = "Skipping exception because exception's {0} ({1}) matches {2}".format(method, value, regexp_str)
result.PutCString(output)
result.flush()
# If we tell the debugger to continue before this script finishes,
# Xcode gets into a weird state where it won't refuse to quit LLDB,
# so we set async so the script terminates and hands control back to Xcode
debugger.SetAsync(True)
debugger.HandleCommand("continue")
return None
return None
def __lldb_init_module(debugger, unused):
debugger.HandleCommand('command script add --function ignore_specified_objc_exceptions.filterException ignore_specified_objc_exceptions')
Add the following to ~/.lldbinit:
command script import ~/Library/lldb/ignore_specified_objc_exceptions.py
replacing ~/Library/lldb/ignore_specified_objc_exceptions.py with the correct path if you saved it somewhere else.
Usage
In Xcode, add a breakpoint to catch all Objective-C exceptions
Edit the breakpoint and add a Debugger Command with the following command:
ignore_specified_objc_exceptions name:NSAccessibilityException className:NSSomeException
This will ignore exceptions where NSException -name matches NSAccessibilityException OR -className matches NSSomeException
It should look something like this:
In your case, you would use ignore_specified_objc_exceptions className:_NSCoreData
See http://chen.do/blog/2013/09/30/selectively-ignoring-objective-c-exceptions-in-xcode/ for the script and more details.
Here is an alternative quick answer for when you have a block of code e.g. a 3rd part library that throws multiple exceptions that you want to ignore:
Set two breakpoints, one before and one after the exception throwing block of code you want to ignore.
Run the program, until it stops at an exception, and type 'breakpoint list' into the debugger console, and find the number of the 'all exceptions' break point, it should look like this:
2: names = {'objc_exception_throw', '__cxa_throw'}, locations = 2
Options: disabled
2.1: where = libobjc.A.dylibobjc_exception_throw, address = 0x00007fff8f8da6b3, unresolved, hit count = 0
2.2: where = libc++abi.dylib__cxa_throw, address = 0x00007fff8d19fab7, unresolved, hit count = 0
This means it is breakpoint 2. Now in xcode, edit the first breakpoint (before the exception throwing code) and change the action to 'debugger command' and type in 'breakpoint disable 2' (and set 'automatically continue...' checkbox ).
Do the same for the break point after the offending line and have the command 'breakpoint enable 2'.
The all breakpoints exception will now turn on and off so it's only active when you need it.
I am trying to call an existing VFP 6 application using Jacob which is a COM bridge for Java.
val vfp = new Application(new ActiveXComponent("VisualFoxPro.Application").getProperty("Application").toDispatch())
vfp.setVisible(false)
try {
vfp.doCmd("do my.exe with myconfig.txt")
} catch {
case t: Throwable => t.printStackTrace
} finally {
vfp.doCmd("close data")
vfp.doCmd("clear all")
vfp.doCmd("clear")
vfp.quit
vfp.safeRelease
}
When there are no error conditions this code executes well and generates the expected .dbfs. The problem is that when an error occurs (.dbf not found, file in use by another user, etc) a GUI window pops up and stops execution of the program until I use the mouse to cancel it. I want this program to run on a server with no user interaction so this won't work.
How can I gracefully handle the errors preferably without making a change to the VFP 6 program?
Since you have the source code for VFP6, I would suggest looking into
SYS(2335,0)
Sys 2335 is used to identify if the program is running in an "unattended" mode, any such popup dialog boxes will throw an error and prevent an actual "hit" ok/cancel/whatever button to continue. This includes popup window prompting user to pick a table.
I'm not positive of when it was made available as I had limited use of it. Like you, when dealing with a COM server under IIS and obviously nobody there to respond.
Start JVM in headless mode, catch HeadlessException or something. Or, write a Java program that will execute your GUI program using Runtime, and restart in a case of parsed errors in console.
I'm writing an application that can be started either as a standard WinForms app or in unattended mode from the command-line. The application was built using the VS 2k5 standard WinForms template.
When the application is executed from the command-line, I want it to output information that can be captured by the script executing the application. When I do this directly from Console.WriteLine(), the output does not appear, although it can be captured by piping to a file.
On the other hand, I can force the application to pop up a second console by doing a P/Invoke on AllocConsole() from kernel32. This is not what I want, though. I want the output to appear in the same window the application was called from.
This is the salient code that allows me to pop up a console from the command line:
<STAThread()> Public Shared Sub Main()
If My.Application.CommandLineArgs.Count = 0 Then
Dim frm As New ISECMMParamUtilForm()
frm.ShowDialog()
Else
Try
ConsoleControl.AllocConsole()
Dim exMan As New UnattendedExecutionManager(ConvertArgs())
IsInConsoleMode = True
OutputMessage("Application started.")
If Not exMan.SetSettings() Then
OutputMessage("Execution failed.")
End If
Catch ex As Exception
Console.WriteLine(ex.ToString())
Finally
ConsoleControl.FreeConsole()
End Try
End If
End Sub
Public Shared Sub OutputMessage(ByVal msg As String, Optional ByVal isError As Boolean = False)
Trace.WriteLine(msg)
If IsInConsoleMode Then
Console.WriteLine(msg)
End If
If isError Then
EventLog.WriteEntry("ISE CMM Param Util", msg, EventLogEntryType.Error)
Else
EventLog.WriteEntry("ISE CMM Param Util", msg, EventLogEntryType.Information)
End If
End Sub
Raymond Chen recently posted (a month after the question was posted here on SO) a short article about this:
How do I write a program that can be run either as a console or a GUI application?
You can't, but you can try to fake it.
Each PE application contains a field
in its header that specifies which
subsystem it was designed to run
under. You can say
IMAGE_SUBSYSTEM_WINDOWS_GUI to mark
yourself as a Windows GUI application,
or you can say
IMAGE_SUBSYSTEM_WINDOWS_CUI to say
that you are a console application. If
you are GUI application, then the
program will run without a console.
The subsystem determines how the
kernel prepares the execution
environment for the program. If the
program is marked as running in the
console subsystem, then the kernel
will connect the program's console to
the console of its parent, creating a
new console if the parent doesn't have
a console. (This is an incomplete
description, but the details aren't
relevant to the discussion.) On the
other hand, if the program is marked
as running as a GUI application, then
the kernel will run the program
without any console at all.
In that article he points to another by Junfeng Zhang that discusses how a couple of programs (Visual Studio and ildasm) implement this behavior:
How to make an application as both GUI and Console application?
In VisualStudio case, there are actually two binaries: devenv.com and devenv.exe. Devenv.com is a Console app. Devenv.exe is a GUI app. When you type devenv, because of the Win32 probing rule, devenv.com is executed. If there is no input, devenv.com launches devenv.exe, and exits itself. If there are inputs, devenv.com handles them as normal Console app.
In ildasm case, there is only one binary: ildasm.exe. It is first compiled as a GUI application. Later editbin.exe is used to mark it as console subsystem. In its main method it determines if it needs to be run as console mode or GUI mode. If need to run as GUI mode, it relaunches itself as a GUI app.
In the comments to Raymond Chen's article, laonianren has this to add to Junfeng Zhang's brief description of how Visual Studio works:
devenv.com is a general purpose console-mode stub application. When it runs it creates three pipes to redirect the console's stdin, stdout and stderr. It then finds its own name (usually devenv.com), replaces the ".com" with ".exe" and launches the new app (i.e. devenv.exe) using the read end of the stdin pipe and the write ends of the stdout and stderr pipes as the standard handles. Then it just sits and waits for devenv.exe to exit and copies data between the console and the pipes.
Thus even though devenv.exe is a gui app it can read and write the "parent" console using its standard handles.
And you could use devenv.com yourself for myapp.exe by renaming it to myapp.com. But you can't in practise because it belongs to MS.
Update 1:
As said in Michael Burr answer, Raymond Chen recently posted a short article about this. I am happy to see that my guess was not totally wrong.
Update 0:
Disclaimer: This "answer" is mostly speculation. I post it only because enough time has passed to establish that not many people have the answer to what look like a fundamental question.
I think that the "decision" if the application is gui or console is made at compile time and not at runtime. So if you compile your application as gui application, even if you don't display the gui, its still a gui application and doesn't have console. If you choose to compile it as console application then at minimum you will have a console windows flashing before moving to gui "mode". And I don't know if it is possible in managed code.
The problem is fundamental, I think, Because a console application has to take "control" of the calling console application. And it has to do so before the code of the child application is running.
If you want to check if your app is started from the command line in .NET, you can use Console.GetCursorPosition().
The reason that this works is that when you start it from the command line, the cursor moves away from the initial point ((0, 0)) because you typed something in the terminal (the name of the app).
You can do this with an equality check (code in C#):
class Program
{
public static void Main
{
if (Console.GetCursorPosition() == (0, 0))
{
//something GUI
}
else
{
//something not GUI
}
}
}
Note: You must set the output type to Console Application as other output types will make Console.GetCursorPosition() throw an exception.