周末在家收拾东西,找到一本刚入职时记的笔记,重新读一遍记录部分内容方便查阅。
获取下标为n的元素地址
当时记录在笔记本上旁边有个大大的问号,为何不使用下标形式呢?
#include <stdio.h>
//获取下标为n的元素地址
#define ELEM_PTR(base,n,esize) ((void *)(((char *)base + n*esize)))
int main()
{
int arr[] = {1,2,3,4,5,6,7,8,9,10};
printf("address of fifth elem = %p.\n",ELEM_PTR(arr,5,4));
printf("fifth elem = %d.\n",*(int *)ELEM_PTR(arr,5,4));
return 0;
}
运行结果:
[root c++]#./a.out
address of fifth elem = 0x7ffc45463124.
fifth elem = 6.
查看linux系统是32位 64位
使用命令lscpu可以看到系统架构 x86_64,小端方式 双核 6代等信息。
[root c++]#lscpu
Architecture: x86_64
CPU op-mode(s): 32-bit, 64-bit
Byte Order: Little Endian
CPU(s): 2
On-line CPU(s) list: 0,1
Thread(s) per core: 1
Core(s) per socket: 2
Socket(s): 1
NUMA node(s): 1
Vendor ID: GenuineIntel
CPU family: 6
Model: 61
Model name: Intel(R) Core(TM) i5-5257U CPU @ 2.70GHz
Stepping: 4
CPU MHz: 2700.000
BogoMIPS: 5400.00
Hypervisor vendor: KVM
Virtualization type: full
L1d cache: 32K
L1i cache: 32K
L2 cache: 256K
L3 cache: 3072K
NUMA node0 CPU(s): 0,1
Flags: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ss ht syscall nx rdtscp lm constant_tsc nopl xtopology nonstop_tsc cpuid tsc_known_freq pni pclmulqdq ssse3 fma cx16 pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand hypervisor lahf_lm abm 3dnowprefetch invpcid_single pti fsgsbase tsc_adjust bmi1 avx2 smep bmi2 invpcid rdseed adx smap xsaveopt dtherm arat pln pts
编程中使用宏的方式:
// Check windows
#if _WIN32 || _WIN64
#if _WIN64
#define ENVIRONMENT64
#else
#define ENVIRONMENT32
#endif
#endif
// Check GCC
#if __GNUC__
#if __x86_64__ || __ppc64__
#define ENVIRONMENT64
#else
#define ENVIRONMENT32
#endif
#endif
确定linux库文件时32位 64位
确定静态库动态库位数的方法:
objdump -a example.a / example.so
示例:
[root c++]#objdump -a /var/lib/parallels-tools/GL/libglx.so
/var/lib/parallels-tools/GL/libglx.so: file format elf64-x86-64
/var/lib/parallels-tools/GL/libglx.so
查看so中是否存在某函数
nm xxx.so | grep func_name
T:存在函数
unrandom.c
int rand(){
return 42; //the most random number in the universe
}
使用如下命令将其编译成动态库:
gcc -shared -fPIC unrandom.c -o unrandom.so
使用方法:
[root c++]#nm unrandom.so | grep rand
000000000000057a T rand
[root c++]#
[root c++]#
[root c++]#nm unrandom.so | grep random
LD_PRELOAD用法
笔记里有一处记录hook的方法,比如定位问题时想看下进程是被哪个进程杀掉,这里可以hook kill,记录kill调用关系,一种场景是允许你重新编译代码替换到环境中,但绝大部分客户环境场景是不能随意替换二进制文件。一种可行的方法:Linux下LD_PRELOAD的简单用法。这边笔记算我整个博客里实用的文章top 5了。
linux tar命令
压缩:
tar zxvf xxx.tgz XXX/
解压
tar zxvf xxx.tgz
解压到某个文件
tar zxvf library.tgz -C /root/example
gdb中使用shell
在调试问题时如果已经使用gdb attach到线程里,又想使用命令查看某些信息,在不重新打开一个窗口的情况下,可以使用shell cmd执行。
lsmod命令用于显示已经加载到内核中的模块的状态信息
lsmod | grep -i ext3 (grep -i忽略大小写)
grep -o作用
周五解决了一个关于grep的bug,查看代码提交记录发现居然是2018年同一个实习生写的代码,巧的是上次那个问题也是我花了一天时间从一个2000多行的脚本中定位到了原因。
man grep 查看-o选项:
-o, --only-matching
Print only the matched (non-empty) parts of a matching line, with each such part on a separate output line.
我们来实际看一个例子:
[root ~]#cat file
foo foo
main
example
foo
[root ~]#
[root ~]#grep -o foo file
foo
foo
foo
[root ~]#
[root ~]#
[root ~]#grep foo file
foo foo
foo
如果要统计出现过foo的行数,是千万不能加-o,加了会导致统计的行数比实际行数多导致后续逻辑出错。当然如果要统计foo出现的次数是需要加-o然后统计行数就是foo出现的次数。
脚本一旦超过500行我认为就需要将脚本拆分成不同文件,一个2000多行的脚本是非常不利于维护。
return和exit的区别