Try-catch problem in Embarcadero C++ 10.1 x64 - dom

I have a problem executing 64-bit version of my program:
_XMLDoc = new TBasicXML(_owner);
try {
_XMLDoc->LoadFromFile(_filePath);
}
catch (...) {
delete _XMLDoc;
return "?";
}
In 32-bit version, when _filePath does not exist, program goes into catch block,
but in 64-bit version it does not.
Actually, it throws EDOMParseError several times and it enters catch block after I press continue for each error dialog.
TBasicXML class constructor is:
__fastcall TBasicXML::TBasicXML(TComponent *Owner, UnicodeString encoding)
{
_doc = new TXMLDocument(Owner);
_doc->Active = true;
_doc->Encoding = encoding;
_doc->Options = TXMLDocOptions()<<doNodeAutoIndent;
}
Is there something specifically I need to specify in project options for Win 64 target that defers from 32-bit target, to avoid such behavior?
Edit: I was focused on this part of code (parser), because it's executed at the program start. However, I've added this peace of code in my main form's constructor, before parser call:
int x;
try {
x = StrToInt("not a number");
}
catch (...) {
MessageDlg("Exception catched!", mtInformation, TMsgDlgButtons() << mbOK, 0);
}
I've built 64-bit release version and started the program (Run without debugger). It simply aborts without any message. When the same program (release) is started with debugger (Run (F9)) it shows error message dialog (EConverterError) and then after continue is pressed it shows my MessageDlg.
Note: with 32-bit version, there is no problem at all.
Edit2: I've test some other projects, the same situation:
__fastcall TfrmMain::TfrmMain(TComponent* Owner)
: TForm(Owner)
{
// test
int x;
try {
x = StrToInt("not a number");
}
catch (...) {
MessageDlg("Exception catched!", mtInformation, TMsgDlgButtons() << mbOK, 0);
}
//Ie settings
IEGlobalSettings()->AutoFragmentBitmap = false;
IEGlobalSettings()->MsgLanguage = msEnglish;
IEGlobalSettings()->EnableTheming = true;
// initialize spengine
speInit(); // delayed DLL load
FLeftId = 0;
FRightId = 0;
}
Again, 64-bit release version, when started from IDE, without debugger, silently terminates program, when started with debugger, works normally.
Edit3: Now, here is a mystery?
From the example above, I've excluded DLL library (spEngine.a) from build and commented all code related to DLL entry calls and try-catch block works as usual. When spEngine.a is included, no matter if DLL loading (spEngine.dll) is delayed or not and without any call to DLL entries, try-catch block woks as previously described. Very strange. spEngine.dll calls custom Intel's ipp DLL build with MVSC2017. The similar try-catch behavior I have experienced with another library that calls OpenCV DLLs (wrapper built with MSVC2017). The complete source code is here: https://github.com/spetric/Lips
Note: 64-bit host application works well, no problems with functionality, only with strange try-catch block behavior.

Related

Named pipe is connected while checking if it exists from Java

