lock_lint subcommand
LockLint 工具可静态分析 ANSI C 源代码,帮助检测由于互斥锁和读取器-写入器锁使用不一致而引起的数据争用和死锁。LockLint 使用 Oracle Solaris libthread API 功能支持 ANSI C 程序员。
LockLint 有两个界面:
这些从命令行(或从脚本)输入,采用格式:
lock_lint subcommand
这些直接输入到源代码中。尽管源代码注释比子命令要少,但是它们通常比子命令更可取。
要启动 LockLint 会话,请键入:
lock_lint start
这样将启动用户可指定的子 shell,并建立相应的 LockLint 上下文。(有关更多信息,请参见下文的 start 子命令。)
要使 LockLint 分析源代码,必须首先使用 C 编译器的 -Zll 选项编译代码。然后,C 编译器将生成 LockLint 数据库文件(.ll 文件),为编译的每个 .c 文件生成一个。.ll 文件随后将通过 load 子命令装入到 LockLint 中。
要在 LockLint 会话期间查看有关任何 LockLint 子命令的快速信息,请使用 LockLint help 子命令(请参见下文)。
为了简便高效,您可以为子命令创建别名(如果 shell 允许);您还能将子命令放入脚本文件并运行该脚本。
分析装入的文件是否存在锁不一致,该问题可能会导致数据争用和死锁。此子命令可能会生成大量的输出,所以您可能要将输出重定向到文件。此指令只能针对保存的每种状态运行一次(请参见 save)。
分析完成后,您仍会在 "vars" 和 "order" 子命令的输出中发现更多潜在问题。例如,命令
lock_lint vars -h | fgrep *
将显示未受任何锁妥善保护的变量。
为 LockLint 提供关于如何使用锁的断言。分析期间,LockLint 会报告这些断言的任何违规。
声明关于程序中锁、函数和变量的各种属性。
列出不允许的调用序列,如使用 disallow 子命令所指定。
要退出 LockLint,请使用您正在使用的 shell 的退出命令。由 lock_lint start 命令启动的子 shell 退出时,LockLint 即会退出。
列出由通过装入子命令装入的 .ll 文件表示的源代码文件。
列出关于装入的文件中所用函数指针的信息。
列出关于装入的文件中定义和/或调用的函数的信息。
未指定任何主题的 help 子命令可提供一个子命令列表,其中包含相应的选项和一些常规帮助信息。有关子命令的详细帮助可通过以下语法指定:
lock_lint help first word of subcommand
还提供关于以下关键字的帮助:
condvars inversions names example limitations overview exit locking shell ifdef makefile shell
告知 LockLint 从分析中排除某些函数和变量。可使用 "in func ..." 子句将这种排除限制到特定函数;否则,排除将应用于所有函数。
装入指定的 .ll 文件。扩展名可省略,但是如果指定了扩展名,它必须是 .ll。允许使用绝对路径和相对路径。以下内容合法(取决于 shell 的功能):
lock_lint load *.ll lock_lint load ../foo/abcdef{1,2} lock_lint load `find . -name ll
列出关于已装入文件的锁的信息。请注意,仅显示实际用于锁操作例程中的那些变量;不显示只是简单地声明但从未操作的锁。
列出带有指定标记的结构的成员,每行一个。对于未分配标记的结构,使用 "file@line" 表示法(例如 "x.c@29"),其中文件和行号是结构声明的源位置。
列出关于分析的代码获取锁的顺序的信息。只有分析完成后才能运行。
列出通过已装入文件中的函数指针进行的调用。
允许对 disallow 子命令破例。
列出重新允许的调用序列,如使用 reallow 子命令所指定。
弹出保存的状态堆栈,将 LockLint 恢复到保存的状态堆栈顶部的状态。将输出与该状态关联的描述。然后以相同的描述再次保存该状态(以便重新恢复/刷新)。
弹出保存的状态堆栈,将 LockLint 恢复到保存的状态堆栈顶部的状态。将输出与该状态关联的描述。
保存堆栈上工具的当前状态。指定的描述将附着于这种状态。保存的状态构成 LIFO(Last-In-First-Out,后进先出)堆栈,所以保存的最后一种状态将最先恢复。
列出通过 save 子命令在保存的堆栈上保存的状态的描述。描述从上到下显示,第一条描述是最近保存的尚未恢复的状态。最后一条描述是最早保存的尚未恢复的状态。
启动 LockLint 会话。在使用其他任何 LockLint 子命令之前,必须启动 LockLint 会话。缺省情况下,start 子命令会建立 LockLint 上下文,并在此上下文中为用户启动子 shell,如通过 $SHELL 所指定。导出到子 shell 的唯一的 LockLint 上下文是 LL_CONTEXT 环境变量。LL_CONTEXT 包含用于维护 LockLint 会话的临时文件目录的路径。
列出指定的名称在已装入文件中可能指的各种对象。例如,根据上下文,"foo" 可能是指变量 "x.c:func1/foo" 和函数 y.c:foo。
撤消关于保护指定变量的锁的任何断言。请注意,无法删除关于保护函数的锁的断言。
列出关于已装入文件的变量的信息。请注意,仅显示实际*使用*的那些变量;不显示只是在程序中简单地声明但从未访问的变量。
告知 LockLint,到达代码中的这一点时,执行此测试的线程不得保持任何锁。分析期间会报告违规行为。
告知 LockLint,到达代码中的这一点时,其他任何线程都不得与运行此代码的线程竞争。分析期间会报告违规行为(根据某些附注样式的断言提供的信息)。
如果执行的线程未按所述保持锁,会报告一个错误。
前两个注释告知 LockLint,只要访问指定的数据就应该保持锁。
第三个注释 SCHEME_PROTECTS_DATA 描述如何保护未受互斥锁或读取器/写入器锁保护的数据。为方案提供的描述只是文本。
告知 LockLint,数据只能读取而不能写入。
告知 LockLint,在未保持保护锁的情况下,可读取指定的数据。
告知 LockLint,读取器/写入器锁与一组其他锁之间存在层次关系。
告知 LockLint,函数对指定的锁有指定的副作用-即,函数在退出时会故意将锁置于不同于函数输入时的状态。对于这些注释中的最后两个,副作用不是关于锁,而是关于并发性的状态。
第一个注释告知 LockLint,在代码中这一点后面,存在的其他线程可能尝试访问与此线程将访问的数据相同的数据。第二个函数指定不再是这种情况,要么是没有其他线程正在运行,要么是正在运行的任何线程都不会访问此线程将访问的数据。
告知 LockLint,无法到达代码中的特定点,因此 LockLint 应该忽略在该点保持锁的条件。锁顺序
指定获取锁的顺序。
告知 LockLint,由指定表达式表示的变量对其他线程是否可见-即,其他线程是否可以访问这些变量。
告知 LockLint,此函数假定由指定表达式表示的变量受保护-即,为每个变量保持相应的锁;或者这些变量对其他线程不可见;或者进行调用时没有竞争性线程。
包含上下文目录的路径
用作缺省 shell
用作缺省临时目录路径
有关完整的 Oracle Solaris Studio 文档,请访问 http://www.oracle.com/technetwork/server-storage/solarisstudio/documentation
目前,LockLint 不会就源文件检查 .ll 是否已过期。
来自 cc 的 LockLint 数据库文件
lock_lint 命令
LockLint 引擎
帮助文件的目录
关于 cmd 的帮助主题
lock_lint 命令的退出状态如下所示:
正常
系统错误
用户导致的错误,例如错误选项或未定义的名称
多种类型的错误
Lock_lint 检测到错误:可能发现断言潜在数据争用或死锁违规行为、数据引用未受保护等等。
许可错误