相关疑难解决方法(0)

什么是LD_PRELOAD技巧?

我最近在proggit看到了它的引用,并且(截至目前)它没有被解释.

我怀疑可能是它,但我不确定.

c linux environment-variables

321
推荐指数
6
解决办法
29万
查看次数

重新定义标准名称是不确定的行为?

很容易理解这样的代码是如何工作的:

#include <string.h>

#define strcmp my_strcmp

int my_strcmp(const char *, const char *)

...
strcmp(str1, str2);
...
Run Code Online (Sandbox Code Playgroud)

但这个问题是这在技术上是否正确.

从C11:

7.1.3.1(关于保留名称):

...

  • 如果包含任何相关标头,则保留以下任何子条款中的每个宏名称(包括未来的库方向)以供指定使用; 除非另有明确说明(见7.1.4).
  • 在以下任何子条款(包括未来的库方向)和errno中具有外部链接的所有标识符始终保留用作具有外部链接的标识符.184)
  • 在以下任何子条款中列出的具有文件范围的每个标识符(包括未来的库方向)保留用作宏名称,并且如果包括任何相关联的标题,则用作具有相同名称空间的文件范围的标识符.

184具有外部链接的保留标识符列表包括math_errhandling,setjmp,va_copy和va_end.

所以这意味着这strcmp是一个保留字,因为string.h包括在内.

7.1.3.2:

...如果程序在保留它的上下文中声明或定义标识符(7.1.4允许的除外),或者将保留标识符定义为宏名称,则行为未定义.

现在这似乎说重新定义strcmp是未定义的行为,除了它在7.1.4中以某种方式允许.

7.1.4可能相关的内容是:

7.1.4.1:

...标头中声明的任何函数可以另外实现为标头中定义的类函数宏,因此如果在包含标头时显式声明了库函数,则可以使用下面显示的技术之一来确保声明不受这种宏的影响.通过将函数的名称括在括号中,可以在本地抑制函数的任何宏定义,因为该名称后面没有左括号,后面表示宏函数名称的扩展.出于相同的语法原因,即使它也被定义为宏,也允许获取库函数的地址.185)使用#undef删除任何宏定义也将确保引用实际函数....

185这意味着实现应为每个库函数提供实际函数,即使它还为该函数提供宏.

7.1.4.2:

如果可以在不引用标头中定义的任何类型的情况下声明库函数,则允许声明该函数并使用它而不包括其关联的标头.

其余条款无关紧要.我没有看到7.1.3.2指的是"7.1.4允许的",除了与函数相同的头中的库函数的定义,即标准头,作为宏.

总之,上面的代码是技术上未定义的行为吗?如果string.h不包括在内怎么样?

c language-lawyer

12
推荐指数
2
解决办法
766
查看次数

在编译时在所有.c源文件中包含#define

我需要#define在大约300个.c文件的顶部包含一个.我宁愿不更改代码,因为它是开源代码,但如果我必须,我将只编写一个脚本来修改所有文件.有没有办法#define在编译期间使用gcc在每个源文件的顶部添加一个或头文件include?这#define是:

#define malloc MYmalloc
Run Code Online (Sandbox Code Playgroud)

c gcc

8
推荐指数
2
解决办法
8428
查看次数

LLVM中的参数转发

我需要一些关于向被调用方"转发"参数的建议(在LLVM-IR中).

假设我有一个在模块F所有其他函数开头调用的函数.从F我需要访问(读取)传递给其直接调用者的参数.

现在要做到这一点,我在结构中的调用者中包含所有参数,并将i8*指针传递给结构F,以及一个标识符,告诉调用哪个调用者F.F然后有一个巨大的开关,分支到适当的拆箱代码.必须这样做,因为模块中的函数具有不同的签名(不同的参数/返回值计数和类型;甚至不同的调用约定),但它显然是次优的(从性能和代码大小的角度来看)因为我需要在堆栈上分配结构,复制其中的参数,传递一个额外的指针F,然后执行拆箱.

我想知道是否有更好的方法来做到这一点,即从函数访问其直接调用者的堆栈帧的方法(知道,由于标识符,调用函数的调用者),或者更一般地,任意在其直接调用者中定义的值.有什么建议?

注意:我正在研究的重点是拥有完成所有这一切的单一功能F; 拆分/内联/专门化/模板化F不是一种选择.


