Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ocaml line numbers #7736

Closed
vicuna opened this issue Oct 20, 2002 · 3 comments

Comments

@vicuna
Copy link

commented Oct 20, 2002

Original bug ID: 1448
Reporter: administrator
Status: closed
Resolution: fixed
Priority: normal
Severity: minor
Category: ~DO NOT USE (was: OCaml general)

Bug description

Hi. I'm new to ocaml and think it's a great language. However I
encountered this problem and was wondering if it was a known issue...

I've noticed that line numbers (or more precisely, character positions)
aren't reported properly by the debugger or backtrace facility. Needless
to say, this is somewhat annoying during debugging. Here's a simple test
program that exhibits the problem:

(* test for reported character positions *)

exception Testing

let rec fact n =
if n = 1 then
raise Testing
else
n * fact(n - 1)

let foo n =
fact n + 3

let bar n =
foo n

let test () =
bar 4

let _ = test()

(* end of test *)

I compile and run this test program as follows:

# ocamlc -g test.ml
# ocamlrun -b camlprog.exe
Fatal error: exception Test.Testing
Raised at module Test, character 120
Called from module Test, character 149
Called from module Test, character 149
Called from module Test, character 149
Called from module Test, character 174
Called from module Test, character 247

The reported character positions correspond to the following places in
the file:

* 120: the 's' in the word 'else' in the function 'fact'
* 149: the 'f' in 'foo' on the 'let foo n =' line
* 174: the 'b' in 'bar' on the 'let bar n =' line
* 247: the ')' at the end of the last comment.

I suspected that because this was on Windows the LF vs CRLF problem was
the culprit, so I added the gratuitous CRs to the file and tried again.
This time I got this:

Fatal error: exception Test.Testing
Raised at module Test, character 126
Called from module Test, character 157
Called from module Test, character 157
Called from module Test, character 157
Called from module Test, character 185
Called from module Test, character 266

These correspond as follows:

* 126: the 'l' in the word 'else' in the function 'fact'
* 157: the ' ' after 'let' on the 'let foo n =' line
* 185: the 't' in 'let' on the 'let bar n =' line
* 266: the ' ' after 'test' in last comment.

The first 2 are 1 char before the previous result, the next 2 are 2
before the previous result -- not consistently off, so something is
seriously wrong here. I've tried this with both the cygwin and native
ports, and both had the same problem.

Another problem is that some stack frames seem to be dropped. As I see
it, fact is called with 7, so there should be 5 recursive calls on its
last line. Instead 3 are (trying to be) shown. Also, some of the simpler
functions don't appear to have frames. Maybe this is because of
inlining, but I wouldn't think you would want inlining with the -g
option precisely because you're trying to trace the flow according to
what you've written.

Perhaps there's something obvious that I need to do to correct my ocaml
environment, but I suspect that this is a real bug and it's biting
everyone, at least on Windows. I'm willing to help debug the problem,
but could use some pointers on where to look. I started by looking at
the lexer, but it appears to deal with line numbers, not character
positions, so I'm doubly confused.

Thanks,

Warren Harris


<title></title> Hi. I'm new to ocaml and think it's a great language. However I encountered this problem and was wondering if it was a known issue...

I've noticed that line numbers (or more precisely, character positions) aren't reported properly by the debugger or backtrace facility. Needless to say, this is somewhat annoying during debugging. Here's a simple test program that exhibits the problem:
(* test for reported character positions *)

exception Testing

let rec fact n =
if n = 1 then
raise Testing
else
n * fact(n - 1)

let foo n =
fact n + 3

let bar n =
foo n

let test () =
bar 4

let _ = test()

(* end of test *)

I compile and run this test program as follows:
# ocamlc -g test.ml
# ocamlrun -b camlprog.exe
Fatal error: exception Test.Testing
Raised at module Test, character 120
Called from module Test, character 149
Called from module Test, character 149
Called from module Test, character 149
Called from module Test, character 174
Called from module Test, character 247
The reported character positions correspond to the following places in the file:
  • 120: the 's' in the word 'else' in the function 'fact'
  • 149: the 'f' in 'foo' on the 'let foo n =' line
  • 174: the 'b' in 'bar' on the 'let bar n =' line
  • 247: the ')' at the end of the last comment.
