Skip to content

Commit 7ad6ba8

Browse files
committed
fix: Isolate & Workaround the Stack_overflow raised by 'Experiment'
* Add some (commented-out) debug code facilities; * Add some TODO/FIXME/XXX remarks; * Workaround the issue by ignoring the 'exercise.descr' string in editor_lib.ml (otherwise its encoding-then-*decoding* fails)
1 parent 1b7edfb commit 7ad6ba8

File tree

3 files changed

+33
-13
lines changed

3 files changed

+33
-13
lines changed

src/app/learnocaml_exercise_main.ml

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -90,18 +90,24 @@ let () =
9090

9191
(* if we came from a true exercise we search in the server.
9292
In the other case we get the exercise information from the Local storage *)
93+
(* FIXME: for debug purposes; to be removed:
94+
let ok str = lwt_alert ~title:"TEST1" ~buttons:["OK", (fun () -> Lwt.return_unit)]
95+
[ H.p [H.txt (String.trim str)] ] in *)
9396
let exercise_fetch = match idEditor id with
9497
| false -> token >>= fun token ->
9598
retrieve (Learnocaml_api.Exercise (token, id))
9699

97100
| true -> let proper_id = String.sub id 1 ((String.length id)-1) in
98-
Lwt.return ((Editor_lib.get_editor_state proper_id).Editor.metadata,
99-
(Editor_lib.exo_creator proper_id ),
100-
None)
101+
let state = Editor_lib.get_editor_state proper_id in
102+
(* FIXME: for debug purposes; to be removed:
103+
ok state.Editor.metadata.title >>= fun () -> *)
104+
let exo = Editor_lib.exo_creator proper_id in
105+
Lwt.return (state.Editor.metadata, exo, None)
101106
in
102107

103108
let after_init top =
104109
exercise_fetch >>= fun (_meta, exo, _deadline) ->
110+
105111
begin match Learnocaml_exercise.(decipher File.prelude exo) with
106112
| "" -> Lwt.return true
107113
| prelude ->

src/editor/editor_lib.ml

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -293,18 +293,21 @@ let genTemplate top ?(on_err = fun () -> ()) sol =
293293
else Lwt.return (let () = on_err () in "")
294294
295295
(* ---- create an exo ------------------------------------------------------- *)
296+
296297
let exo_creator proper_id =
297298
let exercise = (get_editor_state proper_id).exercise in
298299
let read_field field =
299300
match field with
300-
| "id"-> Some exercise.id
301+
| "id" -> Some exercise.id (* XXX = proper_id *)
301302
| "prelude.ml" -> Some exercise.prelude
302303
| "template.ml" -> Some exercise.template
303-
| "descr.md" -> Some exercise.descr
304+
| "descr.md" -> (* FIXME: SHOULD BE 'Some exercise.descr' *)
305+
Some "<p>Note: question export disabled for the time being; otherwise descrs_from_string raises a Stack_overflow on strings of size 14000.</p>"
304306
| "prepare.ml" -> Some exercise.prepare
305-
| "test.ml" -> Some exercise.test
306307
| "solution.ml" -> Some exercise.solution
307-
| "max_score" -> Some (string_of_int exercise.max_score)
308+
| "test.ml" -> Some exercise.test
309+
| "max_score.txt" -> Some (string_of_int exercise.max_score)
310+
| "depend.txt" -> None (* TODO: Add support *)
308311
| _ -> None
309312
in
310313
Learnocaml_exercise.read

src/repo/learnocaml_exercise.ml

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ type t =
2121
dependencies : string list;
2222
}
2323

24+
(* XXX: a change to this type may require another change in editor_lib.ml *)
25+
2426
let encoding =
2527
let open Json_encoding in
2628
conv
@@ -192,7 +194,7 @@ module File = struct
192194

193195
let depend =
194196
{ key = "depend.txt" ; ciphered = false ;
195-
decode = (fun v -> Some v) ;
197+
decode = (fun v -> Some v) ; (* XXX should this produce None sometimes? *)
196198
encode = (function
197199
| None -> "" (* no `depend` ~ empty `depend` *)
198200
| Some txt -> txt) ;
@@ -289,7 +291,7 @@ module File = struct
289291
* return ()
290292
* with _ -> return ()
291293
* in *)
292-
let descrs = ref [] in
294+
let descrs : (string option * string) list ref = ref [] in
293295
let rec read_descr lang = function
294296
| [] ->
295297
(* If there are no extensions to try, we just give up. *)
@@ -314,23 +316,32 @@ module File = struct
314316
| Some raw ->
315317
(* If it does, we apply the function, add the
316318
description to [!descrs] and return. *)
317-
descrs := (lang, f raw) :: !descrs;
319+
descrs := (lang, f raw) :: !descrs ;
318320
return ()
319321
in
320322
let markdown_to_html md =
321323
Omd.(md |> of_string |> to_html)
322324
in
323325
let read_descrs () =
324326
let langs = [] in
327+
(* XXX: Really [] ? *)
325328
let exts = [
326329
(Filename.extension descr.key, fun h -> h) ;
327330
(".md", markdown_to_html)
328331
] in
329332
join (read_descr None exts :: List.map (fun l -> read_descr (Some l) exts) langs)
330333
>>= fun () ->
331-
ex := set descr
332-
(List.map (function (None, v) -> "", v | (Some l, v) -> l, v) !descrs)
333-
!ex;
334+
let res = (List.map (function (None, v) -> "", v | (Some l, v) -> l, v) !descrs) in
335+
(* let res' = descr.encode res in
336+
let stack_overflow = descr.decode res' in () *)
337+
338+
(* Also reproducible with:
339+
let html = (* markdown_to_html md (* length = 13711 *) *)
340+
String.init 14000 (fun n -> if n mod 2 = 0 then 'A' else ' ') in
341+
let res' = descrs_to_string [("", html)] (* length = 13857 *) in
342+
let stack_overflow = descrs_from_string res' in () *)
343+
344+
ex := set descr res !ex;
334345
return ()
335346
in
336347
join

0 commit comments

Comments
 (0)