Display runtime error message on specific line in Xcode - c++

I would like to display custom error message during runtime in Xcode in C/C++ code. This could be used for example for custom assert() function.
I would like to display message inline, like SenTestingKit does:
Right now the only thing I can do is use __builtin_trap to stop at the correct line. But no custom error message is displayed.

I'm not familiar with xcode but here's how it's done almost everywhere else.
Your custom assert will look like this:
#define MY_ASSERT(a1, a2, desc, ...) {\
PrintAssertMessage(...); \
DebugBreak(); \
}
In windows there's already a DebugBreak function in win32 API.
In Linux and most other systems that run IA32/X64 you can simply call int 3 which is the breakpoint trap.
asm ("int 3");
I read that in xcode it's:
__asm {int 3}
or
__asm__("int $3")
or
__asm__("trap")
In any case this should be surrounded by a macro that disables the assert in debug builds as well macro that defines how to cause a break point.

Related

GCC: How to customising warning and errors generated from compilation

My Usecase:
I have two c language files: ApplicationCode.c and UserCode.c . Application code is something generated by my app and UserCode is available to my application user where he can write his own code.
ApplicationCode.c internally uses UserCode.c and calls out its methods/function.
One thing you can assume here that ApplicationCode.c will never have any errors but could have warnings generated by gcc compiler. And UserCode.c can have both errors and warnings.
So, While compiling code I wanted to show user his code's errors as first priority. If needed to show warning also then show warning generated by his code only not from ApplicationCode.c (As i don't want to expose my ApplicationCode.c's code).
One more constraint is here that I wanted to show return-type warning as error here and for this I am using -Werror=return-type argument.
So, I am thinking of following three approaches to do this:
If I could able to disable all the warnings and enable only -Wreturn-type
Raised a saparate question for this here
If I could able to instruct gcc (or redirect) only error messages to stderr and rest on stdout.
Raised a saparate question for this also here
If I could able to disable all the warnings (which are enabled by default) from ApplicationCode.c file and enable all with -Werror=return-type for UserCode.c
I tried searching everywhere but did not get any solution for all the above 3. Let me know how could I achieve above problems or if there any other better way to do solve my use case ?
Update 1:
Here is my both the code file look like
ApplicationCode.c
#include <stdio.h>
// some headers
// some application specific code
int testUserFunction(); // user function declaration
int main(int argc, char *a[]) {
int result = testUserFunction(); // calling user function
// some logic to use and evaluate result
}
UserCode.c
#include<stdio.h>
int testUserFunction(int input1)
{
// user will write his code below this
// user code
}
Base command to compile code:
gcc -o code.out ApplicationCode.c UserCode.c
or if there any other better way to do solve my use case ?
If you don't want to "expose ApplicationCode.c", then why are you showing its compilation output in the first place? Solution: Compile it in somewhere secret and let the user link their UserCode.c with it.

Is there any way to make Visual Studio C++ error output useful?

