Throw runtime error in GLSL when assertion fails for debugging - runtime-error

In the function distSigned I am assuming that l.p != vec2(0). If this isn't the case, it could break the entire shader with a hard to find bug. Is there is any way of verifying this, and throwing a runtime-error if the parameters are invalid? This would make debugging a lot easier. I know GLSL doesn't have a throw like Java, but maybe theres some kind of hack?
struct parallel {
vec2 p;
vec2 d;
};
struct pt {vec2 v;};
float distSigned(pt p, parallel l) {
vec2 l2o = fromOrigo(l);
float d = length(l2o);
return dot(p.v, l2o/d) - d;
}
Edit: I had a look at the GLSL specification and found this:
"Compile-time errors must be returned for lexically or
grammatically incorrect shaders. Other errors are reported at compile time or link time as
indicated."
I guess this means GLSL doesn't have runtime errors? If so, maybe its possible for me to implement exceptions on my own? Is there some kind of design pattern for this?

Throw a runtime error to whom? When would it be thrown? How many shader invocations would throw, and how would the receiving code receive them?
Shaders get executed whenever the GPU gets around to it, not when you run a draw call. So the time when such errors would be "thrown" could be anywhere from "when you issue the draw call" to, well, arbitrarily far into the future. So how would you receive them, and who would do the receiving?
Plus, you're executing multiple shader invocations; every vertex and every fragment get their own individual invocation. And thus, every vertex and rasterized fragment could potentially "throw" some kind of runtime error. For a scene of size and complexity, that's potentially millions of such errors. How would you handle that?
No, if you want to debug shaders, you either need a specialized tool for that or you need to do the shader equivalent of printf debugging. That is, reduce your scene to the least complexity it can be reduced to, then write output values based on whether some error condition worked out one way or the other.

Error Pixel Implementation, Webgl2:
//:ES2_AA2_MAC_DEB: My debug macro, true if positive.
//: pix_err: PIXel ERRor ( Stores Hex Error Code )
//: pix_fra: PIXel FRAgment ( fragment color )
#if( ES2_AA2_MAC_DEB > 0 ) //:///////////////////////////://
//:ASSIGN_TO_ZERO_AT_TOP_OF_FUNCTION!!!!!!!!!!!!!!!!!!!!
uint pix_err =( 0x00000000 );
#endif //:///////////////////////////////////////////////://
//: ...Later when you want to error check....
#if( ES2_AA2_MAC_DEB > 0 ) //:///////////////////////////://
if( Ax1-Ax0+uint(1) != ES2_zoo_wid ||
Ay1-Ay0+uint(1) != ES2_zoo_hig ){
//: The first error encountered puts program ://
//: into invalid state, so we want to make sure ://
//: we never override the first error tripped. ://
//: So always guard with comparison to ://
//: 0x00000000 before setting to the error color.://
if( uint(0x00000000) == pix_err ){
pix_err=( uint(0xFF9000FF) );
};;
};;
#endif //:///////////////////////////////////////////////://
... Do more code.......................................
... DONT TRY TO EXIT EARLY if error is tripped ........
... that will just turn your code into spaghetti ......
#if( ES2_AA2_MAC_DEB > 0 ) //://////////////////////////://
if( uint(0x000000) != pix_err ){
#define F_F uint(0xFF)" //://////////////////////://
pix_fra=( vec4( //://///////////////////////////://
float( ( pix_err >> 24 ) & F_F ) / 255.0
,float( ( pix_err >> 16 ) & F_F ) / 255.0
,float( ( pix_err >> 8 ) & F_F ) / 255.0
,float( ( pix_err >> 0 ) & F_F ) / 255.0
));; //://///////////////////////////////////////://
#undef F_F //://////////////////////////////////://
};;
#endif //:///////////////////////////////////////////////://
//: Now in debug mode, you can color sample the pixel ://
//: and type in the hex code to find the exact error. ://
//: Might not be helpful for minor edge cases, but ://
//: should be very helpful for gross mistakes in ://
//: your programming logic. ://
return( pix_fra );

As it says in my edit, GLSL doesn't have runtime errors. It is possible to implement however. For something like try-catch one can do this:
#define assert(array, index, line, condition) if (!(condition)) array[index] = exception(line);
struct exception {int line;};
// In use
float distSigned(pt p, parallel l, out exception[1] errors) {
assert(errors, 0, __LINE__, l.p != vec2(0));
// rest of method ..
}
To log uncaught errors, one can use certain pixel-colors that each correspond to a specific error code, and maybe a pixel palette that hides these. When a fatal error occurs it's color is output.
In debug-mode the program can then look for pixels with these colors.
Problems with this method is that the __LINE__ can be offset if the shader is being included in another and that, in webGL, shader output can't be accessed by the CPU.
Perhaps there are GLSL debugers with this functionality, I haven't tried any.
Thanks to Nicol Bolas and LJᛃ for explaining most of this.

