OCaml本机代码带字符串的堆栈溢出

OCaml本机代码带字符串的堆栈溢出,ocaml,stack-overflow,native,Ocaml,Stack Overflow,Native,我正在从事一个OCaml项目,它似乎在计算效率方面存在一些问题。在试图找到瓶颈的同时,出于好奇,我尝试编译为本机代码而不是字节码,不知道运行时间会有多大差异 事实证明,本机代码会引发堆栈溢出。我尝试使用OCAMLRUNPARAM=b执行,但没有获得有关stacktrace的太多信息: Fatal error: exception Stack overflow Raised at file "map.ml", line 122, characters 10-25 Called from file

我正在从事一个OCaml项目,它似乎在计算效率方面存在一些问题。在试图找到瓶颈的同时,出于好奇,我尝试编译为本机代码而不是字节码,不知道运行时间会有多大差异

事实证明,本机代码会引发堆栈溢出。我尝试使用OCAMLRUNPARAM=b执行,但没有获得有关stacktrace的太多信息:

Fatal error: exception Stack overflow
Raised at file "map.ml", line 122, characters 10-25
Called from file "str.ml", line 259, characters 6-29
没别的了。我不知道我的代码中是什么原因导致了它。此外,我的程序不使用大字符串,所以我不明白为什么
Str
会出现堆栈溢出


是否可以调整一些参数来调查问题?

溢出是由嵌套函数调用的深度引起的,而不是由涉及的字符串长度引起的

除此之外,您没有提供足够的信息来提供帮助。您的项目中是否有名为“map.ml”的文件?122号线周围是什么样子


如果项目中没有名为“map.ml”的文件,则可能会看到标准库中函数的非尾部递归行为。特别是,我想问题在于
Str
模块中正则表达式的编译。是否有异常大的正则表达式?

溢出是由嵌套函数调用的深度引起的,而不是由所涉及字符串的长度引起的

除此之外,您没有提供足够的信息来提供帮助。您的项目中是否有名为“map.ml”的文件?122号线周围是什么样子


如果项目中没有名为“map.ml”的文件,则可能会看到标准库中函数的非尾部递归行为。特别是,我想问题在于
Str
模块中正则表达式的编译。您有任何异常大的正则表达式吗?

如果您使用
-g
构建代码(例如,通过在
\u标记中添加
true:debug
,如果您使用ocamlbuild),您将在stacktrace中获得代码的调试信息(而不仅仅是标准库)。这将为您提供有关问题的更多信息。

如果您使用
-g
构建代码(例如,如果您使用ocamlbuild,则通过在
\u标记中添加
true:debug
),则stacktrace中将包含代码的调试信息(而不仅仅是标准库)。这将为您提供有关问题的更多信息。

OCAMLRUNPARAM
控制OCaml解释器的堆栈大小,而与由操作系统加载程序运行的编译代码无关,因此您需要使用操作系统来控制堆栈的大小。提示,在UNIX中,可以使用
ulimit
设置堆栈大小

确定堆栈溢出源的问题是,堆栈的默认大小允许如此大的跟踪,以至于默认堆栈溢出打印机无法将其打印到源,因此技巧实际上是限制堆栈大小,请参阅我的另一篇文章中的完整解释

当然,此外,您还需要(i)使用
-g
选项构建源代码,以及(ii)启用堆栈跟踪(取决于编译器版本和使用的库,默认情况下可能启用也可能不启用)。前者特定于构建系统,后者可以通过设置
OCAMLRUNPARAM=b
环境变量(适用于字节码和本机代码)或在应用程序开始时在源代码中显式调用
Printexc.record\u backtrace true
来完成


这些是一般性的注释。但是,在您的情况下,map调用很可能导致堆栈溢出。在OCAML标准库中,<代码>列表.map < /C>不是尾部递归的,因此您可以考虑用<代码> List.Rv(List.ReVixMax xs)< /C> >或仅与<代码>列表替换.<代码> List.map xs <代码>。p>
OCAMLRUNPARAM
控制OCaml解释器的堆栈大小,与操作系统加载程序运行的编译代码无关,因此需要使用操作系统控制堆栈大小。提示,在UNIX中,可以使用
ulimit
设置堆栈大小

确定堆栈溢出源的问题是,堆栈的默认大小允许如此大的跟踪,以至于默认堆栈溢出打印机无法将其打印到源,因此技巧实际上是限制堆栈大小,请参阅我的另一篇文章中的完整解释

当然,此外,您还需要(i)使用
-g
选项构建源代码,以及(ii)启用堆栈跟踪(取决于编译器版本和使用的库,默认情况下可能启用也可能不启用)。前者特定于构建系统,后者可以通过设置
OCAMLRUNPARAM=b
环境变量(适用于字节码和本机代码)或在应用程序开始时在源代码中显式调用
Printexc.record\u backtrace true
来完成


这些是一般性的注释。但是,在您的情况下,map调用很可能导致堆栈溢出。在OCAML标准库中,<代码>列表.map < /C>不是尾部递归的,因此您可以考虑用<代码> List.Rv(List.ReVixMax xs)< /C> >或仅与<代码>列表替换.<代码> List.map xs <代码>。p> 是的,我不是指字符串长度“本身”。没有map.ml文件,这个调用在Str中:我假设它是一个非尾部递归函数,正如您所说的。我有一个简单的正则表达式来检查字符串是否是一个有效的整数,我现在将其删除,并在be处使用一个更大的正则表达式(没有那么复杂)