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

segfault with Set.Make on Intel Macs #4282

Closed
vicuna opened this issue May 17, 2007 · 2 comments
Closed

segfault with Set.Make on Intel Macs #4282

vicuna opened this issue May 17, 2007 · 2 comments
Labels

Comments

@vicuna
Copy link

vicuna commented May 17, 2007

Original bug ID: 4282
Reporter: acone
Status: closed (set by @xavierleroy on 2007-11-10T11:36:18Z)
Resolution: not a bug
Priority: normal
Severity: crash
Version: 3.09.3
Category: ~DO NOT USE (was: OCaml general)
Monitored by: ertai

Bug description

The code below segfaults on Mac OS 10.4.9 on Intel using ocamlopt 3.09.3.

The input to the program should be a newline-delimited list of strings of length 12 over the alphabet {A,C,G,T}, delivered on stdin. For example:
--begin stdin to attached program
ACCGGTAAATAC
ACCGGTAAATCC
ACCGGTAAATCT
ACCGGTAAATGT
ACCGGTAACACC
ACCGGTAACAGA
ACCGGTAACCAT
ACCGGTAACGTA
ACCGGTAACTAA
ACCGGTAACTAC
ACCGGTAACTTG
--end stdin

It works fine on an input of 250,000 strings, but it fails on 300,000.

Additional information

open Printf
module Int64Set = Set.Make(struct type t = Int64.t let compare = Int64.compare end)

let base_of_int64 int64 =
match int64 with
0L -> 'A'
| 1L -> 'C'
| 2L -> 'G'
| 3L -> 'T'
| _ -> failwith "shouldn't get here"

let int64_of_base b =
match b with
'A' -> 0L
| 'C' -> 1L
| 'G' -> 2L
| 'T' -> 3L
| _ -> 0L

let int64_of_seq seq =
let len = String.length seq in
let out = ref 0L in
for i = 0 to len-1 do
out := Int64.shift_left !out 2;
out := Int64.logor !out (int64_of_base seq.[i])

done;
!out

let set_of_file ic =
let rec loop set =
try
let str = input_line ic in
loop(Int64Set.add (int64_of_seq str) set)
with End_of_file -> set
in
loop Int64Set.empty

let seq_of_int64 len int64 =
let int64 = ref int64 in
let seq = String.create len in
for i=len-1 downto 0 do
seq.[i] <- base_of_int64 (Int64.logand 0x3L !int64);
int64 := Int64.shift_right !int64 2
done;
seq

let _ =
let s = set_of_file stdin in
Int64Set.iter
(fun int64 -> printf "%s\n" (seq_of_int64 12 int64))
s

@vicuna
Copy link
Author

vicuna commented May 29, 2007

Comment author: Christophe

It must be a stack overflow...
your function "loop" in "set_of_file" is not tail recursive due to "try with". Try that :

let set_of_file ic =
let str = ref "" in
let rec loop set =
if (try
str := input_line ic; true
with End_of_file -> false) then
loop(Int64Set.add (int64_of_seq str) !set)
else set
in
loop Int64Set.empty

@vicuna
Copy link
Author

vicuna commented Nov 10, 2007

Comment author: @xavierleroy

This is indeed a stack overflow. With 3.10, it is properly reported as a Stack_overflow exception.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant