- 论坛徽章:
- 0
|
偶自己写的字符串连接造成多线程不安全
字符串连接头文件:join.h
- #ifndef JOIN_H
- char *Join(char *JoinItems[]);
- #endif
复制代码
字符串连接:join.c
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- char *
- Join(char *JoinItems[])
- {
- char *JoinStr = NULL;
- size_t JoinStrLen = 0;
- int TotalItemsNum = 0;
- int i;
- while (*JoinItems != NULL)
- {
- JoinStrLen += strlen(*JoinItems);
- JoinItems++;
- TotalItemsNum++;
- }
- if ((JoinStr = malloc(JoinStrLen)) != NULL)
- {
- for (i = 0; i < TotalItemsNum; i++)
- {
- JoinItems--;
- }
- while (*JoinItems != NULL)
- {
- strcat(JoinStr, *JoinItems);
- JoinItems++;
- }
-
- return JoinStr;
- }
- else
- {
- return "FALSE";
- }
- }
复制代码
单线程测试用例:testjoin.c,单线程工作起来是正常的
- #include <stdio.h>
- #include "join.h"
-
- int
- main(int argc, char *argv[])
- {
- char *JoinStr = NULL;
- char *items[] = {
- "./cache/",
- "sirtoozee",
- ".html",
- NULL
- };
-
- if (argc < 2)
- {
- JoinStr = Join(items);
- }
- else
- {
- JoinStr = Join(argv);
- }
- printf("%s\n", JoinStr);
- free(JoinStr);
- JoinStr = NULL;
-
- return 0;
- }
复制代码
多线程测试用例:testmtjoin.c,工作起来就不正常了
- #include <stdio.h>
- #include <pthread.h>
- #include "join.h"
- #include "./../md5/md5.h"
- #define DIR "./cache/"
- #define EXT ".html"
- char *urls[] = {
- "http://localhost/",
- "http://localhost/yui/",
- "http://localhost/libc/"
- };
- void *TestCallback(void *url)
- {
- FILE *fw;
- char *cache_file;
- char *JoinItems[] = {
- DIR,
- SIR_MD5(url),
- EXT,
- NULL
- };
-
- if ((cache_file = Join(JoinItems)) != "FALSE")
- {
- if ((fw = fopen(cache_file, "w")) != NULL)
- {
- fputs(url, fw);
- printf("Constructed %s\n", cache_file);
- }
- else
- {
- printf("Fail to wrtie to %s\n", cache_file);
- }
- }
- else
- {
- printf("Fail to join %s\n", cache_file);
- }
- fclose(fw);
- free(cache_file);
- cache_file = NULL;
- free(JoinItems);
- return NULL;
- }
- int
- main(int argc, char *argv[])
- {
- pthread_t tid[3];
- int i;
-
- for (i = 0; i < 3; i++)
- {
- pthread_create(&tid[i], NULL, TestCallback, urls[i]);
- }
-
- for (i = 0; i < 3; i++)
- {
- pthread_join(tid[i], NULL);
- printf("Destructed %s.\n", urls[i]);
- }
-
- return 0;
- }
复制代码
由于使用了openssl的md5加密,提贴出代码:
- #ifndef MD5_H
- char *SIR_MD5(char *str);
- #endif
- #include <stdio.h>
- #include <string.h>
- #include <openssl/evp.h>
- #include <openssl/md5.h>
- static char *pt(unsigned char *md);
- static char
- *pt(unsigned char *md)
- {
- int i;
- static char buf[80];
- for (i = 0; i < MD5_DIGEST_LENGTH; i++)
- {
- sprintf(&(buf[i * 2]), "%02x", md[i]);
- }
- return(buf);
- }
- char *SIR_MD5(char *str)
- {
- char *p;
- unsigned char md[MD5_DIGEST_LENGTH];
-
- EVP_Digest(str, strlen(str), md, NULL, EVP_md5(), NULL);
- p = pt(md);
-
- return p;
- }
复制代码
我的SConstruct脚本:
- Program('testmtjoin', Split('./../md5/md5.c join.c testmtjoin.c'), LIBS=['-lssl', '-lpthread'])
- #Program('testjoin', Split('join.c testjoin.c'))
复制代码
错误信息:
- constructed ./cache/c9db569cb388e160e4b86ca1ddff84d7.html
- *** glibc detected *** ./testmtjoin: double free or corruption (out): 0xb7cbf450 ***
- ======= Backtrace: =========
- /lib/libc.so.6[0xb7e2dcb0]
- /lib/libc.so.6(__libc_free+0x84)[0xb7e2f2f4]
- ./testmtjoin[0x804898f]
- /lib/libpthread.so.0[0xb7eee294]
- /lib/libc.so.6(__clone+0x5e)[0xb7e8632e]
- ======= Memory map: ========
- 08048000-08049000 r-xp 00000000 08:03 2959737 /root/Projects/sirch/trunk/tests/join/testmtjoin
- 08049000-0804a000 rw-p 00000000 08:03 2959737 /root/Projects/sirch/trunk/tests/join/testmtjoin
- 0804a000-0806b000 rw-p 0804a000 00:00 0 [heap]
- b6300000-b6321000 rw-p b6300000 00:00 0
- b6321000-b6400000 ---p b6321000 00:00 0
- b64bd000-b64be000 ---p b64bd000 00:00 0
- b64be000-b6cbe000 rw-p b64be000 00:00 0
- b6cbe000-b6cbf000 ---p b6cbe000 00:00 0
- b6cbf000-b74bf000 rw-p b6cbf000 00:00 0
- b74bf000-b74c0000 ---p b74bf000 00:00 0
- b74c0000-b7cc1000 rw-p b74c0000 00:00 0
- b7cc1000-b7cc3000 r-xp 00000000 08:03 1733411 /lib/libdl-2.4.so
- b7cc3000-b7cc5000 rw-p 00001000 08:03 1733411 /lib/libdl-2.4.so
- b7cc5000-b7cc6000 rw-p b7cc5000 00:00 0
- b7cc6000-b7db6000 r-xp 00000000 08:03 1116342 /usr/lib/libcrypto.so.0.9.7
- b7db6000-b7dc8000 rw-p 000f0000 08:03 1116342 /usr/lib/libcrypto.so.0.9.7
- b7dc8000-b7dcb000 rw-p b7dc8000 00:00 0
- b7dcb000-b7ee2000 r-xp 00000000 08:03 1733408 /lib/libc-2.4.so
- b7ee2000-b7ee4000 r--p 00116000 08:03 1733408 /lib/libc-2.4.so
- b7ee4000-b7ee6000 rw-p 00118000 08:03 1733408 /lib/libc-2.4.so
- b7ee6000-b7ee9000 rw-p b7ee6000 00:00 0
- b7ee9000-b7ef8000 r-xp 00000000 08:03 1733424 /lib/libpthread-2.4.so
- b7ef8000-b7ef9000 r--p 0000e000 08:03 1733424 /lib/libpthread-2.4.so
- b7ef9000-b7efa000 rw-p 0000f000 08:03 1733424 /lib/libpthread-2.4.so
- b7efa000-b7efc000 rw-p b7efa000 00:00 0
- b7efc000-b7f2a000 r-xp 00000000 08:03 1116339 /usr/lib/libssl.so.0.9.7
- b7f2a000-b7f2d000 rw-p 0002e000 08:03 1116339 /usr/lib/libssl.so.0.9.7
- b7f3d000-b7f47000 r-xp 00000000 08:03 1115354 /usr/lib/gcc/i686-pc-linux-gnu/4.1.1/libgcc_s.so.1
- b7f47000-b7f48000 rw-p 00009000 08:03 1115354 /usr/lib/gcc/i686-pc-linux-gnu/4.1.1/libgcc_s.so.1
- b7f48000-b7f49000 rw-p b7f48000 00:00 0
- b7f4a000-b7f4b000 rw-p b7f4a000 00:00 0
- b7f4b000-b7f4c000 r-xp b7f4b000 00:00 0 [vdso]
- b7f4c000-b7f66000 r-xp 00000000 08:03 1733396 /lib/ld-2.4.so
- b7f66000-b7f67000 r--p 00019000 08:03 1733396 /lib/ld-2.4.so
- b7f67000-b7f68000 rw-p 0001a000 08:03 1733396 /lib/ld-2.4.so
- bfd06000-bfd1b000 rw-p bfd06000 00:00 0 [stack]
复制代码
我的系统是Gentoo,gcc是4.1.1,多线程操作的时候,malloc是不是需要“特别照顾”呢?请大家帮帮sirtoozee,谢谢了 |
|