I suspected that because this was on Windows the LF vs CRLF problem was the culprit, so I added the gratuitous CRs to the file and tried again. This time I got this:
Fatal error: exception Test.Testing
Raised at module Test, character 126
Called from module Test, character 157
Called from module Test, character 157
Called from module Test, character 157
Called from module Test, character 185
Called from module Test, character 266
These correspond as follows:
  • 126: the 'l' in the word 'else' in the function 'fact'
  • 157: the ' ' after 'let' on the 'let foo n =' line
  • 185: the 't' in 'let' on the 'let bar n =' line
  • 266: the ' ' after 'test' in last comment.
The first 2 are 1 char before the previous result, the next 2 are 2 before the previous result -- not consistently off, so something is seriously wrong here. I've tried this with both the cygwin and native ports, and both had the same problem.

Another problem is that some stack frames seem to be dropped. As I see it, fact is called with 7, so there should be 5 recursive calls on its last line. Instead 3 are (trying to be) shown. Also, some of the simpler functions don't appear to have frames. Maybe this is because of inlining, but I wouldn't think you would want inlining with the -g option precisely because you're trying to trace the flow according to what you've written.

Perhaps there's something obvious that I need to do to correct my ocaml environment, but I suspect that this is a real bug and it's biting everyone, at least on Windows. I'm willing to help debug the problem, but could use some pointers on where to look. I started by looking at the lexer, but it appears to deal with line numbers, not character positions, so I'm doubly confused.

Thanks,

Warren Harris




@vicuna

This comment has been minimized.

Copy link
Author

commented Oct 21, 2002

Comment author: administrator

Damien Doligez wrote:

  • 120: the 's' in the word 'else' in the function 'fact'
  • 149: the 'f' in 'foo' on the 'let foo n =' line
  • 174: the 'b' in 'bar' on the 'let bar n =' line
  • 247: the ')' at the end of the last comment.

That seems wrong. Since you are under Windows, I assume your text file
uses the Windows newline convention (i.e. end of line is marked by CR LF,
two characters). In this case, 120 is the end of the "raise Testing"
line, 149 is the end of the "n * fact(n - 1), etc. If your text editor
hides the CR characters from you, you will see what you describe,
but I think the character numbers given by O'Caml are accurate.

I'm using emacs which always shows CRLF (the unix convension) with ^M
characters at the end of each line. I believe the Windows convension is
simply LF. However, I do see now that I was being fooled by invisible CR
characters, and the offsets reported are correct.

At any rate, our technique of reporting the character numbers has
a few other problems, and we are trying to get rid of them by
storing and reporting line number and offset of character in the
line. Hopefully, this will make all such problems go away...

I think that would be better.

Another problem is that some stack frames seem to be dropped. As I see
it, fact is called with 7, so there should be 5 recursive calls on its

In your case, fact is called with 4, not 7, so it is normal that you
see only 3 recursive calls.

I see now. The precedence of + isn't what I expected. (Did I say I was a
beginner? :-)

last line. Instead 3 are (trying to be) shown. Also, some of the simpler
functions don't appear to have frames. Maybe this is because of
inlining, but I wouldn't think you would want inlining with the -g
option precisely because you're trying to trace the flow according to
what you've written.

You should also be aware of the tail-call optimisation: if the very
last thing that f does is to call g and return g's result, then the
program will remove f's stack frame before calling g, so a backtrace
within g will not include the stack frame of f. It would be nice to
disable this optimisation when debugging, but most programs cannot
run without it (they run out of stack space).

I'm used to that from scheme.

Thanks for your helpful response,

Warren


<title></title>

