【github myLocker】线程切换调试,读写指针修改文件,socket 阻塞设置

来源:互联网 发布:应届生程序员面试题 编辑:程序博客网 时间:2024/05/29 19:45

线程切换调试

gdb查看帮助:help

(gdb) helpList of classes of commands:aliases -- Aliases of other commandsbreakpoints -- Making program stop at certain pointsdata -- Examining datafiles -- Specifying and examining filesinternals -- Maintenance commandsobscure -- Obscure featuresrunning -- Running the programstack -- Examining the stackstatus -- Status inquiriessupport -- Support facilitiestracepoints -- Tracing of program execution without stopping the programuser-defined -- User-defined commandsType "help" followed by a class name for a list of commands in that class.Type "help all" for the list of all commands.Type "help" followed by command name for full documentation.Type "apropos word" to search for commands related to "word".Command name abbreviations are allowed if unambiguous.

查看特定类的命令:
比如 help command

(gdb) help running...target remote -- Use a remote computer via a serial linetarget tfile -- Use a trace file as a targettask -- Use this command to switch between Ada tasksthread -- Use this command to switch between threadsthread apply -- Apply a command to a list of threadsthread apply all -- Apply a command to all threadsuntil -- Execute until the program reaches a source line greater than the current

由此可知切换线程的命令是thread。后面加上thread Id即可。

(gdb) help status...info symbol -- Describe what symbol is at location ADDRinfo target -- Names of targets and files being debuggedinfo tasks -- Provide information about all known Ada tasksinfo terminal -- Print inferior's saved terminal statusinfo threads -- IDs of currently known threadsinfo tracepoints -- Status of tracepoints

查看所有线程的命令是info threads
eg:

(gdb) info thread  4 Thread 0xb67ffb70 (LWP 3353)  0x00110424 in __kernel_vsyscall ()  3 Thread 0xb73ffb70 (LWP 3352)  0x00110424 in __kernel_vsyscall ()  2 Thread 0xb7fe7b70 (LWP 3351)  0x00110424 in __kernel_vsyscall ()* 1 Thread 0xb7fe88d0 (LWP 3348)  main () at main.c:85(gdb) thread 4[Switching to thread 4 (Thread 0xb67ffb70 (LWP 3353))]#0  0x00110424 in __kernel_vsyscall ()

某一次,程序在输入加密文本后出现了段错误,我们可以利用bt, thread TID等命令查看具体的细节。

[lockerThread] ret: 7, recv buff: encrypt[lockerThread] start encrypt text file...[lockerThread] please enter filename to enrypt which file is put in folder.[main] retval from textCode thread: 1[Thread 0xb7fe7b70 (LWP 3377) exited][main] retval from textRW thread: 1[Thread 0xb73ffb70 (LWP 3378) exited]txtProgram received signal SIGSEGV, Segmentation fault.[Switching to Thread 0xb69feb70 (LWP 3379)]0x00289396 in strcat () from /lib/libc.so.6Missing separate debuginfos, use: debuginfo-install libgcc-4.4.7-17.el6.i686(gdb) info thread* 4 Thread 0xb69feb70 (LWP 3379)  0x00289396 in strcat () from /lib/libc.so.6  1 Thread 0xb7fe88d0 (LWP 3374)  0x00110424 in __kernel_vsyscall ()(gdb) thread 4[Switching to thread 4 (Thread 0xb69feb70 (LWP 3379))]#0  0x00289396 in strcat () from /lib/libc.so.6(gdb) bt#0  0x00289396 in strcat () from /lib/libc.so.6#1  0x08049fbe in pth_encrypt () at pthLocker.c:106#2  0x08049f29 in pthLocker_run (arg=0x0) at pthLocker.c:78#3  0x003b0bc9 in start_thread () from /lib/libpthread.so.0#4  0x002f2dee in clone () from /lib/libc.so.6

由此可见,问题出现在 pthLocker.c文件的pth_encrypt ()函数的strcat()处。

读写指针修改文件

只用一个指针读取文件内容并修改内容。
应用fseek移动文件指针指向的位置,使用ftell()获取指针的当前位置。
int fseek(FILE *stream, long offset, int whence)的第三个参数可以取SEEK_SET(文件开始),SEEK_END(文件末尾),SEEK_CUR(当前读取位置)。offset是相对whence的值,可正可负,文件结束位置方向为正,开始方向位置为负。

#include <stdio.h>int main(){    FILE* text_f = fopen("txt","r+");    long pos, posEnd;    char ch;    fseek(text_f,0L,SEEK_END);    posEnd = ftell(text_f);    fseek(text_f,0L,SEEK_SET);    pos = ftell(text_f);    printf("len is %d\n",posEnd-pos);    printf("pos is %d\n",pos);    while(pos < posEnd-1){        fscanf(text_f,"%c",&ch);        int primer = 2;        ch = ch^primer;        fseek(text_f,-1,SEEK_CUR);        fprintf(text_f,"%c",ch);        pos = ftell(text_f);        printf("pos is %d\n",pos);    }    return 0;}

SEEK_SET是0处,SEEK_END是strlen(文本内容)+1处。pos < posEnd-1相当于 pos < strlenSEEK_END-SEEK_SET等于sizeof(str), SEEK_END-SEEK_SET-1等于strlen(str).

socket 阻塞设置

为什么在下面的while(1)循环中,printf只打出了一次?
下面是线程pthTextCode,线程函数有一个while(1)循环,用于接收main传过来的消息,让我困惑的是为什么确认消息的printf只有在确实接收了消息才打印?(虽然这确实是好事,但我想知道究竟发生了什么)

    while(1){        int client_len;        client_len = sizeof(client);        memset(buff,0,pthTextCode_buff_len);        ret = recvfrom(sock_fd,buff,pthTextCode_buff_len,0,(struct sockaddr*)&client,&client_len);        printf("\033[1;33m[textCodeThread]\033[0m ret: %d, recv buff: %s\n",ret,buff);        if(ret > 0){            short analyze = 0;...

问题出在sock_fd上,他没有被设置成非阻塞。
相关说明:

F_GETFL (void)
Read the file status flags; arg is ignored.
F_SETFL (long)
Set the file status flags to the value specified by arg.
File access mode (O_RDONLY, O_WRONLY, O_RDWR) and file creation flags (i.e., O_CREAT, O_EXCL, O_NOCTTY, O_TRUNC) in arg are ignored. On Linux this command can only change the O_APPEND, O_ASYNC,O_DIRECT, O_NOATIME, and O_NONBLOCK flags.

使用fcntl函数设置socket:

flag = fcntl(sock_fd,F_GETFL);/* sock_fd not blocked */fcntl(sock_fd,F_SETFL,flag|O_NONBLOCK);

对应的sock_fd即为非阻塞类型。

工程地址:https://github.com/theArcticOcean/myLocker

原创粉丝点击