Related

Derefencing nullptr warning in c++

if (nullptr!=timing_info)
{
timing_info->h = start_time;
}
I get the following warning
autosar_cpp14 a5-1-1 violation
Using literal "NULL" other than type initialization, where symbolic names shall be used instead.
The autosar rule a5-1-1 reads
Rule A5-1-1 (required, implementation, partially automated) Literal
values shall not be used apart from type initialization, otherwise
symbolic names shall be used instead.
I never thought "nullptr" was a literal value. If it is a literal value, then what is the best way to handle this warning.
As you've already quoted, Rule A5-1-1 says
Rule A5-1-1 (required, implementation, partially automated)Literal
values shall not be used apart from type initialization,
otherwise symbolic names shall be used instead.
(source)
The idea behind this rule is that you should not use magic constants, i.e., don't write something like
// 100 is a magic constant. It's not clear what the next line means without comments.
if (list.size() > 100) {
std::cout << "error!";
} else {
std::cout << "everything ok!";
}
but rather, write
static constexpr auto maximum_allowed_size = 100;
// The next line speaks for itself: "if list is bigger than allowed ..."
if (list.size() > maximum_allowed_size) {
std::cout << "error!";
} else {
std::cout << "everything ok!";
}
This extra constant increases readability in most cases.
Since nullptr is a literal and you use that literal nullptr for something else than "type initialization", your code violates that rule A5-1-1.
I don't know if autosar intentionally discourages the use of literal nullptr, I personally don't see a reason why one should do this. Maybe it has been overseen (should be an exception).
You can rephrase your code to silence the checker:
if (timing_info) // implicitly convert pointer to bool
as that variant apparently makes the checker unhappy, too, here is another variant:
if (!!timing_info) // convert pointer to bool using double negation
You could also use casts, but I wouldn't do that. Frankly speaking, I like the original variant (if (nullptr != timing_info)) most.

c++ Occasional Dynamic Pointer Crashing

