有人可以帮我弄清楚这是否真的是我的错误造成的,或者因为 helgrind 在这种情况下无法正确追踪它?
我也想知道“在...”是什么意思。在这种情况下是
at 0x48488A6: mempcpy (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_helgrind-amd64-linux.so)
。这是否意味着条件在那里找到并且由于这不是我编写的函数,所以这不是我的错?
我可以修复任何竞争条件错误,但这个错误。
编辑开始:
如果有帮助,我在this repo中有完整的代码: 只需构建和测试:
git clone https://github.com/mortytheshorty/thread && cd thread
mkdir build && cd build
cmake ..
make
valgrind -tool=helgrind -s ./simple_thread_test
测试功能:
void *thread_test(void *arg)
{
struct timespec timespec = { 0 };
timespec.tv_nsec = CLOCKS_PER_SEC * 500;
char *p = arg;
while(*p++) {
printf("%s\n", (char *) arg);
nanosleep(×pec, NULL);
}
}
编辑结束
标题:
// (c) 2023 Florian Giest
// This code is licensed under MIT license (see LICENSE.txt for details)
#ifndef _DEBUG_H// BEGIN INCLUDE GUARD
#define _DEBUG_H
/*********************************************************************************************************/
/* DEPENDANICIES */
/*********************************************************************************************************/
#include <stdio.h>
#include <string.h>
#include <stdarg.h>
#include <errno.h>
#include <pthread.h>
/*********************************************************************************************************/
/* DEFINITIONS */
/*********************************************************************************************************/
/* if DEBUG is defines it enables the macro for logging the steps
of every function which calls these functions/macros */
#ifdef DEBUG
/* pretty simple debug function expaned by macro 'debug()'
write DEBUG: at the first place followed by the calling pthread id
and a formatstring and its arguments
*/
void xdebug(pthread_t threadid, const char *function, const char *fmt, ...);
#define debug(fmt, ...) xdebug(pthread_self(), __func__, fmt, ##__VA_ARGS__)
/* same as for 'xdebug()' but for error and also prints errno string if
errno is set.
*/
void xdebug_error(pthread_t threadid, const char *function, const char *fmt, ...);
#define debug_error(fmt, ...) xdebug_error(pthread_self(), __func__, fmt, ##__VA_ARGS__)
#else
#define debug_error(x, ...)
#define debug(x, ...)
#endif
/*********************************************************************************************************/
/* FUNCTION DEFINITIONS */
/*********************************************************************************************************/
#endif
代码:
// (c) 2023 Florian Giest
// This code is licensed under MIT license (see LICENSE.txt for details)
/*********************************************************************************************************/
/* DEPENDANICIES */
/*********************************************************************************************************/
#include <pthread.h>
/*********************************************************************************************************/
/* DEFINITIONS */
/*********************************************************************************************************/
pthread_mutex_t debugmtx = PTHREAD_MUTEX_INITIALIZER;
/*********************************************************************************************************/
/* FUNCTION DEFINITIONS */
/*********************************************************************************************************/
void xdebug(pthread_t threadid, const char *function, const char *fmt, ...)
{
pthread_mutex_lock(&debugmtx);
va_list args;
va_start(args, fmt);
fprintf(stdout, "DEBUG: thread[%ld] %s(): ", threadid, function);
vfprintf(stdout, fmt, args);
fputc('\n', stdout);
va_end(args);
pthread_mutex_unlock(&debugmtx);
}
void xdebug_error(pthread_t threadid, const char *function, const char *fmt, ...)
{
pthread_mutex_lock(&debugmtx);
va_list args;
va_start(args, fmt);
fprintf(stderr, "ERROR: thread[%ld] %s(): ", threadid, function);
vfprintf(stderr, fmt, args);
if(errno) {
fprintf(stderr, " (%s)", strerror(errno));
}
fputc('\n', stderr);
va_end(args);
pthread_mutex_unlock(&debugmtx);
}
Valgrind(Helgrind)输出:
==30008==
==30008== 6 errors in context 1 of 2:
==30008== ----------------------------------------------------------------
==30008==
==30008== Lock at 0x4856200 was first observed
==30008== at 0x483FEDF: ??? (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_helgrind-amd64-linux.so)
==30008== by 0x4853939: xdebug (error.c:34)
==30008== by 0x48530FC: thread_create (thread.c:156)
==30008== by 0x109326: main (in /home/flo/projects/thread/build/simple_thread_test)
==30008== Address 0x4856200 is 0 bytes inside data symbol "debugmtx"
==30008==
==30008== Possible data race during write of size 1 at 0x4A79045 by thread #2
==30008== Locks held: none
==30008== at 0x48488A6: mempcpy (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_helgrind-amd64-linux.so)
==30008== by 0x4914631: _IO_new_file_xsputn (fileops.c:1236)
==30008== by 0x4914631: _IO_file_xsputn@@GLIBC_2.2.5 (fileops.c:1197)
==30008== by 0x49094F7: puts (ioputs.c:40)
==30008== by 0x1092B5: thread_test (in /home/flo/projects/thread/build/simple_thread_test)
==30008== by 0x48530A8: thread_worker (thread.c:126)
==30008== by 0x4842B1A: ??? (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_helgrind-amd64-linux.so)
==30008== by 0x486A608: start_thread (pthread_create.c:477)
==30008== by 0x49A4132: clone (clone.S:95)
==30008==
==30008== This conflicts with a previous write of size 1 by thread #1
==30008== Locks held: 1, at address 0x4856200
==30008== at 0x48488A6: mempcpy (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_helgrind-amd64-linux.so)
==30008== by 0x4914631: _IO_new_file_xsputn (fileops.c:1236)
==30008== by 0x4914631: _IO_file_xsputn@@GLIBC_2.2.5 (fileops.c:1197)
==30008== by 0x48FB971: __vfprintf_internal (vfprintf-internal.c:1373)
==30008== by 0x48E6C69: fprintf (fprintf.c:32)
==30008== by 0x4853992: xdebug (error.c:38)
==30008== by 0x48529C6: jobqueue_push (jobqueue.c:114)
==30008== by 0x4853517: thread_addjob (thread.c:264)
==30008== by 0x109403: main (in /home/flo/projects/thread/build/simple_thread_test)
==30008== Address 0x4a79045 is 5 bytes inside a block of size 1,024 alloc'd
==30008== at 0x483C893: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_helgrind-amd64-linux.so)
==30008== by 0x4906D03: _IO_file_doallocate (filedoalloc.c:101)
==30008== by 0x4916ECF: _IO_doallocbuf (genops.c:347)
==30008== by 0x4915F2F: _IO_file_overflow@@GLIBC_2.2.5 (fileops.c:745)
==30008== by 0x49146B4: _IO_new_file_xsputn (fileops.c:1244)
==30008== by 0x49146B4: _IO_file_xsputn@@GLIBC_2.2.5 (fileops.c:1197)
==30008== by 0x48FB971: __vfprintf_internal (vfprintf-internal.c:1373)
==30008== by 0x48E6C69: fprintf (fprintf.c:32)
==30008== by 0x4853992: xdebug (error.c:38)
==30008== by 0x48530FC: thread_create (thread.c:156)
==30008== by 0x109326: main (in /home/flo/projects/thread/build/simple_thread_test)
==30008== Block was alloc'd by thread #1
==30008==
==30008==
==30008== 7 errors in context 2 of 2:
==30008== ----------------------------------------------------------------
==30008==
==30008== Lock at 0x4856200 was first observed
==30008== at 0x483FEDF: ??? (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_helgrind-amd64-linux.so)
==30008== by 0x4853939: xdebug (error.c:34)
==30008== by 0x48530FC: thread_create (thread.c:156)
==30008== by 0x109326: main (in /home/flo/projects/thread/build/simple_thread_test)
==30008== Address 0x4856200 is 0 bytes inside data symbol "debugmtx"
==30008==
==30008== Possible data race during write of size 1 at 0x4A79046 by thread #1
==30008== Locks held: 1, at address 0x4856200
==30008== at 0x48488A6: mempcpy (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_helgrind-amd64-linux.so)
==30008== by 0x4914631: _IO_new_file_xsputn (fileops.c:1236)
==30008== by 0x4914631: _IO_file_xsputn@@GLIBC_2.2.5 (fileops.c:1197)
==30008== by 0x48FB971: __vfprintf_internal (vfprintf-internal.c:1373)
==30008== by 0x48E6C69: fprintf (fprintf.c:32)
==30008== by 0x4853992: xdebug (error.c:38)
==30008== by 0x485357F: thread_pause (thread.c:275)
==30008== by 0x10939A: main (in /home/flo/projects/thread/build/simple_thread_test)
==30008==
==30008== This conflicts with a previous write of size 1 by thread #2
==30008== Locks held: none
==30008== at 0x4915DC8: _IO_file_overflow@@GLIBC_2.2.5 (fileops.c:781)
==30008== by 0x4909599: puts (ioputs.c:41)
==30008== by 0x1092B5: thread_test (in /home/flo/projects/thread/build/simple_thread_test)
==30008== by 0x48530A8: thread_worker (thread.c:126)
==30008== by 0x4842B1A: ??? (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_helgrind-amd64-linux.so)
==30008== by 0x486A608: start_thread (pthread_create.c:477)
==30008== by 0x49A4132: clone (clone.S:95)
==30008== Address 0x4a79046 is 6 bytes inside a block of size 1,024 alloc'd
==30008== at 0x483C893: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_helgrind-amd64-linux.so)
==30008== by 0x4906D03: _IO_file_doallocate (filedoalloc.c:101)
==30008== by 0x4916ECF: _IO_doallocbuf (genops.c:347)
==30008== by 0x4915F2F: _IO_file_overflow@@GLIBC_2.2.5 (fileops.c:745)
==30008== by 0x49146B4: _IO_new_file_xsputn (fileops.c:1244)
==30008== by 0x49146B4: _IO_file_xsputn@@GLIBC_2.2.5 (fileops.c:1197)
==30008== by 0x48FB971: __vfprintf_internal (vfprintf-internal.c:1373)
==30008== by 0x48E6C69: fprintf (fprintf.c:32)
==30008== by 0x4853992: xdebug (error.c:38)
==30008== by 0x48530FC: thread_create (thread.c:156)
==30008== by 0x109326: main (in /home/flo/projects/thread/build/simple_thread_test)
==30008== Block was alloc'd by thread #1
==30008==
--30008--
--30008-- used_suppression: 238 helgrind-glibc2X-005 /usr/lib/x86_64-linux-gnu/valgrind/default.supp:963
--30008-- used_suppression: 36 helgrind-glibc2X-004 /usr/lib/x86_64-linux-gnu/valgrind/default.supp:949
==30008==
==30008== ERROR SUMMARY: 13 errors from 2 contexts (suppressed: 274 from 95)
Helgrind拦截像
memcpy
这样的函数,并在vgpreload_helgrind-amd64-linux.so中使用它自己的版本。
这与问题无关。
在我看来你还有另一个功能
thread_test
,它也在做一些 I/O。您没有发布该功能的来源。 Helgrind 说你没有任何锁。
尝试对您从
thread_test
. 调用的任何 I/O 使用相同的锁