July 29, 2004 Re: prog segfaults | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter | "Walter" <newshound@digitalmars.com> wrote in message news:cea6oh$14c3$1@digitaldaemon.com... > > "Regan Heath" <regan@netwin.co.nz> wrote in message news:opsbvo8cpg5a2sq9@digitalmars.com... > > Cool. Is "access violation" == SIGSEGV > > > > Does it catch anything else as well? It would be cool if I could catch: > > > > #define SIGINT 2 /* interrupt */ > > #define SIGILL 4 /* illegal instruction - invalid function > > image */ > > #define SIGFPE 8 /* floating point exception */ > > #define SIGSEGV 11 /* segment violation */ > > #define SIGTERM 15 /* Software termination signal from kill > */ > > #define SIGBREAK 21 /* Ctrl-Break sequence */ > > #define SIGABRT 22 /* abnormal termination triggered by abort > > call */ > > > > (the above are just the windows signals) > > Yes. If you want to see how it's done, see internal\deh.c function > _d_translate_se_to_d_exception() > > > or the third option, my favourite: > > - The compiler defines a 'char[] file' and 'uint line' which I can > access. > > > > Why is that so hard to do? > > I always thought __FILE__ and __LINE__ are just so ugly. But when you think > about it, __FILE__ and __LINE__ only really make sense for macros. Using them directly is pointless, isn't it? Wouldn't it make sense to throw a string, and then grep on that string if you can't remember where it came from? 1) Sometimes the same exception message is used in multiple places, so it can be hard to track down. 2) Sometimes you don't have the source, but still need to know the culprit 3) the message itself might be manufactured (via localization/externalization) so wouldn't be found with a grep 4) it's very useful to place this information into a 'log' message, so you can easily see what produced a message witthout having to scan the source. etc. If you're concerned about exposing the __FILE__ as a symbol, is it possible to wrap it? Perhaps as an instrinsic function (like rol/ror)? |
July 29, 2004 Re: prog segfaults | ||||
---|---|---|---|---|
| ||||
Posted in reply to Mickey Finn | > 1) Sometimes the same exception message is used in multiple places, so it
> can be hard to track down.
> 2) Sometimes you don't have the source, but still need to know the culprit
> 3) the message itself might be manufactured (via
> localization/externalization) so wouldn't be found with a grep
> 4) it's very useful to place this information into a 'log' message, so you
> can easily see what produced a message witthout having to scan the source.
>
> etc.
5) dmd.exe uses __FILE__ & __LINE__ itself: I just got this message from the
compiler :-)
Internal error: s2ir.c 457
|
July 29, 2004 Re: prog segfaults | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter | "Walter" <newshound@digitalmars.com> wrote in news:cea6oh$14c3$1@digitaldaemon.com: > You can also simply write: > assert(p != null); > and not generate a seg fault. Sure it does! (I checked with DMD 0.96) You probably meant: assert(p isnot null); // ;-) Joking aside, exception stacktraces would be a boon to programmers. The pain with exceptions is that in well refactored code, exceptions are often thrown in on function, but that function is called via various code paths. So you know where the exception was thrown and where it was caught, but you don't known what happened in between. I for one, refused to use exceptions in C++ mainly for that reason. And the one time, I did use exceptions, I actually hacked the stacktrace in my code by hand and a little help from the preprocessor. The __FILE__, __LINE__ and especially __FUNCTION__ (non-standard) data is very handy for writting log files. Please, consider that log files are *very* important to some people, so they create all this information by hand if a language doesn't provide it or in Java's case cannot produce it fast enough. Farmer. |
July 29, 2004 Re: prog segfaults | ||||
---|---|---|---|---|
| ||||
Posted in reply to Farmer | In article <Xns9536AC639A46itsFarmer@63.105.9.61>, Farmer says... > >So you know where the exception was thrown and where it was caught, but you >don't known what happened in between. >I for one, refused to use exceptions in C++ mainly for that reason. And the >one time, I did use exceptions, I actually hacked the stacktrace in my code >by hand and a little help from the preprocessor. There have been articles written by very smart people on how to (in code) generate stack traces in C++ when exceptions are thrown. IIRC the conclusion was that it's just not possible to do very well. I agree that it would be nice to have compiler support for stack traces when exceptions are thrown. Sean |
July 30, 2004 View/Copy Stack for Later Debug was: prog segfaults | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter | I have written some code that allows you to view & dump the current stack. My thought is that many exception types should, by default, perform this stack dump when they are created. Then, whenever they are caught, the user can implement a stack backtrace. We need to add these functions to class Thread: class Thread { ... static byte[] ViewStack() { Thread t = <getCurrentThread>; return t.ViewStack(); } byte[] ViewStack() { // swap the array indices for STACK_GROWS_UP assert(this.stackBottom > Thread.getESP()); return (cast(byte*)0)[Thread.getESP()..this.stackBottom]; } ... } I created this class. Some types of exceptions probably should not do a stack dump; others (like SegFault and AssertError) should do so. Perhaps AssertError should be a child of a class something like this: class Error_DumpsStack : Error { byte[] stackDump; this(char[] arg) { super(arg); stackDump = Thread.ViewStack().dup; } } Finally, users (or perhaps the standard D loader function?) should do this. This code requires that somebody write a function PrintStackBackTrace(byte[]): int main(char[] args) { try { ...put your main code here... } catch(Error_DumpsStack e) { PrintStackBacktrace(e.stackDump); } catch(Error e) { ...whatever... } } |
July 30, 2004 Re: View/Copy Stack for Later Debug was: prog segfaults | ||||
---|---|---|---|---|
| ||||
Posted in reply to Russ Lewis | On Thu, 29 Jul 2004 17:51:36 -0700, Russ Lewis wrote:
> I have written some code that allows you to view & dump the current stack.
50 lines of code?
What are we waiting?
oh, right, it took 1 year to get listdir on linux version.
Walter, please, this should have been there since 0.01.
Ant
|
July 30, 2004 Re: prog segfaults | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter | On Wed, 28 Jul 2004 23:43:33 -0700, Walter <newshound@digitalmars.com> wrote: > "Regan Heath" <regan@netwin.co.nz> wrote in message > news:opsbvo8cpg5a2sq9@digitalmars.com... >> Cool. Is "access violation" == SIGSEGV >> >> Does it catch anything else as well? It would be cool if I could catch: >> >> #define SIGINT 2 /* interrupt */ >> #define SIGILL 4 /* illegal instruction - invalid function >> image */ >> #define SIGFPE 8 /* floating point exception */ >> #define SIGSEGV 11 /* segment violation */ >> #define SIGTERM 15 /* Software termination signal from kill > */ >> #define SIGBREAK 21 /* Ctrl-Break sequence */ >> #define SIGABRT 22 /* abnormal termination triggered by abort >> call */ >> >> (the above are just the windows signals) > > Yes. If you want to see how it's done, see internal\deh.c function > _d_translate_se_to_d_exception() > >> or the third option, my favourite: >> - The compiler defines a 'char[] file' and 'uint line' which I can > access. >> >> Why is that so hard to do? > > I always thought __FILE__ and __LINE__ are just so ugly. So change the names. debug.file and debug.line are fine by me. > But when you think > about it, __FILE__ and __LINE__ only really make sense for macros. Using > them directly is pointless, isn't it? No. > Wouldn't it make sense to throw a > string, and then grep on that string if you can't remember where it came > from? Then you have to make sure all your strings aren't the same, if the same problem is thrown from several locations "Out of memory" you want the same string. > You can also simply write: > assert(p != null); > and not generate a seg fault. Yeah, as long as I remember to check for them all time, I'd rather not have to, like you said why do this when the hardware will do it for me ;) Regan -- Using M2, Opera's revolutionary e-mail client: http://www.opera.com/m2/ |
July 30, 2004 Re: View/Copy Stack for Later Debug was: prog segfaults | ||||
---|---|---|---|---|
| ||||
Posted in reply to Russ Lewis | Russ Lewis wrote: > I have written some code that allows you to view & dump the current stack. My thought is that many exception types should, by default, Any chance you will post it? > perform this stack dump when they are created. Then, whenever they are caught, the user can implement a stack backtrace. > > We need to add these functions to class Thread: Why not add char[] stackDump to Exception and fill it in in the Exception construction? You should also be able to add a function printStackTrace() to Exception and all Errors will thus have the data by default. |
July 30, 2004 Re: View/Copy Stack for Later Debug was: prog segfaults | ||||
---|---|---|---|---|
| ||||
Posted in reply to parabolis | parabolis wrote: > Russ Lewis wrote: > >> I have written some code that allows you to view & dump the current stack. My thought is that many exception types should, by default, > > Any chance you will post it? Well, what I've posted already is the distilled core of the code. I'll post the whole program at the bottom of this message. > Why not add char[] stackDump to Exception and fill it in in the Exception construction? You should also be able to add a function printStackTrace() to Exception and all Errors will thus have the data by default. IMHO, you shouldn't have stack trace in every Exception because some are likely to be caught and handled...and then doing a stack trace would be wasteful. Perhaps I am wrong, though. Here's the complete program. It compiles and (seems to) work on linux. > import std.thread; > import std.string; > byte[] ViewStack(Thread t) { > assert(t.stackBottom > Thread.getESP()); > return (cast(byte*)0)[Thread.getESP()..t.stackBottom]; > } > byte[] ViewStack() { > return ViewStack(Thread.getAll()[0]); > } > class Error_DumpsStack : Error { > byte[] stackDump; > this(char[] arg) { > super(arg); > stackDump = ViewStack().dup; > } > } > int main() { > byte[] stackView = ViewStack(); > byte[] stackCopy = stackView.dup; > try { > throw new Error_DumpsStack("test"); > } > catch(Error_DumpsStack e) { > printf("stackView = %d/%p stackCopy=%d/%p stackDump=%d,%p\n", stackView,stackCopy,e.stackDump); > printf("cmp(...) = %d\n", cmp(cast(char[])stackView[stackView.length/2..stackView.length],cast(char[])e.stackDump[e.stackDump.length-stackView.length/2..e.stackDump.length])); > } > return 0; > } |
July 30, 2004 Re: prog segfaults | ||||
---|---|---|---|---|
| ||||
Posted in reply to Sean Kelly | Sean Kelly wrote: > In article <Xns9536AC639A46itsFarmer@63.105.9.61>, Farmer says... > >>So you know where the exception was thrown and where it was caught, but you don't known what happened in between. >>I for one, refused to use exceptions in C++ mainly for that reason. And the one time, I did use exceptions, I actually hacked the stacktrace in my code by hand and a little help from the preprocessor. > > There have been articles written by very smart people on how to (in code) > generate stack traces in C++ when exceptions are thrown. IIRC the conclusion > was that it's just not possible to do very well. I agree that it would be nice > to have compiler support for stack traces when exceptions are thrown. It is possible to do a portable stack trace if you know the starting address and size of every function in the program. That is something that could be provided in a portable way by the compiler. Something like this: struct FunctionInfo { char[] name; // name would include module name, and, for nested // or literal functions, the nested function name. // Something like: // foo.bar.baz.MyFunc(int).nestedFunc1(char) char[] linkname; // this would be the C-compatible name, as it is // in the object file byte *startingAddr; size_t size; FunctionInfo[] subFunctions; // nested functions and literal functions go here }; FunctionInfo[] GetAllFunctions() {...} |
Copyright © 1999-2021 by the D Language Foundation