Damien Doligez wrote:
    * 120: the 's' in the word 'else' in the function 'fact'
    * 149: the 'f' in 'foo' on the 'let foo n =' line
    * 174: the 'b' in 'bar' on the 'let bar n =' line
    * 247: the ')' at the end of the last comment.
    
That seems wrong.  Since you are under Windows, I assume your text file
uses the Windows newline convention (i.e. end of line is marked by CR LF,
two characters).  In this case, 120 is the end of the "raise Testing"
line, 149 is the end of the "n * fact(n - 1), etc.  If your text editor
hides the CR characters from you, you will see what you describe,
but I think the character numbers given by O'Caml are accurate.
I'm using emacs which always shows CRLF (the unix convension) with ^M characters at the end of each line. I believe the Windows convension is simply LF. However, I do see now that I was being fooled by invisible CR characters, and the offsets reported are correct.

At any rate, our technique of reporting the character numbers has
a few other problems, and we are trying to get rid of them by
storing and reporting line number and offset of character in the
line. Hopefully, this will make all such problems go away...

I think that would be better.
  
Another problem is that some stack frames seem to be dropped. As I see 
it, fact is called with 7, so there should be 5 recursive calls on its 
    
In your case, fact is called with 4, not 7, so it is normal that you
see only 3 recursive calls.
I see now. The precedence of + isn't what I expected. (Did I say I was a beginner? :-)
  
last line. Instead 3 are (trying to be) shown. Also, some of the simpler 
functions don't appear to have frames. Maybe this is because of 
inlining, but I wouldn't think you would want inlining with the -g 
option precisely because you're trying to trace the flow according to 
what you've written.
    
You should also be aware of the tail-call optimisation: if the very
last thing that f does is to call g and return g's result, then the
program will remove f's stack frame *before* calling g, so a backtrace
within g will not include the stack frame of f.  It would be nice to
disable this optimisation when debugging, but most programs cannot
run without it (they run out of stack space).
  
I'm used to that from scheme.

Thanks for your helpful response,

Warren



@vicuna

This comment has been minimized.

Copy link
Author

commented Oct 21, 2002

Comment author: administrator

* 120: the 's' in the word 'else' in the function 'fact'
* 149: the 'f' in 'foo' on the 'let foo n =' line
* 174: the 'b' in 'bar' on the 'let bar n =' line
* 247: the ')' at the end of the last comment.

That seems wrong. Since you are under Windows, I assume your text file
uses the Windows newline convention (i.e. end of line is marked by CR LF,
two characters). In this case, 120 is the end of the "raise Testing"
line, 149 is the end of the "n * fact(n - 1), etc. If your text editor
hides the CR characters from you, you will see what you describe,
but I think the character numbers given by O'Caml are accurate.

At any rate, our technique of reporting the character numbers has
a few other problems, and we are trying to get rid of them by
storing and reporting line number and offset of character in the
line. Hopefully, this will make all such problems go away...

Another problem is that some stack frames seem to be dropped. As I see
it, fact is called with 7, so there should be 5 recursive calls on its

In your case, fact is called with 4, not 7, so it is normal that you
see only 3 recursive calls.

last line. Instead 3 are (trying to be) shown. Also, some of the simpler
functions don't appear to have frames. Maybe this is because of
inlining, but I wouldn't think you would want inlining with the -g
option precisely because you're trying to trace the flow according to
what you've written.

You should also be aware of the tail-call optimisation: if the very
last thing that f does is to call g and return g's result, then the
program will remove f's stack frame before calling g, so a backtrace
within g will not include the stack frame of f. It would be nice to
disable this optimisation when debugging, but most programs cannot
run without it (they run out of stack space).

-- Damien

@vicuna

This comment has been minimized.

Copy link
Author

commented Nov 4, 2002

Comment author: administrator

CRLF Windows issue.
fixed by the new handling of locations (3.06+15)

@vicuna vicuna closed this Nov 4, 2002

@vicuna vicuna added the bug label Mar 19, 2019

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
1 participant
You can’t perform that action at this time.