gedaiu / fluent-asserts

DLang fluent assertions done right
http://fluentasserts.szabobogdan.com/
MIT License
43 stars 6 forks source link

why the stack trace removed ? can we add it back? #91

Closed mw66 closed 4 years ago

mw66 commented 4 years ago

Hi,

When an assertion fails, I want to see the stack trace, esp. in a multi-threaded program, I saw this commit: stack trace is added, and then removed:

https://github.com/gedaiu/fluent-asserts/commit/f1735bf80ac298f435a36791940e36aa56d8fbeb

I wonder why? can we add it back? It will greatly help debug the program.

Or provide a config option to let the user decide if s/he want to see the full stack trace? (I think most people want to see it).

Thanks.

gedaiu commented 4 years ago

hi @mingwugmail

I did not removed any code related to the stack printing. Can you tell me more about your issue? maybe you can paste the test that does not print the stack trace?

What version of the library and compiler are you currently using?

mw66 commented 4 years ago

Oh, I mean the full stack trace. I did saw the current frame, but I want to see the full stack trace all the way up to the root main().

gedaiu commented 4 years ago

The library throws an exception in case one of your asserts fail and the runtime will print the exception with it's stack trace.

From what I understand, you might have a setup problem. Without more details I can't do much to help.

mw66 commented 4 years ago

ok, a small example:

/+dub.sdl:
dependency "fluent-asserts" version= "~>0.13.3"
+/

import std.stdio;
import fluent.asserts;

void f2() {
  int k = 3;
  Assert.equal(k, 4);
}

void f1() {
  int j = 2;
  f2();
}

void f0() {
  int i = 1;
  f1();
}

void main() {
  f0();
}

the current fail message, only show the current stack frame of f2()

$ dub.exe sf.d

fluentasserts.core.base.TestException@sf.d(10): k should equal `4`.

 Expected:4
   Actual:3

--------------------
sf.d:10
--------------------
     6:
     7:
     8: void f2() {
     9:   int k = 3;
>   10:   Assert.equal(k, 4);
    11: }

----------------

what I want to see, all the call stack, f2(), f1(), f0(), all the way up to main(), e.g.:

sf.d:10
--------------------
     6:
     7:
     8: void f2() {
     9:   int k = 3;
>   10:   Assert.equal(k, 4);
    11: }
----------------
  f1() {
  ...
> f2();
----------------
  f0() {
  ...
> f1();
----------------
  main() {
  ...
> f0();

And better: for each stack frame, also print out its local variable values.

Is this possible in D?

Thanks.

gedaiu commented 4 years ago

It is definitely possible to print the variable values, but this is not a trivial task and there is no library support for this.

It looks like it is a compiler dmd issue. I am using the dmd 2.91.0 on linux and mac and I get the stack trace:

fluentasserts.core.base.TestException@source/app.d(10): k should equal `4`.

 Expected:4
   Actual:3

--------------------
source/app.d:10
--------------------
     6: 
     7: 
     8: void f2() {
     9:   int k = 3;
>   10:   Assert.equal(k, 4);
    11: }

----------------
../../source/fluentasserts/core/base.d:61 @safe void fluentasserts.core.base.Result.perform() [0x5e2ad3]
../../source/fluentasserts/core/base.d:65 @safe void fluentasserts.core.base.Result.__dtor() [0x5e2af0]
../../source/fluentasserts/core/base.d:601 @safe void fluentasserts.core.base.Assert.opDispatch!("equal", int, int).opDispatch(int, int, immutable(char)[], const(immutable(char)[]), const(ulong)) [0x5de297]
source/app.d:10 void app.f2() [0x5dc967]
source/app.d:15 void app.f1() [0x5dc983]
source/app.d:20 void app.f0() [0x5dc99b]
source/app.d:24 _Dmain [0x5dc9a8]
Program exited with code 1
gedaiu commented 4 years ago

I'm expecting that you don't see the stack trace of any exception thrown in your app.

mw66 commented 4 years ago

oh, I got that too, up to d_run_main, but 1) I had hoped to saw every stack frame printed nicely as the last frame:

--------------------
sf.d:10
--------------------
     6:
     7:
     8: void f2() {
     9:   int k = 3;
>   10:   Assert.equal(k, 4);
    11: }
----------------

2) and in my multi-threaded program, I indeed only got the last frame. It will take me some time to write another multi-threaded program to show you the example.

gedaiu commented 4 years ago

Ah... I see you want to see the source for each frame. The library was never designed to do this. The purpose of the source is too see which assert failed, which it looks like it works well.

Unfortunately, showing detailed info about your stack, is not possible with fluent asserts. To achieve this, you can use a debugger.

mw66 commented 4 years ago

ok 1) is not possible, I will see if I can make a small example for 2).

gedaiu commented 4 years ago

when you create a new thread, it will have a new stack, and no reference to where it was started. I'm not sure how you would see a stack trace up to your main function, since the stack frames that started the thread might not exist when your assert is triggered.

mw66 commented 4 years ago

Yes, you are right. I do see the stack start from the thread.run().

Thanks.