I have made a program to take in float inputs from a user to create a dynamic array (Then use those inputs with functions to find basic stuff like max,min,sum,avg but that stuff works fine so I don't think Ill include that here for the purpose of not creating a wall of code).
It works about half the time and while I have some theories about the cause I cant put my finger on a solution.
int main() {
int Counter = 0;
float *UsrIn = nullptr;
float Array[Counter];
My first thought was that the part below was the issue. My class hasn't really gone over what notation (I assume it refers to bytes so maybe scientific notation would work) to use with new that I can recall. I just tried 20 for the sake of testing and it seemed to work(probably a silly assumption in hindsight).
UsrIn = new float[(int)20];
cout << "Enter float numbers:" << endl;
cout << "Enter '9999999' to quit:" << endl;
cin >> *UsrIn; // User Input for pointer Dynamic Array
Array[Counter] = *UsrIn;
while(*UsrIn!=9999999) // User Input for Dynamic Array
{
Counter++;
UsrIn++;
cin >> *UsrIn;
Array[Counter] = *UsrIn;
}
delete UsrIn;
delete[] UsrIn;
My other thought was that maybe a pointer address was already in use by something else or maybe it was invalid somehow. I don't know of a way to test for that because the crash I occasionally get only happens when exiting the while loop after entering "9999999"
As a side note I'm not getting any warnings or error messages just a crashed program from eclipse.
Variable-length arrays are not universally supported in C++ implementations, although your compiler clearly supports them. The problem, from what you've described, is with this code:
int main() {
int Counter = 0;
float *UsrIn = nullptr;
float Array[Counter];
You're defining a variable-length array of size 0. So, although you're allocating 20 entries for UsrIn, you're not allocating any memory for Array. The intention of variable-length arrays is to allocate an array of a given size where the size is not actually known until run time. Based on your other code, that's not really the situation here. The easiest thing to do is just change the Array size to match your UsrIn size, e.g.:
float Array[20];
If you really want more of a dynamic behavior, you could use std::vector<float>
std::vector<float> Array;
...
Array.push_back(*UsrIn);

Rf_error and Rf_warning definitions

Where can I find the definitions for these two functions. Grepping for their name brings only declarations but I can't find their implementation in the source code.
Presumably you are looking for the C code function definitions. What I typically do when looking for the definitions is search across all files for the function name without the Rf_ but with the return type. For example, for Rf_error, I would search for void error. In this case you pretty quickly get (from src/main/errors.c#758, for R version 3.2.2):
void error(const char *format, ...)
{
char buf[BUFSIZE];
RCNTXT *c = R_GlobalContext;
va_list(ap);
va_start(ap, format);
Rvsnprintf(buf, min(BUFSIZE, R_WarnLength), format, ap);
va_end(ap);
/* This can be called before R_GlobalContext is defined, so... */
/* If profiling is on, this can be a CTXT_BUILTIN */
if (c && (c->callflag & CTXT_BUILTIN)) c = c->nextcontext;
errorcall(c ? c->call : R_NilValue, "%s", buf);
}
Rf_warning is defined at line 262 of the same file.
Note the following lines in src/include/R_ext/Error.h
#ifndef R_NO_REMAP
#define error Rf_error
#define warning Rf_warning
#endif
R_NO_REMAP is usually not defined, so that means the macro error expands to Rf_error. So, in files that include Error.h, instances of error will be replaced with Rf_error by the preprocessor.
So you need to search for the function with the same return type and arguments. As BrodieG notes in his answer, the functions also usually (always?) have the same name, but without the Rf_ prefix.
Thanks to Duncan Murdoch for helpful pointers. Any errors are mine.

QList for touch-points not being created, "A data abort exception has occurred"

I am trying to get touch inputs for my program targeting an N8 (and a C7), and I am not able to create a QList for keeping touchpoints using QTouchEvent::touchPoints(). The program crashes with the following line: Thread has crashed: A data abort exception has occurred accessing 0xee
The overloaded events function looks like:
bool GLWindow::event(QEvent *event)
{
switch ( event->type() ) {
case QEvent::TouchBegin: {
QList<QTouchEvent::TouchPoint> touchBeginPoints =
static_cast<QTouchEvent *>(event)->touchPoints();
foreach (const QTouchEvent::TouchPoint &touchBeginPoint, touchBeginPoints)
{
float touchBeginX = touchBeginPoint.pos().x();
float touchBeginY = touchBeginPoint.pos().y();
qDebug() << "touchBeginPoint := " << touchBeginX << ", " << touchBeginY;
}
break;
}
case QEvent::TouchUpdate: {
// same as touch begin: getting touch point
break;
}
case QEvent::TouchEnd: {
// same as touch begin: getting touch point
break;
}
default: {
qDebug() << "Goodbye";
return true;
}
}
return true;
}
Now,
I have never worked with containers before. But creating and using a QList in another part of the program works fine. Should I be including something in my .pro file? (Most problems seem to end up regarding this with me!)
I read (a bit) about exceptions in Qt and Symbian, but I am not able to get most of that. BUT I am not doing any networking or resource based i/o or manipulation except textures for 3D objects. Is it possible that memory allocation while running the program is creating some problem?
Basically I am just trying to print the touch point. But I am clueless as to why I can’t create a QList. The code compiles fine. I tried my best (unsuccessfully), but is there any other way to get the screen coordinates of a touchpoint (one that does not require a QList)? Any comments are welcome.
[Reposting from qt-project.org.]
Your syntax is 100% correct. Just look at this example: http://www.developer.nokia.com/Community/Wiki/Painting_in_Qt
What I'm guessing happens is that QTouchEvent::touchPoints() returns a list big enough that it overflows your stack. Try increasing the stack size for your application.
Is your syntax correct ? The compilation error seems to reinforce teukkam point...
What happens when you replace
static_cast<QTouchEvent *>(event)->touchPoints()
With
(dynamic_cast<QTouchEvent *>(event))->touchPoints()
Notice the parentheses...

Why does my program halt when calling front() on a std::queue?

I want to use the Irrnet network library in an Irrlicht game.
The source code uses Linux sockets and I'm trying to port it for Windows replacing it with code that uses Windows' Winsock2.
The library compiles successfully but when I try to run the Quake example it crashes. I located the line at which the program stops but i can't figure out how to solve the problem.
The program stops at the second call of the function getNextItem
class NetworkType {
public :
NetworkType();
~NetworkType();
template<class T>
void getNextItem(irr::core::vector3d<T>& data);
private:
typedef std::queue<std::string> Container;
Container items;
};
template<class T>
void NetworkType::getNextItem(irr::core::vector3d<T>& data) {
T X, Y, Z;
std::istringstream item(items.front());
// the program does not get here the second time it calls this function
items.pop();
item >> X;
item >> Y;
item >> Z;
data = irr::core::vector3d<T>(X, Y, Z);
}
and exactly at this line
std::istringstream item(items.front());
Can anyone tell me why does the program stop the second time it gets to this line ?
here is the link for the complete source code
I assume by "stops" you mean "crashes" in some fashion? Likely causes for a crash on the line in question are:
The NetworkType instance that is invoking the getNextItem() method is garbage (the this pointer is garbage or null). This could happen due to bad pointer math elsewhere, a premature delete or destruction of the instance, et cetera. This would manifest as a fault when the program attempted to access the items member.
The items container is empty. In these cases the return value of front() is undefined (since it is a reference) and the constructor for istringstream may be crashing. front() itself may be raising a debug/runtime check error as well depending on your compiler and its configuration.
Actually you might have a runtime error on this one if the dequeue is empty: MSDN deque
So just check the deque isn't empty before you try to pop a value from it.
if(items.size()>0)
{
//do things
}
else
{
//error deque empty
}
[edit] confounded std and (I guess) MSDN ( OP doesn't say) lib.

Resources