willett wrote:
I'm looking for a very simple debugging info from a running gpc program. without getting into a debugger etc. I'm just using gp from command line.
By default, most errors get the uninformative message "Segmentation fault". I would think ther would be some compiler option for more information at time of program failure, for example, the procedure name in which the error occurred, a procedure traceback, and/or a line number at which the error occurred.
For proper runtime errors, the option `--gpc-rts=-EFILENAME' or `--gpc-rts=-F42' will write a traceback to file FILENAME or file descriptor 42, resp. Using addr2line, the addresses can be translated into source file names and line numbers. The program gpc-run (comes with GPC) does this automatically (if everything works well -- AFAIK it's not well tested, mainly by myself, and only on Unix compatible systems). Just call:
gpc-run your-program your-arguments
However, for crashes such a segfaults, this method won't work as GPC doesn't get to printing error messages. You could try installing a signal handler in your program, like this:
program CrashHandlerDemo;
uses GPC;
procedure CrashHandler (Signal: CInteger); begin Discard (Signal); RuntimeError (267) end;
procedure Test; var p: ^Integer; begin p := nil; WriteLn (p^) end;
procedure Test1; begin Test end;
begin if not InstallSignalHandler (SigSegV, CrashHandler, False, False, Null, Null) then WriteLn (StdErr, 'could not install signal handler'); Test1 end.
But there are also caveats:
- A signal handler might have limited stack space which the backtrace printing routines might not like. On my system, it seems to work now (at least in this case, haven't tested these things much recently), but I remember problems earlier.
- I'm not sure how reliable backtracing from a signal handler is. In my test, only Test1, not Test, showed up in the backtrace.
- After a serious segfault, the program (I/O system, internal variables, ...) may be instable or inconsistent, and trying to print anything (including the backtrace) simply might not work anymore.
So, the best solution, of course, is to turn crashes into runtime errors as far as possible, by enabling checks such as range and object checking (on by default) and pointer checking (--pointer-checking), but for tricky crashes this won't help. So, in the end, using a debugger is sometimes probably the easiest way to locate a segfault.
Frank