I am using Lukas Thomsen's named pipe example to create a pipe server in C++ and a reader in Java.
On the Java side I want to wait until the Named Pipe is created by C++ server.
File file = new File("\\\\.\\pipe\\Pipe");
while(!file.exists());
InputStream input = new FileInputStream(file);
However, the file.exists() somehow connects the named pipe and instantiating FileInputStream throws following exception:
java.io.FileNotFoundException: \\.\pipe\Pipe (All pipe instances are busy)
at java.io.FileInputStream.open0(Native Method)
at java.io.FileInputStream.open(Unknown Source)
at java.io.FileInputStream.<init>(Unknown Source)
Here is the snippet of c++ server:
int main(void)
{
HANDLE hPipe;
char buffer[1024];
DWORD dwRead;
hPipe = CreateNamedPipe(TEXT("\\\\.\\pipe\\Pipe"),
PIPE_ACCESS_DUPLEX | PIPE_TYPE_BYTE | PIPE_READMODE_BYTE, // FILE_FLAG_FIRST_PIPE_INSTANCE is not needed but forces CreateNamedPipe(..) to fail if the pipe already exists...
PIPE_WAIT,
1,
1024 * 16,
1024 * 16,
NMPWAIT_USE_DEFAULT_WAIT,
NULL);
while (hPipe != INVALID_HANDLE_VALUE)
{
if (ConnectNamedPipe(hPipe, NULL) != FALSE) // wait for someone to connect to the pipe
{
cout<<"connected";
//do amazing stuff after being connected.
}
DisconnectNamedPipe(hPipe);
}
return 0;
}
So what it the proper way to wait for named pipe in Java without throwing this error?
The reason this problem occurs is that File.exists() on Windows is implemented using a sequence of native function calls to CreateFile, GetFileInformationByHandle and CloseHandle. See the getFileInformation function in the Java source code. From a named pipe perspective this is bad because on Windows named pipes have to be reset between uses and the CreateFile call in that native function counts as a use.
The solution is to ask forgiveness rather than permission when opening the named pipe on the Java side. Something along the lines of:
File file = new File("\\\\.\\pipe\\Pipe");
while (true) {
try {
return new FileInputStream(file);
} catch (IOException e) {
Thread.sleep(20);
}
}
(Obviously you might not want to loop forever in practice, but the code in the question did.)

Collecting handles with Windbg

I'm using Windbg sdk to write my own debugger. The debugger is capable of collecting all handles allocated by debugged apps to avoid handle leaks. Here is my code:
void zAdvancedDebugger::debugProc(){
// Creating interfaces including m_dbgClient, m_dbgControl
if(!createInterfaces()){
printf("Failed to create debugging interfaces\r\n");
return;
}
std::string strRealCmdLine="\"" + app + "\" " + args;
// Every thing's set up so start the app.
if (( m_dbgClient->CreateProcess(0, (PSTR)strRealCmdLine.c_str(), DEBUG_PROCESS )) != S_OK)
return ;
// event loop
while(true){
if(m_dbgControl->WaitForEvent(DEBUG_WAIT_DEFAULT,INFINITE)!= S_OK)
break;
}
HRESULT ret=m_dbgControl->Execute(
DEBUG_OUTCTL_IGNORE,
".closehandle -a", // Close all handles allocated
DEBUG_EXECUTE_NOT_LOGGED );
}
The problem is: I can't execute the command ".closehandle -a". Whenever I run the code, I always get "ret 0x80040205 An unexpected exception was raised". Would you please tell me what wrong is with this?

Eclipse plugin - how to run external class

