怎么判断程序是c c++ golang python写的
好问题 👍,SRE 工程里经常会遇到一个二进制文件(比如 /usr/bin/xxx),但不知道它是用 C、C++、Go、Python(或其他语言)写的。
判断语言通常不靠“看代码”,而是看 二进制文件特征。
我分几类方法给你:
🔹 1. 用 file 看基础信息
file /usr/bin/nginx
输出类似:
/usr/bin/nginx: ELF 64-bit LSB executable, x86-64, dynamically linked ...
这只能告诉你是 ELF 可执行文件(Linux 下的标准格式),不能直接区分 C / C++ / Go。
🔹 2. 用 strings + grep 找语言特征
strings /usr/bin/myapp | less
-
Go 二进制:几乎总能看到
runtime.goexit、runtime.main、type.*、go.itab等符号。strings mygoapp | grep -i 'go.' -
C++ 二进制:会看到很多
_Z开头的符号(这是 C++ 名字修饰/mangling)。strings mycppapp | grep '_Z' -
Python 程序打包成二进制(PyInstaller/PyOxidizer):能看到
Py_InitModule、PyObject、.pyc、模块名字等。 -
纯 C 程序:一般只有正常的函数名、库函数(
printf,malloc),没有_Z符号,也没有 Go runtime。
🔹 3. 用 nm 或 objdump 看符号表
nm -D /usr/bin/myapp | less
-
Go:
U runtime.morestack U runtime.goexit -
C++:
0000000000401140 T _ZSt4cout 0000000000401180 T _ZNSolsEi -
C:
0000000000401040 T main U printf -
Python (C API):
U Py_Initialize U PyRun_SimpleString
🔹 4. 用 ldd 看依赖库
ldd /usr/bin/myapp
-
Go 静态编译的二进制:通常只有
linux-vdso.so.1或完全 no dynamic dependencies。 -
C / C++:会链接
libc.so,libm.so,libstdc++.so(C++ 才有)。 -
Python:会看到
libpython3.x.so。
🔹 5. 用 readelf 看 section
readelf -S /usr/bin/myapp | grep -i dynstr
-
Go 二进制里有
.gopclntab、.gosymtab段,这是 Go runtime 自带的调试信息。 -
C/C++ 没有这些,只有常规 ELF 段。
🔹 6. 实战对比例子
-
Nginx(C 写的):
strings $(which nginx) | grep runtime.goexit # 没有 ldd $(which nginx) # 依赖 libc.so -
Etcd(Go 写的):
strings $(which etcd) | grep runtime.goexit # 有 ldd $(which etcd) # 可能只有 vdso,没有 libc.so -
Redis(C 写的):
nm -D $(which redis-server) | grep _Z # 没有 _Z -
Fluent-bit(C 写的,SRE 常用日志 agent):
ldd $(which fluent-bit) | grep stdc++ # 没有,说明是 C,不是 C++ -
某个 C++ 程序:
nm -D ./app | grep _Z # 一堆 _Z... 符号
✅ 总结方法:
-
strings→ 看 runtime 特征(Go、Python 很明显)。 -
nm/objdump→ 看符号,C++ 有_Z*,Go 有runtime.*,Python 有Py_*。 -
ldd→ 看依赖库(libc、libstdc++、libpython)。 -
readelf→ 看特殊段(Go 有.gopclntab)。
要不要我写一个 小脚本 (bash/Python),可以自动判断二进制大概是 C / C++ / Go / Python 的?这样你丢个文件进去就能一键分析。
浙公网安备 33010602011771号