当我们使用gdb调试程序时,我们通常会看到在libc(glibc?)中定义了奇怪名称的函数.我的问题是:
定义宏有很多地方.当宏在我们自己的项目中定义时,很容易找到它们的定义位置.但是当我尝试学习一些着名的开源项目时,我经常被这个问题所困扰:在哪里找到宏的来源,如果我不能得到它的定义,我将无法理解它们中的一些(例如其中一些可以猜到他们的名字).例如,来自apache的一些声明:
#if defined(__osf__) && defined(__alpha),
#elif defined(__NSIG)
Run Code Online (Sandbox Code Playgroud)
据我所知,我知道宏有一些可能的起源地:
我有一些问题需要咨询:
grep或find实用程序__strange___通过梳理整个机器(cd /;grep __strange___ -r)无法找到一个宏,这意味着什么?感谢您告诉原则和方法来区分它们,并找到它们的来源!
每个人,当在gdb中使用"next"指令时,我发现每行源代码显示两次-----我很确定,这些代码不在任何循环中.这是现象:
(gdb) frame
#0 ap_get_client_block (r=0x8560d48,
buffer=0xb68501b7 "<?xml version=\"1.0\" encoding=\"utf-8\"?><Root><OperCode>SMS101</OperCode><AppId>SMSMsgFilterReq</AppId><Req><UserMobile>13925237429</UserMobile><SendMsg>abc?34¨?23a?07\214?21??237?11??215?10°?214?27??227?07\214??,hao"..., bufsiz=81920) at http_filters.c:1540
1540 if (r->remaining < 0 || (!r->read_chunked && r->remaining == 0)) {
(gdb) n
1544 bb = apr_brigade_create(r->pool, r->connection->bucket_alloc);
(gdb)
1545 if (bb == NULL) {
(gdb)
1544 bb = apr_brigade_create(r->pool, r->connection->bucket_alloc);
(gdb)
1545 if (bb == NULL) {
Run Code Online (Sandbox Code Playgroud)
----- 1544,1545行没有任何循环,但是他们重复了.愿任何人开导我吗?
我想知道:char*cs = .....;如果cs指向内存块但是没有'\ 0',那么strlen()和printf("%s",cs)会发生什么?我写这些线:
char s2[3] = {'a','a','a'};
printf("str is %s,length is %d",s2,strlen(s2));
Run Code Online (Sandbox Code Playgroud)
我得到结果:"aaa","3",但我认为这个结果是因为'\ 0'(或0字节)恰好位于s2 + 3位置.如何制作一个非空终止的c字符串?strlen和其他c字符串函数严重依赖于'\ 0'字节,如果没有'\ 0',我只想更深入,更好地了解这条规则.
ps:通过研究SO上的帖子来激发我的好奇心. 如何将const char*转换为std :: string 以及该帖子中的这些单词:"这实际上比它看起来更棘手,因为除非字符串实际上是nul终止,否则你不能调用strlen."
下面是过程a和b,这两者都是多线程的.
a叉子b和b立即执行一个新程序;a dups和freopens stderr到日志文件(a是defacto apache的httpd2.22)b继承了打开的stderr a.(我适应apache httpd的,b是我的程序),并b使用fprintf(stderr....)了日志记录a,b共享同一个文件进行日志记录a,b写日志我发现一些log msg是交错的,并且有一点log msg丢失了.
同一个文件中的两个编写者是否可以隐含地互相锁定?
更重要的问题是:如果我们fprintf只在一个单线程中使用多线程进程,那么fprintf线程是否安全,即一次调用fprintf不会干扰fprintf另一个线程中的另一个调用?很多文章都这么说,但这并不容易确保自己,所以我在这里寻求帮助.
答:复制fd的代码是这样的:
......
rv = apr_file_dup2(stderr_log, s_main->error_log, stderr_p);//dup the stderr to the logfile
apr_file_close(s_main->error_log);//here ,2 fd point to the same file description,so close one of
Run Code Online (Sandbox Code Playgroud)
然后
B:apache它自己用这种方式记录: …
当我man -a close,第一页是POSIX手册页,然后我有一个close(2),(2表示系统api或内核函数).这意味着至少有2个版本close().
例如,像这样的代码片段:
int fd = open("xxx");
........
close(fd); -----here, which version is called,
is that one from the POSIX lib, or the raw system API?
Run Code Online (Sandbox Code Playgroud)
PS:因此我的linux系统包含一个POSIX包装器,用于大多数系统API调用,如何辨别我的代码是调用POSIX lib还是原始系统API?