I want to make a plugin for Eclipse. The thing is that I looked into the API, and examples, and I managed to make a button on main bar, with a specific icon, and when I click it, open up an InputDialog.
The hard part, is that I want to start an aplication from this button, but not with Runtime as it was a new process. I simply want to start a class inside plugin, which will log in to a server and get some output from it. I want it to be opened in a console, like launching a normal application, or a separate console.
The best example of this kind is a Tomcat plugin which starts Tomcat, and then outputs the console to the Eclipse console. I want to do that too. I've looked at the Tomcat source plugin, but I got stuck there too. They use their own launcher.
I am not sure what you mean by "I want to simply start a class". I assume there is a command line tool that you want to execute and redirect its output to the console window.
To be able to do that without spawning a new process, you have to be able to control the output stream of the tool. If it cannot be controlled, then you have no choice but to start a new process to properly capture the tool's output.
It is technically possible to call System.setOut instead, but it will redirect output from all threads to your console which is not what you want.
Nevertheless you start by creating a console:
// function findConsole copied from:
// http://wiki.eclipse.org/FAQ_How_do_I_write_to_the_console_from_a_plug-in%3F
private MessageConsole findConsole(String name) {
ConsolePlugin plugin = ConsolePlugin.getDefault();
IConsoleManager conMan = plugin.getConsoleManager();
IConsole[] existing = conMan.getConsoles();
for (int i = 0; i < existing.length; i++)
if (name.equals(existing[i].getName()))
return (MessageConsole) existing[i];
//No console found, so create a new one.
MessageConsole myConsole = new MessageConsole(name, null);
conMan.addConsoles(new IConsole[]{myConsole});
return myConsole;
}
// Find my console
MessageConsole cons = findConsole("MyTool Console");
MessageConsoleStream out = cons.newMessageStream();
// Optionally get it's input stream so user can interact with my tool
IOConsoleInputStream in = cons.getInputStream();
// Optionally make a differently coloured error stream
MessageConsoleStream err = cons.newMessageStream();
err.setColor(display.getSystemColor(SWT.COLOR_RED));
// Display the console.
// Obtain the active page. See: http://wiki.eclipse.org/FAQ_How_do_I_find_the_active_workbench_page%3F
IWorkbenchPage page = ...;
String id = IConsoleConstants.ID_CONSOLE_VIEW;
IConsoleView view = (IConsoleView) page.showView(id);
view.display(cons);
Then set the input and output streams of my tool and start processing in a different thread so the UI will not block.
// Create my tool and redirect its output
final MyTool myTool = new MyTool();
myTool.setOutputStream(out);
myTool.setErrorStream(err);
myTool.setInputStream(in);
// Start it in another thread
Thread t = new Thread(new Runnable() {
public void run() {
myTool.startExecuting();
}
});
t.start();
If your tool does not support I/O redirection, you have no choice but to start it in another process with the ProcessBuilder and use a number of threads to move data between console and process streams See: Process.getInputStream(), Process.getOutputStream() and Process.getErrorStream().
The following links have additional useful details:
Executing a Java application in a separate process
FAQ How do I write to the console from a plug-in?
FAQ How do I find the active workbench page?
This is the code for running a new console with controls, like stop delete, and deleteAll! This is what I asked for in the beginning, but the message console is good to know!
ILaunchConfigurationType launchType = DebugPlugin.getDefault().getLaunchManager().getLaunchConfigurationType("org.eclipse.jdt.launching.localJavaApplication");
ILaunchConfigurationWorkingCopy config = null;
try {
config = launchType.newInstance(null, "My Plugin working");
} catch (CoreException e) {
System.err.println(e.getMessage());
}
config.setAttribute(ILaunchConfiguration.ATTR_SOURCE_LOCATOR_ID, "org.eclipse.jdt.launching.sourceLocator.JavaSourceLookupDirector");
String[] classpath = new String[] { "C:\\Users\\Administrator\\Documents\\myjr.jar" };
ArrayList classpathMementos = new ArrayList();
for (int i = 0; i < classpath.length; i++) {
IRuntimeClasspathEntry cpEntry = JavaRuntime.newArchiveRuntimeClasspathEntry(new Path(classpath[i]));
cpEntry.setClasspathProperty(IRuntimeClasspathEntry.USER_CLASSES);
try {
classpathMementos.add(cpEntry.getMemento());
} catch (CoreException e) {
System.err.println(e.getMessage());
}
}
config.setAttribute(IJavaLaunchConfigurationConstants.ATTR_DEFAULT_CLASSPATH, false);
config.setAttribute(IJavaLaunchConfigurationConstants.ATTR_CLASSPATH, classpathMementos);
config.setAttribute(IJavaLaunchConfigurationConstants.ATTR_MAIN_TYPE_NAME, "collectorlog.handlers.MyClass");
try {
ILAUNCH = config.launch(ILaunchManager.RUN_MODE, null);
} catch (CoreException e) {
System.err.println(e.getMessage());
}

Eclipse IDE doesnt allow me to give the input while running groovy script

