DDE后端之dentry(一):从测试经验看运行机制
http://kms.linuxdeepin.com/?p=2214
上面一篇文章和这篇应该一起看,建议先看第一篇文章。
dentry源码:https://github.com/linuxdeepin/dde/tree/develop/lib/dentry
测试代码源码:https://github.com/linuxdeepin/dde/tree/desktop_test/app/desktop/test
直入正题:
1.nautilus网络文件的拖动问题,或者整个文件夹的复制。不能复制文件夹内部文件的原因:api不支持对网络文件夹内部文件遍历。---未解决
if (g_file_is_native (src)) traverse_directory (src, _copy_files_async, _dummy_func, data); else _copy_files_async (src,data);
代码位置:dde/lib/dentry/fileops_copy.c -->fileops_copy()
此处判断如果是网络文件,那么traverse_directory
若是本地文件,直接_copy_files_async
此处需改进
这个等下半年做文件管理器时修
2.桌面必挂Bug---已解决
bug见tower:
重现方式:(注此bug已于20130716日修复)
首先在文件管理器中创建一个文件夹的软链(文件夹中要有文件),然后下面是两种不同方法,都会挂掉
1. 在软链上右键复制—>到桌面上粘贴
2. 在软链上剪切—->在桌面粘贴这个软链—>然后在桌面再次复制粘贴软链。
会弹出是否覆盖的提示,这个随意选择,最后会报错误: “当复制文件时出错”
最后点击确定,桌面必挂。
详情见:
http://kms.linuxdeepin.com/?p=2255
//begin g_file_enumerator_next_file ,we must check if the file type is symbolic_link then goto post_processing:
GFileType type = g_file_query_file_type (src, G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, NULL);
if (type == G_FILE_TYPE_SYMBOLIC_LINK)
{
//TODO: symbolic links
g_debug ("-------src type is symbolic_link-------");
goto post_processing;
}
3. 对于symlink也有待改进---------已解决,且标准化
dentry_copy:只复制symlink本身,不复制软链对应的文件或者文件夹
dentry_copy_dereference_symlink:还会进入symlink遍历。但是这样很容易由树成图,进入死循环。
static
void _do_dereference_symlink_copy(GFile* src, GFile* dest, GFileCopyFlags copy_flag)
{
GError* error = NULL;
if (!g_file_copy(src, dest, copy_flag, NULL, NULL, NULL, &error)) {
g_warning("error message: %s, error code: %d\n", error->message, error->code);
FileOpsResponse* response;
response = fileops_move_copy_error_show_dialog(_("copy"), error, src, dest, NULL);
if (response != NULL) {
switch (response->response_id)
{
case GTK_RESPONSE_CANCEL:
//cancel all operations
g_debug ("response : Cancel");
break;
case CONFLICT_RESPONSE_SKIP:
//skip, imediately return.
g_debug ("response : Skip");
break;
case CONFLICT_RESPONSE_RENAME:
//rename, redo operations
g_warning ("response : Rename to %s", response->file_name);
GFile* dest_parent = g_file_get_parent(dest);
GFile* new_dest = g_file_get_child (dest_parent, response->file_name);
g_object_unref(dest_parent);
_do_dereference_symlink_copy(src, new_dest, copy_flag);
g_object_unref(new_dest);
break;
case CONFLICT_RESPONSE_REPLACE:
{
g_file_copy(src, dest, G_FILE_COPY_OVERWRITE, NULL, NULL, NULL, NULL);
g_debug ("response : Replace");
break;
}
default:
break;
}
fileops_response_free (response);
g_error_free(error);
}
}
}
4.不够完善,需要改进的traverse_directory中的g_warning------已解决
fileops_moving时
** Message: fileops_move: Begin moving files ** Message: fileops_move: file 0: file:///home/ycl/dde/build/test_files/skype.desktop to dest: file:///home/ycl ** Message: GFileType=2 ** (desktop:25391): WARNING **: traverse_directory 1: 没有那个文件或目录 ** Message: fileops_move: End moving files
说明:
文件是存在的,但是还是报了警告
source:
g_warning ("traverse_directory 1: %s", error->message);
g_warning ("traverse_directory 2: %s", error->message);
g_warning ("traverse_directory 3: %s", error->message);
location:
traverse_directory()内
5. 测试时挂掉的地方:------已解决
** (desktop:24641): DEBUG: _delete_files_async: delete : file:///home/ycl/test_files/brasero.desktop ** (desktop:24641): DEBUG: traverse_directory: come out: file:///home/ycl/test_files ** (desktop:24641): DEBUG: _delete_files_async: delete : file:///home/ycl/test_files ** (desktop:24641): DEBUG: fileops_delete: End deleting files ** Message: 3delete end [ 20%] Testing dentry_move... ** (desktop:24641): ERROR **: Test dentry_move Failed Program received signal SIGTRAP, Trace/breakpoint trap. 0x00007ffff4644205 in g_logv () from /lib/x86_64-linux-gnu/libglib-2.0.so.0 (gdb) bt #0 0x00007ffff4644205 in g_logv () from /lib/x86_64-linux-gnu/libglib-2.0.so.0 #1 0x00007ffff46443d2 in g_log () from /lib/x86_64-linux-gnu/libglib-2.0.so.0 #2 0x000000000042f438 in T () #3 0x000000000042f295 in test_entry () #4 0x000000000042e83f in desktop_test () #5 0x0000000000418996 in desktop_test_wrap () #6 0x00007ffff463da5b in ?? () from /lib/x86_64-linux-gnu/libglib-2.0.so.0 #7 0x00007ffff463ce45 in g_main_context_dispatch () from /lib/x86_64-linux-gnu/libglib-2.0.so.0 #8 0x00007ffff463d188 in ?? () from /lib/x86_64-linux-gnu/libglib-2.0.so.0 #9 0x00007ffff463d5fa in g_main_loop_run () from /lib/x86_64-linux-gnu/libglib-2.0.so.0 #10 0x00007ffff5ff90a5 in gtk_main () from /usr/lib/x86_64-linux-gnu/libgtk-3.so.0 #11 0x0000000000412446 in main () (gdb) q A debugging session is active. Inferior 1 [process 24641] will be killed. Quit anyway? (y or n) y ycl@ycl:~/dde/build$ desktop
注:
1. 自动挂掉后,gvfsd-trash 仍然占据高达2.2G的内存(那么挂掉很有可能是dentry_trash()有问题)
desktop内存高达106.5MB (我已经设置最大为int TEST_MAX_MEMORY = RES_IN_MB(90);)
(此处是因为Test.c中关于内存计算和系统计算不同,内存每溢出。)
2. 重启desktop后,内存由35M 慢慢涨到197.1M,且一直稳定在197.1M
解答:
挂在fileops_trash这了(将dentry_trash 中的fileops_trash 换成fileops_delete则一切正常)。
进入fileops_trash发现:
_trash_files_async (src, data);
//traverse_directory (dir, _dummy_func, _trash_files_async, NULL);
继续一步步深入,还是挂,最后不得不这样:
Test({
system("touch /tmp/test.c");
g_message("1trash start");
GFile* _src1 = g_file_new_for_uri("file:///tmp/test.c");
// ArrayContainer _fs1;
// _fs1.data=&_src1;
// _fs1.num = 1;
// dentry_trash(_fs1);
// ArrayContainer_free0(_fs1);
g_file_trash (_src1, NULL, NULL);
g_object_unref(_src1);
g_message(" trash end");
},"dentry_trash");
然后结果:
[ 28%] Testing dentry_trash...** Message: 1trash start ** Message: trash end [ 28%] Testing dentry_trash... ** (desktop:20703): ERROR **: Test dentry_trash Failed
跟踪/断点陷阱
仍然挂。。。。。
至此,找出了glib 中g_file_trash 的一个bug了。
gboolean g_file_trash (GFile *file,GCancellable *cancellable,GError **error);
trash 次数 2800次以上,必挂! 而且是引起整个DDE桌面挂掉。
可能原因: trash时不仅仅只是将文件move到回收站,而且gvfsd-trash还记录了trash的GFile的info信息。
如下:
ycl@ycl:/tmp$ cd ~/.local/share/Trash/ ycl@ycl:~/.local/share/Trash$ l expunged/ files/ info/ ycl@ycl:~/.local/share/Trash$ cd info/ ycl@ycl:~/.local/share/Trash/info$ l skype.1000.desktop.trashinfo test.11071.c.trashinfo test.13131.c.trashinfo test.1766.c.trashinfo test.3827.c.trashinfo test.5888.c.trashinfo test.7948.c.trashinfo skype.1001.desktop.trashinfo test.11072.c.trashinfo tes
很可能是trash次数过多,后台单独记录的进程跟不上trash的速度,导致挂掉的
case G_IO_ERROR_NOT_FOUND:
//TODO: showup a message box and quit.
g_debug("G_IO_ERROR_NOT_FOUND");
这个等有时间再慢慢修。
// test_thumbnails();//test over
//
// but there is a bug ,but cannot be reviewed ,and it is hard to be shown :
// after test programe run 100% over,there perhaps be a error to kill ./desktop -d but without any messageout
// when I run test in gdb ,still no useful messageout
// when I run test in valgrind to track the memory-out,it messageout:
// ==9299== by 0x7A95AC0: _cairo_compositor_paint (cairo-compositor.c:65)
// ==9299== by 0x7AD9640: _cairo_surface_paint (cairo-surface.c:2022)
// ==9299== by 0x7A9D18B: _cairo_gstate_paint (cairo-gstate.c:1067)
// ==9299== by 0x7A97DC8: _cairo_default_context_paint_with_alpha (cairo-default-context.c:969)
// ==9299== by 0x7A90726: cairo_paint_with_alpha (cairo.c:2026)
// ==9299==
// ==9299== LEAK SUMMARY:
// ==9299== definitely lost: 6,288 bytes in 11 blocks
// ==9299== indirectly lost: 16,790 bytes in 674 blocks
// ==9299== possibly lost: 1,821,394 bytes in 16,770 blocks
// ==9299== still reachable: 2,152,849 bytes in 18,993 blocks
// ==9299== suppressed: 0 bytes in 0 blocks
// ==9299== Reachable blocks (those to which a pointer was found) are not shown.
// ==9299== To see them, rerun with: --leak-check=full --show-reachable=yes
// ==9299==
// ==9299== For counts of detected and suppressed errors, rerun with: -v
// ==9299== ERROR SUMMARY: 1655 errors from 1655 contexts (suppressed: 3 from 3)
// 已杀死
//there still isnot any useful DEBUG message
//and I g_message in somewhere (begin function ,end function ,begin if and so on ),but ,there still isnot DEBUG message useful
9.
/* make
/home/ycl/dde/lib/dentry/fileops_trash.c: 在函数‘fileops_empty_trash’中:
/home/ycl/dde/lib/dentry/fileops_trash.c:108:5: 警告: 不建议使用‘g_io_scheduler_push_job’(声明于 /usr/include/glib-2.0/gio/gioscheduler.h:36):Use '"GThreadPool or g_task_run_in_thread"' instead [-Wdeprecated-declarations]
/home/ycl/dde/lib/dentry/fileops_trash.c: 在函数‘_empty_trash_job’中:
/home/ycl/dde/lib/dentry/fileops_trash.c:163:5: 警告: 不建议使用‘g_io_scheduler_job_send_to_mainloop_async’(声明于 /usr/include/glib-2.0/gio/gioscheduler.h:49):Use 'g_main_context_invoke' instead [-Wdeprecated-declarations]
[ 22%] Building C object lib/dentry/CMakeFiles/dentry.dir/gnome-desktop-thumbnail.c.o
/home/ycl/dde/lib/dentry/gnome-desktop-thumbnail.c: 在函数‘gnome_desktop_thumbnail_factory_finalize’中:
/home/ycl/dde/lib/dentry/gnome-desktop-thumbnail.c:456:7: 警告: 不建议使用‘g_mutex_free’(声明于 /usr/include/glib-2.0/glib/deprecated/gthread.h:274) [-Wdeprecated-declarations]
/home/ycl/dde/lib/dentry/gnome-desktop-thumbnail.c: 在函数‘gnome_desktop_thumbnail_factory_init’中:
/home/ycl/dde/lib/dentry/gnome-desktop-thumbnail.c:752:3: 警告: 不建议使用‘g_mutex_new’(声明于 /usr/include/glib-2.0/glib/deprecated/gthread.h:272) [-Wdeprecated-declarations]
[ 23%] Building C object lib/dentry/CMakeFiles/dentry.dir/mime_actions.c.o
*/
本文探讨了DDE后端dentry模块的运行机制,包括网络文件拖动问题、桌面BUG修复、symlink处理及改进、traverse_directory函数优化等内容,并指出了有待解决的问题。
:从测试中发现的不足和bug&spm=1001.2101.3001.5002&articleId=9719451&d=1&t=3&u=301034c48e664e7c913611c5008cf5d1)

被折叠的 条评论
为什么被折叠?



