theArcticOcean

博观而约取,厚积而薄发

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

线程切换调试

gdb查看帮助:help

(gdb) help
List of classes of commands:

aliases -- Aliases of other commands
breakpoints -- Making program stop at certain points
data -- Examining data
files -- Specifying and examining files
internals -- Maintenance commands
obscure -- Obscure features
running -- Running the program
stack -- Examining the stack
status -- Status inquiries
support -- Support facilities
tracepoints -- Tracing of program execution without stopping the program
user-defined -- User-defined commands

Type "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 line
target tfile -- Use a trace file as a target
task -- Use this command to switch between Ada tasks
thread -- Use this command to switch between threads
thread apply -- Apply a command to a list of threads
thread apply all -- Apply a command to all threads
until -- 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 ADDR
info target -- Names of targets and files being debugged
info tasks -- Provide information about all known Ada tasks
info terminal -- Print inferior's saved terminal status
info threads -- IDs of currently known threads
info 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]
txt

Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0xb69feb70 (LWP 3379)]
0x00289396 in strcat () from /lib/libc.so.6
Missing 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

阅读更多
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/theArcticOcean/article/details/77608007
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!
关闭
关闭