我一直在挖掘Linux内核的某些部分,发现这样的调用:
if (unlikely(fd < 0))
{
/* Do something */
}
Run Code Online (Sandbox Code Playgroud)
要么
if (likely(!err))
{
/* Do something */
}
Run Code Online (Sandbox Code Playgroud)
我找到了它们的定义:
#define likely(x) __builtin_expect((x),1)
#define unlikely(x) __builtin_expect((x),0)
Run Code Online (Sandbox Code Playgroud)
我知道它们是为了优化,但它们是如何工作的?使用它们可以预期性能/尺寸减少多少?至少在瓶颈代码中(当然在用户空间中)是否值得麻烦(并且可能失去可移植性).
目前我正在做一些从bash执行的单元测试.单元测试在bash脚本中初始化,执行和清理.该脚本通常包含init(),execute()和cleanup()函数.但它们不是强制性的.我想测试它们是否定义.
我之前通过greping和seding来源做了这个,但它似乎错了.有没有更优雅的方式来做到这一点?
编辑:以下代码片段就像一个魅力:
fn_exists()
{
LC_ALL=C type $1 | grep -q 'shell function'
}
Run Code Online (Sandbox Code Playgroud) 我目前正在研究一些日志代码,它们应该 - 除其他外 - 打印有关调用函数的信息.这应该相对容易,标准C++有一个type_info
类.它包含typeid'd类/函数/ etc的名称.但它被破坏了.它不是很有用.即typeid(std::vector<int>).name()
回归St6vectorIiSaIiEE
.
有没有办法从中产生有用的东西?就像std::vector<int>
上面的例子一样.如果它只适用于非模板类,那也没关系.
该解决方案应该适用于gcc,但如果我可以移植它会更好.这是为了记录所以它不是那么重要,它不能被关闭,但它应该有助于调试.
标准方式如下:
if (ptrace(PTRACE_TRACEME, 0, NULL, 0) == -1)
printf("traced!\n");
Run Code Online (Sandbox Code Playgroud)
在这种情况下,如果跟踪当前进程(即使用gdb运行或附加到它),ptrace将返回错误.
但是这有一个严重的问题:如果调用成功返回,gdb可能以后不会附加到它.这是一个问题,因为我没有尝试实现反调试的东西.我的目的是在满足转义时发出'int 3'(即断言失败)并且gdb正在运行(否则我得到一个停止应用程序的SIGTRAP).
每次禁用SIGTRAP并发出'int 3'都不是一个很好的解决方案,因为我正在测试的应用程序可能正在使用SIGTRAP用于其他目的(在这种情况下我还是搞砸了,所以它没关系,但它是事情的原理:))
谢谢
我有以下问题:当我使用backtrace(3)函数在C中获得回溯时,返回的符号可以使用dwarf库和dladdr(3)轻松确定函数的名称.
问题是,如果我有一个简单的函数指针(例如通过传递它和函数),dladdr + dwarf函数就无济于事.似乎指针与backtrace(3)返回的指针不同(这并不奇怪,因为回溯直接从堆栈中获取这些函数指针).
我的问题是,是否有一些解决这些名称的方法?另外,我想确切地知道两个指针之间的区别.
谢谢!
更新:
指针之间的区别是非常重要的:
我得到的回溯是:0x8048ca4
直接指针版本:0x3ba838
在我看来,第二个需要一个偏移量.
我正在寻找一个可以让我用标准运算符(*, - ,*,/等)操作函数的库.
让我们假设你有一个功能f(x) = x ** 2
和g(x) = x + 2
.我希望能写f * g
,并得到一个新的算符就是essentialy x ** 2 * (x + 2)
或f(g)
并获得(x + 2) ** 2
.
我知道这不是很难实现,你只需要创建一个Functor
类并重载它的__call__
功能,但我希望有一个第三方库.
我不是想把它用于任何重量级的学习.谢谢您的帮助.