I find VS19 output quite useless when working on C++ project. Consider running the example code on freshly installed VS19:
#include <iostream>
using namespace std;
class My
{
public:
void f() noexcept
{
throw exception{"A problem sir!"};
}
};
int main()
{
try
{
My m;
m.f();
}
catch (exception& ex)
{
cout << "exception caught! " << ex.what() << endl;
}
return 0;
}
What I would like to receive is: "Function throws an exception while marked as noexcept", and the cursor set on the problematic line. What I get is a new window with some general text, none of which mentions the problem, or where the problem is.
What compiler warning level have you specified? If I use the /W0 option there is no diagnostic but with any other value, /W1 through /W4, the compiler outputs the following lines:
1>filename.cpp(9,1): warning C4297: 'My::f': function assumed not to throw an exception but does
1>filename.cpp(9,1): message : __declspec(nothrow), throw(), noexcept(true), or noexcept was specified on the function
Note: the diagnostic messages include the line and column numbers. If you double-click the error message it moves the cursor to the offending line.
Your verbosity parameter of MSBuild is may be too high. Go to menu: Tools -> Options. Then on the left pane select: Projects and Solutions -> Build and Run.
There you can select the appropriate verbosity of MSBuild (from Quiet to Diagnostic)
Trying to resolve your puzzle in your question:
What I get is a new window with some general text, none of which
mentions the problem, or where the problem is.
I find 90% of output useless for me.
I think what you mean is the Output window, it is always used to display output about build process.
Also, You can also program your own applications to write diagnostic messages at run time to an Output pane. To do this, use members of the Debug class or Trace class in the System.Diagnostics namespace of the .NET Framework Class Library.
For those large solution or large project, which has plenty of resource files. The build sometimes fail with unknown error. The output window is necessary for trouble-shooting.
If you think most of its info is useless,like P.PICARD suggests: Go Tools=>Projects and Solutions=>Build and Run to set its build output verbosity(!Not build log file verbosity) I suggest you change it to Minimal.
If you have a failed build and want to watch the details of the whole build process. Change it to Detailed and rebuild the project or solution.
What I would like to receive is: "Function throws an exception while
marked as noexcept", and the cursor set on the problematic line.
Have you checked the Error List window? If it disappeared,choose View > Error List, or press Ctrl++E.
Add two lines to your code sample:
int main()
{
int a = 2;
int b;
...
}
Navigate to the Error List window(I suggest you set it as Build and Intellisense):
I think it's what you want. And error list window also indicates the Variable which is not initialized or not referenced for improving your coding.
Also, you can see their line numbers. And Double-click the error message, the cursor will navigate to that line.
For C++ program, the warning level is from w0 to w4, you can set it w4 to get the high warning level.(By default it should be w3)
Right-click project=>properties=>Configuration Properties=>C/C++=>Warning Level to set it. (Have been described by Blastfurance, thanks to him!)
Change it to w0, nothing shows. Change it to w3, and it will show warnings about My::f and b but not a.(Actually I don't think you make changes to that, because w3 is by default) Change it to w4 then get the high warning level and all associated warnings display.

Refactor MFC message maps to include fully qualified member function pointers

I have a codebase where MFC message maps are written in this form:
BEGIN_MESSAGE_MAP(SomeForm, BaseForm)
ON_COMMAND(CID_ButtonAction, OnButtonAction)
END_MESSAGE_MAP()
This compiles just fine in MSVC. When I want to compile the same code in Clang I get a call to non-static member function without an object argument error because OnButtonAction is not a correct form for specifying a member function pointer. The code can be easily fixed:
ON_COMMAND(CID_ButtonAction, &SomeForm::OnButtonAction)
or we can use ThisClass typedef from the BEGIN_MESSAGE_MAP() macro:
ON_COMMAND(CID_ButtonAction, &ThisClass::OnButtonAction)
So far so good...the only problem is that I have hundreds of these message map entries in a lot of separate files. Is there any tool that can fix this? Some obscure Visual Studio magic? Or is it possible to use replacement via regex here?
In the end I came up with a sed command that I ran from MinGW:
sed -b -i -re '/^BEGIN_MESSAGE_MAP/,/^END_MESSAGE_MAP/{/(BEGIN_MESSAGE_MAP|\/\/)/!s/(.*),\s{0,}/\1, \&ThisClass::/;}' *.cpp
To explain what it does:
-b treat files as binary (optional, to keep line endings in Windows)*
-re support extended regular expressions
-i in-place substitution
/^BEGIN_MESSAGE_MAP/,/^END_MESSAGE_MAP/ match only text between these two strings
/!s substitution command that will ignore whatever you match before it
/\(BEGIN_MESSAGE_MAP\|\/\/\)/ matches line beginnings to ignore (either the first line of the message map or commented-out lines)
/(.*),\s{0,}/\1, \&ThisClass::/ substitutes the last comma on a line followed by 0+ whitespaces with , &ThisClass::
Sample input:
BEGIN_MESSAGE_MAP(SomeForm, BaseForm)
ON_COMMAND(CID_ButtonAction, OnButtonAction)
ON_NOTIFY_EX(CID_Notify, 0, OnNotify)
END_MESSAGE_MAP()
Output:
BEGIN_MESSAGE_MAP(SomeForm, BaseForm)
ON_COMMAND(CID_ButtonAction, &ThisClass::OnButtonAction)
ON_NOTIFY_EX(CID_Notify, 0, &ThisClass::OnNotify)
END_MESSAGE_MAP()
This worked nicely, for ~500 files I only had to make two manual adjustments where the class method membership notation was already used. The sed command could be adjusted to account for this (e.g. check if the last comma on the line was followed by &) but this was just good enough for my purposes.
EDIT - added -b option. This treats the files as binary. On Windows this prevents replacing original newline characters by Unix ones - without this option enabled the git diff for any processed file will look like the whole file has been deleted and added again.
The error message is a bit strange and I suppose it has to do with a difference between Visual Studio and CLANG so far as processing the source.
The compiler I have handy is Visual Studio 2005 and I have an MFC application I am working on so the MFC source for Visual Studio 2005 is handy. I took a quick look at Visual Studio 2015 with the same solution and it appears the MFC header files are similar. So I am going to base this on Visual Studio 2005 MFC.
The ON_COMMAND() macro located in afxmsg_.h is defined as the following:
#define ON_COMMAND(id, memberFxn) \
{ WM_COMMAND, CN_COMMAND, (WORD)id, (WORD)id, AfxSigCmd_v, \
static_cast<AFX_PMSG> (memberFxn) },
// ON_COMMAND(id, OnBar) is the same as
// ON_CONTROL(0, id, OnBar) or ON_BN_CLICKED(0, id, OnBar)
And AFX_PMSG is defined in the file afxwin.h as:
// pointer to afx_msg member function
#ifndef AFX_MSG_CALL
#define AFX_MSG_CALL
#endif
typedef void (AFX_MSG_CALL CCmdTarget::*AFX_PMSG)(void);
The class CCmdTarget is a base class from which is derived other classes such as CWnd and CWinThreadand other MFC classes that use a message map.
So the ON_COMMAND() macro is using static_cast<> to what should be a base class of the window or thread target. Perhaps someone else, more knowledgable can provide an actual explanation as to what the compiler is doing and how the C++ language specification would treat this construct.
However on a more practical note, what I suggest is that you write your own version of the ON_COMMAND() macro and insert this version in the StdAfx.h file that is in each project of your solution. I picked the StdAfx.h file since there is only one per project and it is a central point where a single modification can affect multiple compile units.
At the bottom of the file after all the various includes and before the #endif that closes the test for the header file already included, add the following lines of source.
#undef ON_COMMAND
#define ON_COMMAND(id, memberFxn) \
{ WM_COMMAND, CN_COMMAND, (WORD)id, (WORD)id, AfxSigCmd_v, \
static_cast<AFX_PMSG> (&ThisClass :: memberFxn) },
// ON_COMMAND(id, OnBar) is the same as
// ON_CONTROL(0, id, OnBar) or ON_BN_CLICKED(0, id, OnBar)
This does two things.
First of all it undefines the current definition of the ON_COMMAND() macro so that you can replace it with your own.
Secondly it uses the class method membership notation for the method pointer. I am unable to test with CLANG however it should do the same source text substitution as you did by hand which you say works.
ON_COMMAND(CID_ButtonAction, &SomeForm::OnButtonAction)
ThisClass is a typedef for the class specified in the BEGIN_MESSAGE_MAP() directive (e.g. BEGIN_MESSAGE_MAP(CFrameworkWnd, CWin)) and is generated by the BEGIN_MESSAGE_MAP() macro which looks like:
#define BEGIN_MESSAGE_MAP(theClass, baseClass) \
PTM_WARNING_DISABLE \
const AFX_MSGMAP* theClass::GetMessageMap() const \
{ return GetThisMessageMap(); } \
const AFX_MSGMAP* PASCAL theClass::GetThisMessageMap() \
{ \
typedef theClass ThisClass; \
typedef baseClass TheBaseClass; \
static const AFX_MSGMAP_ENTRY _messageEntries[] = \
{
I tested this approach with Visual Studio and everything compiles just fine and it works with Visual Studio 2005.
Please note there may be other message map macros which may require a similar workaround as the use of the static_cast<AFX_PMSG> seems to be pretty common in most of the message map macros.
A curious difference
Looking into this, one curious difference in the various macros in afxmsg_.h is an entire set of macros that use the class method pointer notation. An example is the following:
#define ON_WM_PAINT() \
{ WM_PAINT, 0, 0, 0, AfxSig_vv, \
(AFX_PMSG)(AFX_PMSGW) \
(static_cast< void (AFX_MSG_CALL CWnd::*)(void) > ( &ThisClass :: OnPaint)) },
Looking at some of the specific event macros, it appears that they reuse the ON_CONTROL() macro so replacing that macro in addition to the ON_COMMAND() macro would ripple down through the set of control specific MFC macros.
// Combo Box Notification Codes
#define ON_CBN_ERRSPACE(id, memberFxn) \
ON_CONTROL(CBN_ERRSPACE, id, memberFxn)
A summation
Using this approach of overriding the default macros with your own version, it appears that the include file afxmsg_.h contains a list of the what would need to change. It also appears that there are two sets of MFC macros that would need a replacement version, ones near the top of the file (beginning with ON_COMMAND()) and a few macros near the bottom of the include file afxmsg_.h.
For instance the ON_MESSAGE() macro would need a change to:
// for Windows messages
#define ON_MESSAGE(message, memberFxn) \
{ message, 0, 0, 0, AfxSig_lwl, \
(AFX_PMSG)(AFX_PMSGW) \
(static_cast< LRESULT (AFX_MSG_CALL CWnd::*)(WPARAM, LPARAM) > \
(&ThisClass :: memberFxn)) },
I wonder why there is a mix of styles (possibly due to different people adding new macros over the years and not bothering to change the existing ones?). I am curious why this has not been addressed sometime during the last two decades as MFC dates from at least Visual Studio 6.x and there would have been opportunities to make the macros uniform. For instance the release of Visual Studio 2005 would have been a good time. Perhaps there was a concern for backwards compatibility with that huge Visual Studio 6.x MFC code base?
And now I know why the tailored, specific static_cast<>. It allows for the detection of a class method with the wrong or non-matching interface signature with a compilation error. So the C-style cast is to make things right with the definition for the function pointer in AFX_MSGMAP_ENTRY and the static_cast<> is to catch programmer errors due to a defective interface by issuing a compiler error if the method interface differs from what is expected.

Replacing a name of a function using define macros in cpp correctly

I'm using Eclipse + Qualcomm libraries (in cpp) + Android SDK on Ubuntu. My application runs fine. If I change some code in the qualcomm libraries, it compiles and works correctly.
The problem is: I have changed the name of the project, and I have to change some code in cpp (The name of the function), if I don't do it, I get a Java.lang.UNSATISFIEDLINKERROR.
That's because all the functions have the name as the Android package like this:
Java_org_myproject_marker_MainActivity_onQCARInitializedNative(JNIEnv *, jobject)
Then I define a macro like this:
#define MAIN_ACTIVITY_PREFIX org_myproject_marker_MainActivity
#define VISUALIZER_PREFIX org_myproject_marker_Visualizer
And I change all the correct functions by:
Java_MAIN_ACTIVITY_PREFIX_onQCARInitializedNative(JNIEnv *, jobject)
but I am still getting the Java.lang.UNSATISFIEDLINKERROR exception.
It works if I do it without the #define macro (and write all the lines), but I want to save the cpp code with a top define that changes everything automatically if I need to use it in other projects.
I have read this tutorial. Can't I replace a text inside another text or something like that?
you are looking for string concatenation, like this:
#define MAIN_ACTIVITY_PREFIX(n) Java_org_myproject_marker_MainActivity##n
and then use it like this:
MAIN_ACTIVITY_PREFIX(_onQCARInitializedNative)(JNIEnv *, jobject)
Indeed, a CPP macro wont be expanded in the middle of an identifier. Try with
#define MAIN_ACTIVITY_PREFIX(func) Java_org_myproject_marker_MainActivity##func
That gives you a macro that will prepend Java_org_myproject_marker_MainActivity to the function name you pass it. Use it as:
MAIN_ACTIVITY_PREFIX(_onQCARInitializedNative)(JNIEnv *, jobject) {
...
}

How can I catch an invalid fgetpos call as a C++ exception on Windows?

In Visual C++ 2008, I want to "catch" an exception generated as shown here:
try {
int foo = 20;
::fgetpos(0, (fpos_t*)&foo);
}
//...
Here are adjustments I've made to attempt a successful catch:
SEH is activated (/eha)
I've added a catch(...)
I've added a _set_se_translator vector.
I've added/adjusted to SEH syntax: __try / __except(EXCEPTION_EXECUTE_HANDLER)
In short, I've tried "everything in the book" and I still can't catch the exception. If I replace the call to ::fgetpos with int hey = foo / 0 then suddenly all of the above techniques work as expected. So the exception I'm dealing with from ::fgetpos is somehow "extra special."
Can someone explain why this ::fgetpos error seems uncatchable, and how to work around it?
update When executed in the VS IDE, the output window doesn't name an exception. All it says is this:
Microsoft Visual Studio C Runtime Library has detected a fatal error in MyProgram.exe.
Not very helpful. When I run the console app from the command line, I get a crash dialogue. The "problem details" section of the dialogue includes this information:
Problem Event Name: BEX
Exception Offset:0002fd30
Exception Code: c0000417
Exception Data: 00000000
Additional Information 1:69ad
Additional Information 2:69addfb19767b2221c8e3e7a5cd2f4ae
Additional Information 3:b1ff
Additional Information 4:b1ffca30cadddc78c19f19b6d150997f
Since the code in your dump corresponds to STATUS_INVALID_CRUNTIME_PARAMETER, try _set_invalid_parameter_handler
Most likely, the runtime catches it for you and issues a debug dialog without returning or propagating the exception- that is a CRT call and they may add whatever exception catching code in there they like. It's well within Visual Studio's rights to catch a hardware exception inside a library function, especially if you are running from within the IDE or in debug mode, then it is expected of the runtime.
Of course, when you divide by zero, then there is no library call here to write that extra catching code.