how to find "File name and line number of Exception" in runtime - delphi-7

is there any component in Delphi7 to show more information about an exception in runtime like:
exception message and class
".pas" file name
line number of exception
This information is very important when running the application on customer site.

The Delphi 7 compiler does not include the filename or line number in the DCU. (Later versions make the filename available through RTTI, but it's not present in D7.)
You could use an exception handling package such as MadExcept (free for non-commercial use, and reasonably priced for a commercial version), EurekaLog (commercial, but I have no info on cost), or the JEDI JclDebug unit (Open Source), which can use the debugging information and information from a linker map file to provide a stack trace from the exception back. That stack trace includes the unit and line number (as well as the method or procedure name) where the exception occurred.

Related

Change "app name" when connecting to IBM MQ?

I'm working on an application that connects to IBM MQ 8.0 using the C API, calling the MQCONNX function. I run several instances of this application at the same time, and when I open MQ Explorer to list application connections for the queue manager, I see an entry for each connection. However, the entries all have the same "app name" (the name of the executable), making it difficult to distinguish which instances are or are not connected.
Is it possible to change the value that ends up being displayed as the "app name" in MQ Explorer? I'd like to pass an instance identifier from my application, but looking through the documentation for MQCONNX none of the options seem to apply.
In the IBM MQ v8.0 Knowledge Center page "DISPLAY CONN" under APPLTAG it shows how MQ determines the value. You did not state what OS your client app is running on, the information for Unix and Windows is:
UNIX process
Note
On HP-UX if the process name exceeds 14 characters, only the first 14 characters are shown.
On Linux and Solaris, if the process name exceeds 15 characters, only the first 15 characters are shown.
On AIX®, if the process name exceeds 28 characters, only the first 28 characters are shown.
Windows process
Note
This consists of the full program path and executable file name. If it is more than 28 characters long, only the last 28 characters are shown.
As mentioned by #Attila Repasi you can change the ApplName in the MQMD of each message using Set All Context, this does not impact the "app name" displayed in MQ Explorer.
One work around I thought of if you are running on Unix is to create separate symlinks to your program each with different names. If you then run each copy using the different symlink names, this should then reflect as the "app name" displayed by MQ Explorer.
A second work around that I tested on Linux that works without the need for symlinks is setting the process name in your program. I first tried to write over the argv[0], but I found while this changes the process name in a ps output it does not change the APPLTAG value that MQ displays. The working way that I found in Linux is below, this must be called prior to MQCONN.
char *process_name = "samplename\0";
prctl(PR_SET_NAME,process_name,NULL,NULL,NULL);
#Fusspawn's answer to "How to name a thread in Linux? [duplicate]" helped with the above syntax.
Note while testing this on Unix operating system MQI clients I found that on Linux and Solaris that the process name is limited to 15 characters by the OS. Only on AIX was RAPPLTAG able to display a full 28 characters. Windows MQI clients are also able to display the full 28 characters. The IBM Knowledge center only says that HP-UX is limited to 14 characters but indicates that on other Unix platforms it is limited to 28 characters, this appears to be incorrect with Linux and Solaris having a 15 character limit.
Helpful answers:
Linux process name size limit: Thread name longer than 15 chars?
Solaris process name size limit: psinfo_t solaris does not contain full process name in its field
UPDATE: The IBM KC page has been updated based on the feedback I provided, it now states the correct process name limits for Linux and Solaris.
In the interest of providing information to people who may be using IBM MQ classes for Java API the "DISPLAY CONN" page in the Knowledge Center does NOT note that a IBM MQ classes for Java API client can set this value. This is noted on IBM MQ Knowledge Center page "Setting up the IBM MQ environment for IBM MQ classes for Java" under Identifying a connection to the queue manager by setting an application name. This has only been available since v7.5.
Application names are limited to 28 characters and longer names are truncated to fit. If an application name is not specified, a default is provided. The default name is based on the invoking (main) class, but if this information is not available, the text WebSphere MQ Client for Java is used.
...
To set an application name in the properties hash table that is passed to the MQQueueManager constructor, add the name to the properties hash table with a key of MQConstants.APPNAME_PROPERTY.
IBM MQ classes for JMS API client can also set this value. This is noted on IBM MQ Knowledge Center page "Properties of IBM MQ classes for JMS objects > APPLICATIONNAME". This has only been available since v7.5.
Applicable Objects
ConnectionFactory, QueueConnectionFactory, TopicConnectionFactory,
XAConnectionFactory, XAQueueConnectionFactory,
XATopicConnectionFactory
JMS administration tool long name: APPLICATIONNAME
JMS administration tool short name: APPNAME
Programmatic access
Setters/getters
MQConnectionFactory.setAppName()
MQConnectionFactory.getAppName()
Values
Any valid string that is no longer than 28 characters. Longer names
are adjusted to fit by removing leading package names, if necessary.
For example, if the invoking class is com.example.MainApp, the full
name is used, but if the invoking class is
com.example.dictionaryAndThesaurus.multilingual.mainApp, the name
multilingual.mainApp is used, because it is the longest combination of
class name and rightmost package name that fits into the available
length.
If the class name itself is more than 28 characters long, it is
truncated to fit. For example,
com.example.mainApplicationForSecondTestCase becomes
mainApplicationForSecondTest.
You can change the application name on messages you send, using the MQOO_SET_ALL_CONTEXT and MQPMO_SET_ALL_CONTEXT options.
But I don't think you can change the application name displayed on the channel status.
However you could run different instances of your application under different OS users. The user name is also displayed among the status information, which could be used for your purpose if you don't override the MCA user id.
(Or you could do something similar by using SSL connections, and using the SSL cert information displayed to distinguish your app instances.)
While I agree with Attila that you "could" use the MQOO_SET_ALL_CONTEXT and MQPMO_SET_ALL_CONTEXT options, I strongly suggest you not do it.
If you do use those options then you need to understand the consequences. The following MQMD fields of each message will be left blank and/or null and it is up to the application to populate them:
AccountingToken
ApplIdentityData
ApplOriginData
PutApplType
PutApplName
PutDate
PutTime
UserIdentifier
So, how much effort are you going to go through to see something in MQ Explorer which is pointless otherwise?
Also, to use those options, the UserId (or group) requires "+set" MQ OAM permission for the queue it is opening.

How to go stack traces from `polyc`?

I am using PolyML compiler 5.6 Release on Mac OS. I'm compiling and running some code which raises an exception (Fail "undefined"). I am expecting my compiled app to exit with a stack trace when the exception is raised; but instead it exits silently.
How can I get PolyML to show stack traces or at least line numbers where the exception is raised?
Running your application under the debugger is the best way to find out where the exception is happening.
If you can't or don't want to use the debugger you can get line number and source file information by adding a handler and using PolyML.Exception.exceptionLocation to get the location from the exception packet. See http://polyml.org/documentation/Reference/PolyMLException.html
In Poly/ML 5.6 you can also use PolyML.exception_trace to get a trace of the calls that led to the exception but that's likely to be removed in the next release,

z/OS ftp: 550 Unable to create data set E043156.UNIX.USERLIB.SOME for STOR command

I'm trying to upload a file from linux to z/OS via ftp (with filezilla). The upload fails with this error:
550-SVC99 RETURN CODE=4 S99INFO=0 S99ERROR=38668 HEX=970C S99ERSN code X'000042CE'.
550 Unable to create data set TESTUSER.UNIX.USERLIB.SOME for STOR command.
Does anyone know how to interpret this message?
SVC99, also known as DYNALLOC, is the dynamic allocation routine on z/OS. Documentation is voluminous, see the IBM Documentation for z/OS and look under z/OS MVS -> z/OS MVS Programming: Authorized Assembler Services -> Dynamic Allocation -> Requesting Dynamic Allocation Functions -> Interpreting Error Reason Codes from DYNALLOC. For z/OS 2.2 that path should take you here.
Meaning: Severe SMS VTOC service error.
Application programmer action:
Check field S99ERSN for a non-zero value. A non-zero value in S99ERSN
is a reason code. See SMS reason code (S99ERSN) for the possible
reason codes. If the system displayed message IKJ56893I, SMS messages
for the error follow IKJ56893I. If the system displayed message
IKJ56894I, no messages were returned. Request the message processing
option of dynamic allocation to obtain related messages and resubmit
the request. Because SMS creates entries in the logrec data set, if
you still cannot obtain messages, locate the logrec data set entry for
the error that corresponds to the reason code. If you need further
assistance contact your system programmer.
Corresponding Messages: IKJ56893I (messages were displayed) or
IKJ56894I (messages not displayed).
Following the link, your S99ERSN code is documented as...
42CE (17102)
Meaning: While trying to define a non-VSAM data set, a catalog error or
exceptional condition caused the allocation attempt to fail.
Application Programmer Action: Examine the return code and reason
code in accompanying message IGD17102I in z/OS MVS System Messages,
Vol 8 (IEF-IGD).
So there should be an accompanying message IGD17102I in the system log with even more information. Looking at the documentation, I'd contact your support staff as this doesn't look like something you can fix yourself.

Oracle OCI function orlon calls SetUnhandledExceptionFilter

I have been working with an old Win32 application that uses OCI (Oracle Call Interface) to connect to an Oracle database. The application calls SetUnhandledExceptionFilter() to catch (among other things) access violations (exception code 0xC0000005).
However, as soon as the application logs on to Oracle using the OCI function orlon() the exception filter already installed gets overridden by the OCI lib which means exceptions are no longer caught by the filter the application originally installed. This has been verified both using a debugger and also by inspecting the function pointer value of the installed exception filter.
Does anybody have an idea why the OCI function orlon() calls SetUnhandledExceptionFilter() and how to disable this behaviour?
It seems that OCI/Oracle installs signal handlers (*nix) and exception filters (Windows) per default to handle incidents of segmentation faults (*nix), access violations (Windows) etc. in order to log diagnostics. The documentation describes where incidents are reported and how to examine them using the Oracle utility adrci.
Setting
DIAG_SIGHANDLER_ENABLED=FALSE
in the configuration file sqlnet.ora disables the OCI signal handler / exception filter and re-enables standard operating system failure processing.
You can also prevent the second call by overrideing "SetUnhandledExceptionFilter". See also:
PreventSetUnhandledExceptionFilter
This will prevent the second call to be installed in the system...

SolrNet in CLR Stored Procedure

Has anyone ever used Solrnet inside CLR Stored Procedures? I would really appreciate pointers to some good tutorials.
One problem I'm facing is that I can't find a way to include the SolrNet library as a reference to the VS (2008) Database (SQL Server) Project.
Update:
So it seems that when you have an SQL Server Project, and you want to add a reference to a library, it has to first exist in SQL Server itself, which makes sense. This is done by creating an assembly in SQL Server from the DLL itself with the following SQL:
CREATE ASSEMBLY SolrNet FROM 'C:\CLR_SP\SolrNet.dll'
WITH PERMISSION_SET = UNSAFE
(Note that UNSAFE might have some repercussions on the security of the database however it is ok for me for now)
However the SolrNet.dll requires other library dependencies such as Castle.Windsor.dll (which in itself requires System.Core.dll) and Ninject.dll. I found the required version of Castle.Windsor.dll (which is 2.5.1.0) and also System.Core.Dll (which was in the .Net folder of Windows), however I cannot find the required version of Ninject.dll (which should be 2.1.0.76). I have attempted to create assembly version 2.2 but, as expected, it did not do the job.
I searched for it on different repositories but could not find it. Does anyone know where I could find this version of DLL?
Update 2:
So after lots of searching over the net, I still didn't manage to find Ninject.dll v2.1.0.76. My next attempt was to use the next version of SolrNet (which is v0.4.0.2002). This version required Ninject.dll v2.2 which I had already found. So my current status is registering all other libraries in SQL Server which are dependencies of SolrNet.dll. I will leave this open to document my process just in case there will be someone having the same problem.
Update 3:
I have managed to register all required libraries (some of which I got from SolrNet source on GitHub). So now, SolrNet is registered as an assembly in SQL Server, and therefore I can reference it from the .NET SQL Server Project (for creating the CLR Stored Procedure). So I have written a very simple CLR SP which connects to SOLR and retrieves a piece of data. Code below:
[Microsoft.SqlServer.Server.SqlProcedure]
public static void PrintToday()
{
SqlPipe p;
p = SqlContext.Pipe;
p.Send("Helloooo");
// Open Solr instance
SolrNet.Startup.Init<ActiveProduct>("http://192.168.2.190:8983/solr");
// Get instance of ActiveProduct
ISolrOperations<ActiveProduct> operations = ActiveProduct.GetActiveProductSolrOperations();
// Prepare QueryOptions. This will be passed as a parameter into the query() method.
SolrNet.Commands.Parameters.QueryOptions qo = new QueryOptions();
qo.Start = 0;
qo.Rows = 20;
// Query Solr
SolrQueryResults<ActiveProduct> results = operations.Query(new SolrQueryByField("SearchDescription", "pants"), qo);
// Read results
String s = "Docs found: " + results.NumFound;
p.Send(s);
}
My next problem is that when I deploy and run the CLR SP, an error is popping stating that Solr is already registered in container. The exact output that I see in SQL Server Management Studio is the following:
Helloooo
Msg 6522, Level 16, State 1, Procedure PrintToday, Line 0
A .NET Framework error occurred during execution of user defined routine or aggregate 'PrintToday':
System.ApplicationException: Key 'SolrNet.Impl.SolrConnection.CLRStoredProcedures2.ActiveProduct.SolrNet.Impl.SolrConnection' already registered in container
System.ApplicationException:
at SolrNet.Utils.Container.Register(String key, Type serviceType, Converter`2 factory)
at SolrNet.Utils.Container.Register[T](String key, Converter`2 factory)
at SolrNet.Startup.Init[T](ISolrConnection connection)
at SolrNet.Startup.Init[T](String serverURL)
at StoredProcedures.PrintToday()
PrintToday is the name of the CLR StoredProcedure
CLRStoredProcedures2 is the name of the .NET SQL Server project and default namespace in VS 2008
ActiveProduct is the name of the document in Solr, and the cs class with Solr annotations
As can be seen from the output, the first Pipe.send("Hellooo") is doing its job therefore the SP works fine until there.
When I searched for the above error, I found out that it will show when one tries to register Solr instance twice in the same application. Now I don't see where I am registering the instance twice. Am I missing something here?
Note that the above cs function worked fine when executed in a cs console application developed on my machine. Another detail which might be important is that the SOLR Server is being hosted on my machine which is on the same network of my SQL Server 2005.
Update 4:
For starters, the error I mentioned above (in update 3) does not fire when the SP is executed the 1st time just after deployment (let's assume that the 1st time works for now since I have another error which I'm currently working on fixing), the error fires when the SP is executed again afterwards. So it seems that whatever SolrNet.Startup.Init<ActiveProduct>("http://192.168.2.190:8983/solr"); is doing (creating some sort of session that has to do with a container I think) when called from the SP it is not releasing the "session" therefore the 2nd time (and each time afterwards) the SP is executed, the error is fired. Is there a way to sort of stop the session or releasing from the container. What I can do as a workaround is to try - catch the SolrNet.Startup.Init part, however this is not clean.
Thanks.
I'll try to summarize the steps / requirements with explanations whenever possible:
For some reason SQL Server seems to trigger the "hidden" dependencies of the merged SolrNet. Usually you can just use the merged SolrNet (which includes all integration modules) and if you ignore the integration classes the dependencies won't trigger. But in this case the unmerged SolrNet is necessary.
SolrNet does HTTP requests to the Solr server, so the DLL must be registered with UNSAFE permissions in SQL-CLR.
SolrNet Initialization (Startup.Init) must happen only once per application, but you don't have a 'root' context in SQL-CLR to place this initialization. A workaround is to use a singleton or a Lazy type. SQL-CLR doesn't run .NET 4 yet, but you can backport the Lazy type or use FSharp.Core.dll's implementation (I blogged about this some time ago)

Resources