最近遇到过几次文件被占用,无法启动服务的情况,在lszrz上传完文件之后,主要还是因为之前的进程没停。所以起不来,提示”Text file busy“。
专业解释如下:The Text file busy error in specific is about trying to modify an executable while it is executing. The "Text" here refers to the fact that the file being modified is the text segment for a running program.
翻译:”Text file busy“ 错误是因为去修改正在运行可执行程序。这里的 "Text" 指的是可执行程序的代码段。~~
主要原因还是因为文件被占用了,因此可以用fuser看下是哪个进程还在占用着文件。kill掉就可以了。fuser ./xx
输出如下:xx: 2878 //这个就是pid了
然后kill掉就可以了。kill -9 2878
可以自己写个代码验证下。
验证流程如下:
写一个1.cpp,一直
while(1)
死循环啥事也不干就可以了。
1#include<iostream>
2#include<fstream>
3using namespace std;
4int main(int argc, char* argv[]){
5 while(1){}
6}
然后编译执行
./1
,新打开一个terminal然后fuser ./1
就可以看到哪个进程占用了。
1gcc -o 1 1.cpp -lstdc++
2./1
3fuser 1
4/root/1: 27975e // 1的pid,忽略后面的e
5// 这个时候尝试
6cp /bin/cat 1
7提示:
8cp:是否覆盖"1"?y // 输入y
9提示:
10cp: 无法创建普通文件"1": 文本文件忙
最后直接
kill -9
就可以了
1kill -9 27975
总结下来:
查看进程打开了哪些文件
1lsof -pPID
查看文件被哪些进程打开
1fuser filename
翻一翻linux源代码也可以找到这里问题对应的代码(参考v1.0版本):
1include/linux/errno.h
2#define ETXTBSY 26 /* Text file busy */
3fs/namei.c
4
5if ((inode->i_count > 1) && (flag & 2)) {
6 for (p = &LAST_TASK ; p > &FIRST_TASK ; --p) {
7 struct vm_area_struct * mpnt;
8 if (!*p)
9 continue;
10 if (inode == (*p)->executable) { // 这里的*p是task_truct指针
11 iput(inode);
12 return -ETXTBSY;
13 }
14 for(mpnt = (*p)->mmap; mpnt; mpnt = mpnt->vm_next) {
15 if (mpnt->vm_page_prot & PAGE_RW)
16 continue;
17 if (inode == mpnt->vm_inode) {
18 iput(inode);
19 return -ETXTBSY;
20 }
21 }
22 }
23 }
看上面的代码有两处会返回”Text file busy“:
当你要替换可执行程序在运行的时候的时候。
当文件是可执行文件,而且代码段已经在内存中的时候。
另外,ios逆向的东西还会写,只是我最近整理ELF文件mach-O文件的东西,稍微晚点在写。🐯🐯🐯
参考链接:
[1] http://wiki.wlug.org.nz/ETXTBSY
[2] https://stackoverflow.com/questions/1282506/where-did-the-text-segment-get-its-name/1282540#1282540
[3] http://www.csyangchen.com/text-file-busy-issue.html
[4] https://mirrors.edge.kernel.org/pub/linux/kernel/v1.0/linux-1.0.tar.gz linux 内核源代码 1.0版本