I tried to run the groovy script. But unfortunately the script does not ask me for the input and through null pointer exceptions. Please help me what I need to do for this.
static startShell() {
client = new Client()
// TODO add Windows compatibility check
def historyFile = new File(System.getProperty("user.home"), "kitty.history")
historyFile.createNewFile()
def history = new History(historyFile)
def reader = new ConsoleReader()
reader.setBellEnabled(false)
reader.setUseHistory(true)
reader.setDefaultPrompt(PROMPT)
reader.setHistory(history)
reader.addCompletor(new SimpleCompletor(commands as String[]))
LOOP: while (true) {
def input = reader?.readLine().trim()
if (input.length() == 0)
continue
if (["exit", "quit"].contains(input.tokenize().get(0)))
break LOOP
try {
inputHandler(input)
}
catch (Exception e) {
println e.getMessage()
}
I also tried by replacing the reader? with reader also.
Error:
kitty> Caught: java.lang.NullPointerException: Cannot invoke method trim() on null object
at org.apache.kitty.CmdShell.startShell(CmdShell.groovy:100)
at org.apache.kitty.CmdShell.main(CmdShell.groovy:79)
Please Help
I believe this is related to this question:
java.io.Console support in Eclipse IDE
Essentially, Eclipse does not support Console Reader for running applications - though I'm confused as to how Andrew Eisenberg got a working result in Eclipse if that is the case.
Can you simplify your program into something that I can run? I tried something very simple and I was able to have it run both on the command line and inside Eclipse.
Here's the script I created:
import jline.ConsoleReader
def reader = new ConsoleReader()
LOOP: while (true) {
def input = reader?.readLine().trim()
if (input.length() == 0)
continue
if (["exit", "quit"].contains(input.tokenize().get(0)))
break LOOP
println "You said: " + input
}
Can you try running this and see if this works for you?

How to run ant from an Eclipse plugin, send output to an Eclipse console, and capture the build result (success/failure)?

From within an Eclipse plugin, I'd like to run an Ant build script. I also want to display the Ant output to the user, by displaying it in an Eclipse console. Finally, I also want to wait for the Ant build to be finished, and capture the result: did the build succeed or fail?
I found three ways to run an Ant script from eclipse:
Instantiate an org.eclipse.ant.core.AntRunner, call some setters and call run() or run(IProgressMonitor). The result is either normal termination (indicating success), or a CoreException with an IStatus containing a BuildException (indicating failure), or else something else went wrong. However, I don't see the Ant output anywhere.
Instantiate an org.eclipse.ant.core.AntRunner and call run(Object), passing a String[] containing the command line arguments. The result is either normal termination (indication success), or an InvocationTargetException (indicating failure), or else something else went wrong. The Ant output is sent to Eclipse's stdout, it seems; it is not visible in Eclipse itself.
Call DebugPlugin.getDefault().getLaunchManager(), then on that call getLaunchConfigurationType(IAntLaunchConfigurationConstants.ID_ANT_BUILDER_LAUNCH_CONFIGURATION_TYPE), then on that set attribute "org.eclipse.ui.externaltools.ATTR_LOCATION" to the build file name (and attribute DebugPlugin.ATTR_CAPTURE_OUTPUT to true) and finally call launch(). The Ant output is shown in an Eclipse console, but I have no idea how to capture the build result (success/failure) in my code. Or how to wait for termination of the launch, even.
Is there any way to have both console output and capture the result?
Edit 05/16/2016 #Lii alerted me to the fact that any output between the ILaunchConfigurationWorkingCopy#launch call and when the IStreamListener is appended will be lost. He made a contribution to this answer here.
Original Answer
I realize this is an old post, but I was able to do exactly what you want in one of my plugins. If it doesn't help you at this point, maybe it will help someone else. I originally did this in 3.2, but it has been updated for 3.6 API changes...
// show the console
final IWorkbenchPage activePage = PlatformUI.getWorkbench()
.getActiveWorkbenchWindow()
.getActivePage();
activePage.showView(IConsoleConstants.ID_CONSOLE_VIEW);
// let launch manager handle ant script so output is directed to Console view
final ILaunchManager manager = DebugPlugin.getDefault().getLaunchManager();
ILaunchConfigurationType type = manager.getLaunchConfigurationType(IAntLaunchConstants.ID_ANT_LAUNCH_CONFIGURATION_TYPE);
final ILaunchConfigurationWorkingCopy workingCopy = type.newInstance(null, [*** GIVE YOUR LAUNCHER A NAME ***]);
workingCopy.setAttribute(ILaunchManager.ATTR_PRIVATE, true);
workingCopy.setAttribute(IExternalToolConstants.ATTR_LOCATION, [*** PATH TO ANT SCRIPT HERE ***]);
final ILaunch launch = workingCopy.launch(ILaunchManager.RUN_MODE, null);
// make sure the build doesnt fail
final boolean[] buildSucceeded = new boolean[] { true };
((AntProcess) launch.getProcesses()[0]).getStreamsProxy()
.getErrorStreamMonitor()
.addListener(new IStreamListener() {
#Override
public void streamAppended(String text, IStreamMonitor monitor) {
if (text.indexOf("BUILD FAILED") > -1) {
buildSucceeded[0] = false;
}
}
});
// wait for the launch (ant build) to complete
manager.addLaunchListener(new ILaunchesListener2() {
public void launchesTerminated(ILaunch[] launches) {
boolean patchSuccess = false;
try {
if (!buildSucceeded[0]) {
throw new Exception("Build FAILED!");
}
for (int i = 0; i < launches.length; i++) {
if (launches[i].equals(launch)
&& buildSucceeded[0]
&& !((IProgressMonitor) launches[i].getProcesses()[0]).isCanceled()) {
[*** DO YOUR THING... ***]
break;
}
}
} catch (Exception e) {
[*** DO YOUR THING... ***]
} finally {
// get rid of this listener
manager.removeLaunchListener(this);
[*** DO YOUR THING... ***]
}
}
public void launchesAdded(ILaunch[] launches) {
}
public void launchesChanged(ILaunch[] launches) {
}
public void launchesRemoved(ILaunch[] launches) {
}
});
I'd like to add one thing to happytime harry's answer.
Sometimes the first writes to the stream happens before the stream listener is added. Then streamAppended on the listener is never called for those writes so output is lost.
See for example this bug. I think happytime harry's solution might have this problem. I myself registered my stream listener in ILaunchListener.launchChanged and this happened 4/5 times.
If one wants to be sure to get all the output from a stream then the IStreamMonitor.getContents method can be used to fetch the output that happened before the listener got added.
The following is an attempt on a utility method that handles this. It is based on the code in ProcessConsole.
/**
* Adds listener to monitor, and calls listener with any content monitor already has.
* NOTE: This methods synchronises on monitor while listener is called. Listener may
* not wait on any thread that waits for monitors monitor, what would result in dead-lock.
*/
public static void addAndNotifyStreamListener(IStreamMonitor monitor, IStreamListener listener) {
// Synchronise on monitor to prevent writes to stream while we are adding listener.
// It's weird to synchronise on monitor because that's a shared object, but that's
// what ProcessConsole does.
synchronized (monitor) {
String contents = monitor.getContents();
if (!contents.isEmpty()) {
// Call to unknown code while synchronising on monitor. This is dead-lock prone!
// Listener must not wait for other threads that are waiting in line to
// synchronise on monitor.
listener.streamAppended(contents, monitor);
}
monitor.addListener(listener);
}
}
PS: There is some weird stuff going on in ProcessConsole.java. Why is the content buffering switched of from the ProcessConsole.StreamListener constructor?! If the ProcessConsole.StreamListener runs before this one maybe this solution doesn't work.