Re: Print only part of a stack trace

2020-07-01 Thread Dennis via Digitalmars-d-learn

On Wednesday, 1 July 2020 at 19:33:08 UTC, JN wrote:
Bit off-topic, but if you can use them, debug contexts offer 
much better OpenGL error-checking experience. 
https://www.khronos.org/opengl/wiki/Debug_Output . Instead of 
checking glGetError() after each call, you can setup a C 
callback that will trigger whenever an error occurs. It also 
offers some vendor-specific performance warnings.


I use those as well, to get a more detailed message about the 
error than the error code alone. While it helps describing _what_ 
went wrong, it doesn't tell me _where_ it went wrong.


I tried doing assert(0) in the callback, but even with 
glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS), the stack trace looks 
something like this:


app.d: debugCallback [0x559eda75c7e8]
??:? [0x7f4a0bffa7d7]

And then it ends. It seems like it goes up into the OpenGL dll 
and then gets stuck, it does not trace back to the call site of 
the glFunction that failed.


Re: Print only part of a stack trace

2020-07-01 Thread JN via Digitalmars-d-learn

On Wednesday, 1 July 2020 at 18:30:15 UTC, Dennis wrote:
I have a function that checks a global error constant of a C 
library (OpenGL) like this:

```
void assertNoOpenGLErrors() {
if (glGetError() != GL_NO_ERROR) {
assert(0); // stack trace points to here instead of 
caller

}
}


Bit off-topic, but if you can use them, debug contexts offer much 
better OpenGL error-checking experience. 
https://www.khronos.org/opengl/wiki/Debug_Output . Instead of 
checking glGetError() after each call, you can setup a C callback 
that will trigger whenever an error occurs. It also offers some 
vendor-specific performance warnings.


Re: Print only part of a stack trace

2020-07-01 Thread Dennis via Digitalmars-d-learn

On Wednesday, 1 July 2020 at 18:54:55 UTC, Dennis wrote:
It sort of works, but it seems it does not start at the right 
stack frame, the top item is this:


??:? void rt.dmain2._d_run_main2(char[][], ulong, extern (C) 
int function(char[][])*).runAll().__lambda1() [0x55c19a09c1fa]


So dmd skips the first 5 stack frames to account for 
_d_traceContext, _d_createTrace etc, while ldc filters out by 
filename.


https://github.com/ldc-developers/druntime/blob/cc97ccd00d4082221eee1d5afdbd775201d75877/src/core/runtime.d#L855

I can easily work around this, though it's unfortunate that the 
public API of DefaultTraceInfo has this limitation.


Re: Print only part of a stack trace

2020-07-01 Thread Dennis via Digitalmars-d-learn

On Wednesday, 1 July 2020 at 18:44:10 UTC, Stanislav Blinov wrote:
void assertNoOpenGLErrors(string file = __FILE__, int line = 
__LINE__, string func = __PRETTY_FUNCTION__)

{
if (glGetError() != GL_NO_ERROR) {
print(file, ":", line, ":", func, ": blah");
exit();
}
}

:)


I love __FILE__ and __LINE__, but in this case they won't cut it.
In my actual code there's usually one or two more functions 
inbetween, and amending hundreds of signatures with __FILE__ and 
__LINE__ for a little debugging convenience is not worth it.


I'm now trying to call the defaultTraceHandler manually like this:
```
void bar() {
import std.stdio;
import core.runtime: defaultTraceHandler;
auto res = defaultTraceHandler(null);
writeln(res);
}

void foo() {bar();}
void main() {foo();}
```

It sort of works, but it seems it does not start at the right 
stack frame, the top item is this:


??:? void rt.dmain2._d_run_main2(char[][], ulong, extern (C) int 
function(char[][])*).runAll().__lambda1() [0x55c19a09c1fa]


Re: Print only part of a stack trace

2020-07-01 Thread Adam D. Ruppe via Digitalmars-d-learn

On Wednesday, 1 July 2020 at 17:44:45 UTC, Dennis wrote:
On assertion failure, the default error handler prints a stack 
trace that looks like this



My cgi.d does something just like that. It just does 
`exception.toString()` then `splitLines` on that string.




Element exceptionToElement(Throwable t) {
auto div = Element.make("div");
div.addClass("exception-display");

div.addChild("p", t.msg);
div.addChild("p", "Inner code origin: " ~ 
typeid(t).name ~ "@" ~ t.file ~ ":" ~ to!string(t.line));


auto pre = div.addChild("pre");
string s;
s = t.toString();
Element currentBox;
bool on = false;
foreach(line; s.splitLines) {
if(!on && line.startsWith("-"))
on = true;
if(!on) continue;
if(line.indexOf("arsd/") != -1) {
if(currentBox is null) {
currentBox = 
pre.addChild("details");

currentBox.addChild("summary", "Framework code");

}
currentBox.addChild("span", line 
~ "\n");

} else {
pre.addChild("span", line ~ "\n");
currentBox = null;
}
}

return div;
}





Re: Print only part of a stack trace

2020-07-01 Thread Stanislav Blinov via Digitalmars-d-learn

On Wednesday, 1 July 2020 at 18:30:15 UTC, Dennis wrote:

I have a function that checks a global error constant of a C 
library (OpenGL) like this:

```
void assertNoOpenGLErrors() {
if (glGetError() != GL_NO_ERROR) {
assert(0); // stack trace points to here instead of 
caller

}
}
```

And I would like to rewrite it to this:
```
void assertNoOpenGLErrors() {
if (glGetError() != GL_NO_ERROR) {
print(getStackTrace().filterTrace());
exit();
}
}
```


void assertNoOpenGLErrors(string file = __FILE__, int line = 
__LINE__, string func = __PRETTY_FUNCTION__)

{
if (glGetError() != GL_NO_ERROR) {
print(file, ":", line, ":", func, ": blah");
exit();
}
}

:)


Re: Print only part of a stack trace

2020-07-01 Thread Dennis via Digitalmars-d-learn

On Wednesday, 1 July 2020 at 18:05:09 UTC, Jacob Carlborg wrote:
[1] 
https://dlang.org/phobos/core_runtime.html#.Runtime.traceHandler


Thanks, but I don't want to re-implement the default trace 
handler, I want to use it on a specific location and capture its 
output. I'll be more specific in what I want to achieve.


I have a function that checks a global error constant of a C 
library (OpenGL) like this:

```
void assertNoOpenGLErrors() {
if (glGetError() != GL_NO_ERROR) {
assert(0); // stack trace points to here instead of caller
}
}
```

And I would like to rewrite it to this:
```
void assertNoOpenGLErrors() {
if (glGetError() != GL_NO_ERROR) {
print(getStackTrace().filterTrace());
exit();
}
}
```

So that the stack trace immediately points to the function that 
raised the OpenGL error, instead of it being buried in a large 
trace.


Re: Print only part of a stack trace

2020-07-01 Thread Jacob Carlborg via Digitalmars-d-learn

On 2020-07-01 19:44, Dennis wrote:
On assertion failure, the default error handler prints a stack trace 
that looks like this


[library functions]
[application functions]
[druntime start-up functions]

I'm only interested in application functions, the rest is noise.
I could easily filter unwanted lines out if I had the stack trace in 
string form, but I don't know how to obtain that. Is there a simple way 
to do this, or should I delve into Druntime internals?


Could `Runtime.traceHandler` [1] be that you're looking for?

[1] https://dlang.org/phobos/core_runtime.html#.Runtime.traceHandler

--
/Jacob Carlborg