如何解决有人可以追踪分段错误的原因吗?
public class Watcher: Object
{
private int _fd;
private uint _watch;
private IOChannel _channel;
private uint8[] _buffer;
private int BUFFER_LENGTH;
public Watcher(string path,Linux.InotifyMaskFlags mask){
_buffer = new uint8[BUFFER_LENGTH];
//➔ Initialize notify subsystem
_fd = Linux.inotify_init();
if(_fd < 0){
error(@"Failed to initialize the notify subsystem: $(strerror(errno))");
}
//➔ actually adding abstraction to linux file descriptor
_channel = new IOChannel.unix_new(_fd);
//➔ watch the channel for given condition
//➔ IOCondition.IN => When the channel is ready for reading,IOCondition.HUP=>Hangup(Error)
_watch = _channel.add_watch(IOCondition.IN | IOCondition.HUP,onNotified);
if(_watch < 0){
error(@"Failed to add watch to channel");
}
//➔ Tell linux kernel to watch for any mask(for ex; access,modify) on a given filepath
var ok = Linux.inotify_add_watch(_fd,path,mask);
if(ok < 0){
error(@"Failed to add watch to path -- $path : $(strerror(errno))");
}
print(@"Watching for $(mask) on $path");
}
protected bool onNotified(IOChannel src,IOCondition condition)
{
if( (condition & IOCondition.HUP) == IOCondition.HUP){
error(@"Received hang up from inotify,can't get update");
}
if( (condition & IOCondition.IN) == IOCondition.IN){
var bytesRead = Posix.read(_fd,_buffer,BUFFER_LENGTH);
Linux.InotifyEvent *pevent = (Linux.InotifyEvent*) _buffer;
handleEvent(*pevent);
}
return true;
}
protected void handleEvent(Linux.InotifyEvent ev){
print("Access Detected!\n");
Posix.exit(0);
}
~Watcher(){
if(_watch != 0){
Source.remove(_watch);
}
if(_fd != -1){
Posix.close(_fd);
}
}
}
int main(string[] args) requires (args.length > 1)
{
var watcher = new Watcher(args[1],Linux.InotifyMaskFlags.ACCESS);
var loop = new MainLoop();
loop.run();
return 0;
}
上面的代码可以在“Introducing Vala Programming - Michael Lauer”中找到
失败证明: Image displaying failure on access to the file being watched for access
1 号航站楼: ./inotifyWatcher 2 号航站楼: 猫
我一访问文件,就会发生分段错误。 我也尝试过使用 gdb 来解决失败的原因,但这对我来说大多是神秘的。我在我的机器上使用 parrot(debian/64-bit)。另外,我是新手(stackoverflow,linux 内核程序)。
解决方法
使用 --debug
开关编译时,Vala 源代码行号可以包含在二进制文件中。行号出现在 .debug_line
DWARF section of an ELF binary:
valac --debug --pkg linux inotifyWatcher.vala
在第一个终端中使用 gdb
运行二进制文件:
gdb --args ./inotifyWatcher .
(gdb) run
点指定观看当前目录。然后,当使用 ls
之类的命令访问当前目录时,观看程序分段错误。 GDB 的输出是:
Program received signal SIGSEGV,Segmentation fault.
0x0000000000401a86 in watcher_onNotified (self=0x412830,src=0x40e6e0,condition=G_IO_IN) at inotifyWatcher.vala:51
51 handleEvent(*pevent);
GDB 包含源文件中的行号 51 并显示该行。
所以问题在于从文件描述符读取然后将缓冲区传递给handleEvent
。您可能想检查 bytesRead
是否大于零,但我不确定本示例中是否使用了指针。像这样的显式指针应该很少需要在 Vala 中使用,它可能需要更改绑定,例如使用 ref
修改参数的传递方式。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。