澄清一下,假设我们有以下功能FuncAFuncB(注意:以下只是伪C代码,永远记住我们在谈论LLVM-IR!)

Type1 FuncA(Type2 ArgA1) {
  F();
  // ...
}

Type3 FuncB(Type4 ArgB1, Type5 ArgB2, Type6 ArgB3) {
  F();
  // ...
}
Run Code Online (Sandbox Code Playgroud)

我需要的是一个有效的方法F来执行以下功能:

void F() {
  switch (caller) {
    case FuncA:
      // do something with ArgA1
      break;
    case FuncB:
      // do something with …
Run Code Online (Sandbox Code Playgroud)

performance callstack function llvm argument-passing

7
推荐指数
1
解决办法
324
查看次数

如何让OS X malloc在失败时自动中止?

Matasano博客呼吁"检查的返回值malloc()"一"C程序反成语."相反malloc()应该自动调用abort()如果失败了你.这个论点是,因为如果malloc()失败,你通常会想要中止程序,这应该是默认行为,而不是你必须费力地键入的东西 - 或者可能忘记输入!-every time.

没有深入了解这个想法的优点,最简单的方法是什么?我正在寻找能够自动检测其他库函数的内存分配失败的东西asprintf().便携式解决方案会很精彩,但我也会对特定于mac的东西感到满意.


总结下面的最佳答案:

Mac运行时解决方案

MallocErrorAbort=1在运行程序之前设置环境变量.自动适用于所有内存分配功能.

Mac/linux运行时解决方案

使用动态库填充malloc()程序在运行时使用LD_PRELOAD或加载自定义包装器DYLD_INSERT_LIBRARIES.你可能会想包装calloc(),realloc(),温度.同样.

Mac/linux编译解决方案

定义您自己的malloc()free()功能,并使用dyld(RTLD_NEXT, "malloc") 此处所示访问系统版本.同样,你可能会想包装calloc(),realloc(),温度.同样.

#include <dlfcn.h>
#include <stdio.h>
#include <stdlib.h>

void *(*system_malloc)(size_t) = NULL;

void* malloc(size_t bytes) {
    if (system_malloc == NULL) {
        system_malloc = dlsym(RTLD_NEXT, "malloc");
    }
    void* ret = system_malloc(bytes);
    if …
Run Code Online (Sandbox Code Playgroud)

c malloc macos

6
推荐指数
1
解决办法
1853
查看次数

如何计算内存分配的数量

我想计算程序中内存分配调用(malloc、calloc、new ...)的数量。该程序积极使用 STL 容器。主要目的是计算所有这些容器内的内存分配。稍后我将使用这些信息来优化性能。我的程序是用 C++ 编写的,在 Linux 下运行。有什么工具可以做到吗?

c++ linux memory-management

6
推荐指数
1
解决办法
4113
查看次数

在 FreeRTOS 中重新定义 malloc 以实现线程安全

我可以做这样的事情吗:

#ifdef FREERTOS

#define malloc(size) pvPortMalloc(size)
#define free(ptr) pvPortFree(ptr)

#endif
Run Code Online (Sandbox Code Playgroud)

并期望它总是调用pvPortMalloc()而不是malloc()?

另外,把它放在之前/之后会有什么区别#include <stdlib.h>

我有一些代码想要在 FreeRTOS 内和外运行,我想将所有调用替换为使用 FreeRTOS 时的malloc()调用pvPortMalloc()

c malloc std freertos c-preprocessor

5
推荐指数
1
解决办法
7305
查看次数

在 Linux 上跟踪 libc 和系统调用函数调用?

我在 Linux 上有一个 C++ 应用程序。在程序的整个执行过程中,我如何才能看到对函数的库调用malloc(),然后是系统调用,例如sbrk()等等?

我希望这能显示哪些 libc 函数发生并负责后续的 Linux 系统调用。

注意:我不想拦截任何函数调用,只是记录哪些 C 库函数调用了哪些系统调用。

c c++ unix linux

4
推荐指数
2
解决办法
3978
查看次数

如何通过代码替换默认的malloc

我想替换默认的 malloc 并添加一些统计信息以及泄漏检测和 malloc 函数的其他行为。我见过一些其他的实现,比如 gperftool 和 jemlloc。他们可以通过链接静态库来替换默认的 malloc。他们怎么能这么做呢?我想像这样实现我的自定义 malloc 函数。

malloc

3
推荐指数
1
解决办法
4072
查看次数