You can subscribe to this list here.
| 2002 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
(1) |
Oct
(122) |
Nov
(152) |
Dec
(69) |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 2003 |
Jan
(6) |
Feb
(25) |
Mar
(73) |
Apr
(82) |
May
(24) |
Jun
(25) |
Jul
(10) |
Aug
(11) |
Sep
(10) |
Oct
(54) |
Nov
(203) |
Dec
(182) |
| 2004 |
Jan
(307) |
Feb
(305) |
Mar
(430) |
Apr
(312) |
May
(187) |
Jun
(342) |
Jul
(487) |
Aug
(637) |
Sep
(336) |
Oct
(373) |
Nov
(441) |
Dec
(210) |
| 2005 |
Jan
(385) |
Feb
(480) |
Mar
(636) |
Apr
(544) |
May
(679) |
Jun
(625) |
Jul
(810) |
Aug
(838) |
Sep
(634) |
Oct
(521) |
Nov
(965) |
Dec
(543) |
| 2006 |
Jan
(494) |
Feb
(431) |
Mar
(546) |
Apr
(411) |
May
(406) |
Jun
(322) |
Jul
(256) |
Aug
(401) |
Sep
(345) |
Oct
(542) |
Nov
(308) |
Dec
(481) |
| 2007 |
Jan
(427) |
Feb
(326) |
Mar
(367) |
Apr
(255) |
May
(244) |
Jun
(204) |
Jul
(223) |
Aug
(231) |
Sep
(354) |
Oct
(374) |
Nov
(497) |
Dec
(362) |
| 2008 |
Jan
(322) |
Feb
(482) |
Mar
(658) |
Apr
(422) |
May
(476) |
Jun
(396) |
Jul
(455) |
Aug
(267) |
Sep
(280) |
Oct
(253) |
Nov
(232) |
Dec
(304) |
| 2009 |
Jan
(486) |
Feb
(470) |
Mar
(458) |
Apr
(423) |
May
(696) |
Jun
(461) |
Jul
(551) |
Aug
(575) |
Sep
(134) |
Oct
(110) |
Nov
(157) |
Dec
(102) |
| 2010 |
Jan
(226) |
Feb
(86) |
Mar
(147) |
Apr
(117) |
May
(107) |
Jun
(203) |
Jul
(193) |
Aug
(238) |
Sep
(300) |
Oct
(246) |
Nov
(23) |
Dec
(75) |
| 2011 |
Jan
(133) |
Feb
(195) |
Mar
(315) |
Apr
(200) |
May
(267) |
Jun
(293) |
Jul
(353) |
Aug
(237) |
Sep
(278) |
Oct
(611) |
Nov
(274) |
Dec
(260) |
| 2012 |
Jan
(303) |
Feb
(391) |
Mar
(417) |
Apr
(441) |
May
(488) |
Jun
(655) |
Jul
(590) |
Aug
(610) |
Sep
(526) |
Oct
(478) |
Nov
(359) |
Dec
(372) |
| 2013 |
Jan
(467) |
Feb
(226) |
Mar
(391) |
Apr
(281) |
May
(299) |
Jun
(252) |
Jul
(311) |
Aug
(352) |
Sep
(481) |
Oct
(571) |
Nov
(222) |
Dec
(231) |
| 2014 |
Jan
(185) |
Feb
(329) |
Mar
(245) |
Apr
(238) |
May
(281) |
Jun
(399) |
Jul
(382) |
Aug
(500) |
Sep
(579) |
Oct
(435) |
Nov
(487) |
Dec
(256) |
| 2015 |
Jan
(338) |
Feb
(357) |
Mar
(330) |
Apr
(294) |
May
(191) |
Jun
(108) |
Jul
(142) |
Aug
(261) |
Sep
(190) |
Oct
(54) |
Nov
(83) |
Dec
(22) |
| 2016 |
Jan
(49) |
Feb
(89) |
Mar
(33) |
Apr
(50) |
May
(27) |
Jun
(34) |
Jul
(53) |
Aug
(53) |
Sep
(98) |
Oct
(206) |
Nov
(93) |
Dec
(53) |
| 2017 |
Jan
(65) |
Feb
(82) |
Mar
(102) |
Apr
(86) |
May
(187) |
Jun
(67) |
Jul
(23) |
Aug
(93) |
Sep
(65) |
Oct
(45) |
Nov
(35) |
Dec
(17) |
| 2018 |
Jan
(26) |
Feb
(35) |
Mar
(38) |
Apr
(32) |
May
(8) |
Jun
(43) |
Jul
(27) |
Aug
(30) |
Sep
(43) |
Oct
(42) |
Nov
(38) |
Dec
(67) |
| 2019 |
Jan
(32) |
Feb
(37) |
Mar
(53) |
Apr
(64) |
May
(49) |
Jun
(18) |
Jul
(14) |
Aug
(53) |
Sep
(25) |
Oct
(30) |
Nov
(49) |
Dec
(31) |
| 2020 |
Jan
(87) |
Feb
(45) |
Mar
(37) |
Apr
(51) |
May
(99) |
Jun
(36) |
Jul
(11) |
Aug
(14) |
Sep
(20) |
Oct
(24) |
Nov
(40) |
Dec
(23) |
| 2021 |
Jan
(14) |
Feb
(53) |
Mar
(85) |
Apr
(15) |
May
(19) |
Jun
(3) |
Jul
(14) |
Aug
(1) |
Sep
(57) |
Oct
(73) |
Nov
(56) |
Dec
(22) |
| 2022 |
Jan
(3) |
Feb
(22) |
Mar
(6) |
Apr
(55) |
May
(46) |
Jun
(39) |
Jul
(15) |
Aug
(9) |
Sep
(11) |
Oct
(34) |
Nov
(20) |
Dec
(36) |
| 2023 |
Jan
(79) |
Feb
(41) |
Mar
(99) |
Apr
(169) |
May
(48) |
Jun
(16) |
Jul
(16) |
Aug
(57) |
Sep
(19) |
Oct
|
Nov
|
Dec
|
| S | M | T | W | T | F | S |
|---|---|---|---|---|---|---|
|
|
|
|
|
1
|
2
(13) |
3
(29) |
|
4
(18) |
5
(12) |
6
(12) |
7
(22) |
8
(9) |
9
(14) |
10
(6) |
|
11
|
12
|
13
(1) |
14
(5) |
15
(11) |
16
(7) |
17
(5) |
|
18
(1) |
19
(8) |
20
(7) |
21
(12) |
22
(5) |
23
(17) |
24
(6) |
|
25
(27) |
26
(17) |
27
(2) |
28
(10) |
29
(3) |
30
(8) |
31
(20) |
|
From: Jeremy F. <je...@go...> - 2004-01-21 21:27:33
|
On Wed, 2004-01-21 at 04:44, Nicholas Nethercote wrote: > I've attached a file that lists all the tasks now done in main(), > and their dependencies. It doesn't look very much like your list above, > Jeremy; mostly I kept the existing order of things. Valgrind has > certainly become a tricky sucker to start up. I think these dependencies > should eventually go into comments in main(); there are already some > dependencies listed for the code that was VG_(main)(), and they're very > useful. One other nice thing to do would be to drop all of stage2's use of malloc and fprintf(), and use the Valgrind equivalents (esp printf, since we want to report errors in a consistent way). Certainly mixing the use of VG_(arena_malloc)/malloc in vg_main just looks very strange. J |
|
From: Jeremy F. <je...@go...> - 2004-01-21 21:17:54
|
On Wed, 2004-01-21 at 04:44, Nicholas Nethercote wrote: > I've attached a file that lists all the tasks now done in main(), > and their dependencies. It doesn't look very much like your list above, > Jeremy; mostly I kept the existing order of things. Valgrind has > certainly become a tricky sucker to start up. Yep. I wrote my list off the top of my head, so I'm not surprised it doesn't match something which actually works. > I think these dependencies > should eventually go into comments in main(); there are already some > dependencies listed for the code that was VG_(main)(), and they're very > useful. Agreed. > There is certainly potential for the order of startup events to change, > and for neatening up, and fixing the mentioned shortcomings. However, if > nobody objects, I'd like to put this patch in sooner rather than later > since any intermediate commits could cause some pretty heinous clashes. OK. It will clash a bit with the archdep patch, but I think sooner rather than later. > Loading everything (was stage2.c:main()): > > 1. Check launched by stage 1, with scan_auxv() [must be first] > 2. Begin working out address space layout [must be second] > 3. pad from client_base..valgrind_base [must be third] > 4. get vg_argv + cl_argv, from command-line or _VALGRIND_CLO [after ?] > 5. augment vg_argv from VALGRIND_OPTS and .valgrindrc [after 4] I think _VALGRIND_CLO should exclusively take precedence over all other sources of command-line options (so if it is present, then 5 is skipped). That's because it is constructed out of vg_argv, which in turn is constructed out of all the sources when V first starts. > 6. pre-process cmd-line, to find --tool and --exec [after 5] > 7. find client, check exists [after 6] ((move to before 14/15?)) May as well fail out early? > 8. set VG_(libdir) from VALGRINDLIB [after ??] ((move to after 3?)) Earlier is better. > 9. load/map in tool [after 6] > 10. get toolinfo (esp ratio) [after 9] > 11. check interface version matches [after 10] > 11b. Set heapblock-redzone size of V's allocator [after 10] > 12. finalise address space layout (shadow area, client area) [after 10] > 13. make redzone inaccessible [after 12] > 14. make client hole [after 12] > 15. load (do_exec) client [after 14] > 16. mmap shadow memory [after 12] > 17. unpad shadow_end..0xffffffff [after 12] This should probably be shadow_end..valgrind_mmap_end; this will leave the padding covering Valgrind's heap/stack, which will prevent unwanted mappings from ending up there. This could be problematic (since the stack won't be able to grow while the padding is there), so maybe the answer is to make sure the Segment list has already blocked out Valgrind's bss/heap/stack area for mapping, and just use VG_(mmap) for address space allocation - see below at init_memory). > 18. fix_environment [after 9; others?] > 19. setup client stack [after 18] > > Valgrind + tool initialisation (was vg_main.c:VG_(main)()): > > 20. do m_state_static, inc FPU state [after 19; where is have_ssestate setup? > looks like it's always True...] m_state_static is a holdover from the old code, and isn't really necessary anymore. It's just used to bootstrap the initial thread state, but we could do it more directly. The FPU state is pretty bogus - it just needs to be a not-completely-borked state. > 21. do atfork(NULL, NULL, newpid) > 22. work out file descriptor limits, reserve some fds [after ??] > 23. read proc/self/maps into buffer [after ??] > 24. call SK_(pre_clo_init) [after ??] > 25. tool_init_dlsym to setup tool functions [after 24] > 26. process command line opts [after 25] > 27. delay to hook GDB [after ??] Needs to be after 26. > 28. SK_(post_clo_init) [after 26] > 29. setup baseBlock [after 28] > 30. init_preopened_fds [after 26] > 31. scheduler_init [after ??] It needs the initial thread state (ie, eip and esp), but that's about it. > 32. proxy_init > 33. sigstartup_action [after 31] I seem to remember the relationships between 32 and 33 are pretty subtle. > 34. init internal profiling [after ??] > 35. start RDTSC calibration [after ??] > 36. init_memory [after 23? (so we can parse proc/self/maps); complex, because > it does several things] Maybe it should be split up. The most important thing it does is initialize the Segment list. This point represents the boundary between "mmap must be used, VG_(mmap) must not be used" and "VG_(mmap) must be used, mmap must not be used". Since this is a subtle distinction, and hard to police, I think it should happen as early as possible, and just make everyone use VG_(mmap). This is a bit tricky, since ume.c/do_exec uses mmap(), but maybe we can change it to use VG_(mmap), and give stage1 a stub definition of VG_(mmap). If it uses VG_(mmap), it may also be able to encode more information about the executable in the SF_* flags. > 37. load suppressions [after 25?] > 38. end RDTSC calibration [after 35] > 39. init TT/TC [after ??] > 40. setup code redirect table [after ??] > 41. install pointercheck, if necessary [after ??] 26. I think that's the only dependency. > 42. Run! > 43. finalisation... (errors, SK_(fini), counts, exit) J |
|
From: Nicholas N. <nj...@ca...> - 2004-01-21 17:40:46
|
CVS commit by nethercote:
Make output more thread-independent.
M +1 -1 threadederrno.c 1.4 [POSSIBLY UNSAFE: printf]
M +1 -1 threadederrno.stdout.exp 1.4
--- valgrind/memcheck/tests/threadederrno.c #1.3:1.4
@@ -28,5 +28,5 @@ int main ( void )
pthread_create(&tid3, NULL, &thr3, NULL);
f = fopen("bogus", "r");
- printf("f1 = %p, errno1 = %d (%s)\n", f, errno, strerror(errno));
+ printf("f = %p, errno = %d (%s)\n", f, errno, strerror(errno));
pthread_join(tid2, NULL);
pthread_join(tid3, NULL);
--- valgrind/memcheck/tests/threadederrno.stdout.exp #1.3:1.4
@@ -1,3 +1,3 @@
-f1 = (nil), errno1 = 2 (No such file or directory)
+f = (nil), errno = 2 (No such file or directory)
f = (nil), errno = 2 (No such file or directory)
f = (nil), errno = 2 (No such file or directory)
|
|
From: Nicholas N. <nj...@ca...> - 2004-01-21 17:35:31
|
CVS commit by nethercote:
Change test so output doesn't depend on thread scheduling.
M +2 -2 threadederrno.c 1.3 [POSSIBLY UNSAFE: printf]
M +2 -2 threadederrno.stdout.exp 1.3
--- valgrind/memcheck/tests/threadederrno.c #1.2:1.3
@@ -9,5 +9,5 @@ void* thr2 ( void* v )
{
FILE* f = fopen("bogus2", "r");
- printf("f2 = %p, errno2 = %d (%s)\n", f, errno, strerror(errno));
+ printf("f = %p, errno = %d (%s)\n", f, errno, strerror(errno));
return NULL;
}
@@ -16,5 +16,5 @@ void* thr3 ( void* v )
{
FILE* f = fopen("bogus3", "r");
- printf("f3 = %p, errno3 = %d (%s)\n", f, errno, strerror(errno));
+ printf("f = %p, errno = %d (%s)\n", f, errno, strerror(errno));
return NULL;
}
--- valgrind/memcheck/tests/threadederrno.stdout.exp #1.2:1.3
@@ -1,3 +1,3 @@
f1 = (nil), errno1 = 2 (No such file or directory)
-f2 = (nil), errno2 = 2 (No such file or directory)
-f3 = (nil), errno3 = 2 (No such file or directory)
+f = (nil), errno = 2 (No such file or directory)
+f = (nil), errno = 2 (No such file or directory)
|
|
From: Nicholas N. <nj...@ca...> - 2004-01-21 16:13:26
|
CVS commit by nethercote:
Fix a bug in Cachegrind: when invalidating BBs, the lookup in the BBCC_table
sometimes failed, causing an assertion failure. This is because the debug
info for the code address, which is used in the lookup,
can change -- eg. "myprint.c:myprint()" is found at instrumentation, but by the
time the invalidation occurs, it's changed to "myprint.c:???". So it now falls
back to a slow exhaustive search of the table.
This was causing cachegrind/tests/dlclose to fail, and should hopefully fix
bug #72781.
M +68 -6 cg_main.c 1.64
--- valgrind/cachegrind/cg_main.c #1.63:1.64
@@ -400,4 +400,61 @@ static UInt hash(Char *s, UInt table_siz
}
+/* This is a backup for get_BBCC() when removing BBs from the table.
+ * Necessary because the debug info can change when code is removed. For
+ * example, when inserting, the info might be "myprint.c:myprint()", but
+ * upon removal, the info might be "myprint.c:???", which causes the
+ * hash-lookup to fail (but it doesn't always happen). So we do a horrible,
+ * slow search through all the file nodes and function nodes (but we can do
+ * 3rd stage with the fast hash-lookup). */
+static BBCC* get_BBCC_slow_removal(Addr bb_orig_addr)
+{
+ Int i, j;
+ UInt BBCC_hash;
+ file_node *curr_file_node;
+ fn_node *curr_fn_node;
+ BBCC **prev_BBCC_next_ptr, *curr_BBCC;
+
+ for (i = 0; i < N_FILE_ENTRIES; i++) {
+
+ for (curr_file_node = BBCC_table[i];
+ NULL != curr_file_node;
+ curr_file_node = curr_file_node->next)
+ {
+ for (j = 0; j < N_FN_ENTRIES; j++) {
+
+ for (curr_fn_node = curr_file_node->fns[j];
+ NULL != curr_fn_node;
+ curr_fn_node = curr_fn_node->next)
+ {
+ BBCC_hash = bb_orig_addr % N_BBCC_ENTRIES;
+ prev_BBCC_next_ptr = &(curr_fn_node->BBCCs[BBCC_hash]);
+ curr_BBCC = curr_fn_node->BBCCs[BBCC_hash];
+
+ while (NULL != curr_BBCC) {
+ if (bb_orig_addr == curr_BBCC->orig_addr) {
+ // Found it!
+ sk_assert(curr_BBCC->array_size > 0
+ && curr_BBCC->array_size < 1000000);
+ if (VG_(clo_verbosity) > 2) {
+ VG_(message)(Vg_DebugMsg, "did slow BB removal");
+ }
+
+ // Remove curr_BBCC from chain; it will be used and
+ // free'd by the caller.
+ *prev_BBCC_next_ptr = curr_BBCC->next;
+ return curr_BBCC;
+ }
+
+ prev_BBCC_next_ptr = &(curr_BBCC->next);
+ curr_BBCC = curr_BBCC->next;
+ }
+ }
+ }
+ }
+ }
+ VG_(printf)("failing BB address: %p\n", bb_orig_addr);
+ VG_(skin_panic)("slow BB removal failed");
+}
+
/* Do a three step traversal: by filename, then fn_name, then instr_addr.
* In all cases prepends new nodes to their chain. Returns a pointer to the
@@ -450,9 +507,14 @@ static BBCC* get_BBCC(Addr bb_orig_addr,
if (curr_BBCC == NULL) {
- sk_assert(False == remove);
-
+ if (remove == False) {
curr_fn_node->BBCCs[BBCC_hash] = curr_BBCC =
new_BBCC(bb_orig_addr, cb, curr_fn_node->BBCCs[BBCC_hash]);
*BB_seen_before = False;
+ } else {
+ // Ok, BB not found when removing: the debug info must have
+ // changed. Do a slow removal.
+ curr_BBCC = get_BBCC_slow_removal(bb_orig_addr);
+ *BB_seen_before = True;
+ }
} else {
@@ -461,5 +523,5 @@ static BBCC* get_BBCC(Addr bb_orig_addr,
if (VG_(clo_verbosity) > 2) {
VG_(message)(Vg_DebugMsg,
- "BB retranslation, retrieving from BBCC table");
+ "BB retranslation/invalidation, retrieving from BBCC table");
}
*BB_seen_before = True;
|
|
From: Nicholas N. <nj...@ca...> - 2004-01-21 15:08:36
|
CVS commit by nethercote:
Convert "skin" to "tool" in various places; almost entirely within comments,
nothing that will affect code.
M +1 -1 AUTHORS 1.6
M +1 -1 cachegrind/cg_main.c 1.63
M +9 -9 coregrind/vg_errcontext.c 1.50
M +3 -3 coregrind/vg_malloc2.c 1.18
M +1 -1 coregrind/vg_mylibc.c 1.65
M +2 -2 coregrind/vg_needs.c 1.15
M +1 -1 coregrind/vg_replace_malloc.c 1.18
M +4 -4 coregrind/vg_scheduler.c 1.138
M +4 -4 coregrind/vg_signals.c 1.58
M +3 -3 coregrind/vg_symtab2.c 1.74
M +1 -1 coregrind/vg_symtypes.c 1.5
M +2 -2 coregrind/vg_to_ucode.c 1.124
M +3 -3 include/valgrind.h 1.25
M +3 -3 include/vg_profile.c 1.11
M +1 -1 memcheck/mac_malloc_wrappers.c 1.10
M +3 -3 memcheck/mac_shared.h 1.17
M +1 -1 memcheck/memcheck.h 1.18
M +1 -1 tests/filter_stderr_basic 1.15
--- valgrind/AUTHORS #1.5:1.6
@@ -3,5 +3,5 @@
Nicholas Nethercote, nj...@ca..., did the core/tool
-generalisation, and wrote Cachegrind and some of the other skins.
+generalisation, and wrote Cachegrind and some of the other tools.
Jeremy Fitzhardinge, je...@go..., wrote much of Helgrind, and lots
--- valgrind/cachegrind/cg_main.c #1.62:1.63
@@ -70,5 +70,5 @@ typedef
VgpCacheResults
}
- VgpSkinCC;
+ VgpToolCC;
/*------------------------------------------------------------*/
--- valgrind/coregrind/vg_errcontext.c #1.49:1.50
@@ -421,5 +421,5 @@ void VG_(maybe_record_error) ( ThreadId
/* Second top-level entry point to the error management subsystem, for
- errors that the skin want to report immediately, eg. because they're
+ errors that the tool wants to report immediately, eg. because they're
guaranteed to only happen once. This avoids all the recording and
comparing stuff. But they can be suppressed; returns True if it is
@@ -628,7 +628,7 @@ static Bool setLocationTy ( Char** p_cal
-/* Look for "skin" in a string like "skin1,skin2,skin3" */
+/* Look for "tool" in a string like "tool1,tool2,tool3" */
static __inline__
-Bool skin_name_present(Char *name, Char *names)
+Bool tool_name_present(Char *name, Char *names)
{
Bool found;
@@ -654,5 +654,5 @@ static void load_one_suppressions_file (
Bool eof;
Char buf[N_BUF+1];
- Char* skin_names;
+ Char* tool_names;
Char* supp_name;
@@ -665,5 +665,5 @@ static void load_one_suppressions_file (
while (True) {
- /* Assign and initialise the two suppression halves (core and skin) */
+ /* Assign and initialise the two suppression halves (core and tool) */
Supp* supp;
supp = VG_(arena_malloc)(VG_AR_CORE, sizeof(Supp));
@@ -694,9 +694,9 @@ static void load_one_suppressions_file (
buf[i] = '\0'; /* Replace ':', splitting into two strings */
- skin_names = & buf[0];
+ tool_names = & buf[0];
supp_name = & buf[i+1];
/* Is it a core suppression? */
- if (VG_(needs).core_errors && skin_name_present("core", skin_names))
+ if (VG_(needs).core_errors && tool_name_present("core", tool_names))
{
if (VG_STREQ(supp_name, "PThread"))
@@ -706,7 +706,7 @@ static void load_one_suppressions_file (
}
- /* Is it a skin suppression? */
+ /* Is it a tool suppression? */
else if (VG_(needs).skin_errors &&
- skin_name_present(VG_(details).name, skin_names))
+ tool_name_present(VG_(details).name, tool_names))
{
if (SK_(recognised_suppression)(supp_name, supp))
--- valgrind/coregrind/vg_malloc2.c #1.17:1.18
@@ -255,5 +255,5 @@ void ensure_mm_init ( void )
/* Use a checked red zone size of 1 word for our internal stuff,
and an unchecked zone of arbitrary size for the client. Of
- course the client's red zone can be checked by the skin, eg.
+ course the client's red zone can be checked by the tool, eg.
by using addressibility maps, but not by the mechanism implemented
here, which merely checks at the time of freeing that the red
@@ -262,5 +262,5 @@ void ensure_mm_init ( void )
arena_init ( &vg_arena[VG_AR_CORE], "core", 1, True, 262144, False );
- arena_init ( &vg_arena[VG_AR_SKIN], "skin", 1, True, 262144, False );
+ arena_init ( &vg_arena[VG_AR_SKIN], "tool", 1, True, 262144, False );
arena_init ( &vg_arena[VG_AR_SYMTAB], "symtab", 1, True, 262144, False );
@@ -1359,5 +1359,5 @@ void* VG_(arena_realloc) ( ArenaId aid,
/*------------------------------------------------------------*/
-/* All just wrappers to avoid exposing arenas to skins */
+/* All just wrappers to avoid exposing arenas to tools */
void* VG_(malloc) ( Int nbytes )
--- valgrind/coregrind/vg_mylibc.c #1.64:1.65
@@ -1035,5 +1035,5 @@ __inline__ Char* VG_(arena_strdup) ( Are
}
-/* Wrapper to avoid exposing skins to ArenaId's */
+/* Wrapper to avoid exposing tools to ArenaId's */
Char* VG_(strdup) ( const Char* s )
{
--- valgrind/coregrind/vg_needs.c #1.14:1.15
@@ -1,5 +1,5 @@
/*--------------------------------------------------------------------*/
-/*--- Stuff relating to skin data structures. ---*/
+/*--- Stuff relating to tool data structures. ---*/
/*--- vg_needs.c ---*/
/*--------------------------------------------------------------------*/
@@ -34,5 +34,5 @@
/* ---------------------------------------------------------------------
- Skin data structure initialisation
+ Tool data structure initialisation
------------------------------------------------------------------ */
--- valgrind/coregrind/vg_replace_malloc.c #1.17:1.18
@@ -37,5 +37,5 @@
be called from within Valgrind.
- This file can be #included into a skin that wishes to know about
+ This file can be #included into a tool that wishes to know about
calls to malloc(). It should define functions SK_(malloc) et al
that will be called.
--- valgrind/coregrind/vg_scheduler.c #1.137:1.138
@@ -1115,5 +1115,5 @@ VgSchedReturnCode VG_(scheduler) ( void
VG_(exitcode) = VG_(threads)[tid].m_ebx; /* syscall arg1 */
- /* Only run __libc_freeres if the skin says it's ok and
+ /* Only run __libc_freeres if the tool says it's ok and
it hasn't been overridden with --run-libc-freeres=no
on the command line. */
@@ -2962,8 +2962,8 @@ void do_client_request ( ThreadId tid )
}
- /* Note: for skins that replace malloc() et al, we want to call
+ /* Note: for tools that replace malloc() et al, we want to call
the replacement versions. For those that don't, we want to call
VG_(cli_malloc)() et al. We do this by calling SK_(malloc)(), which
- malloc-replacing skins must replace, but have its default definition
+ malloc-replacing tools must replace, but have its default definition
call */
@@ -3281,5 +3281,5 @@ void do_client_request ( ThreadId tid )
if (!whined) {
- // Allow for requests in core, but defined by skins, which
+ // Allow for requests in core, but defined by tools, which
// have 0 and 0 in their two high bytes.
Char c1 = (arg[0] >> 24) & 0xff;
--- valgrind/coregrind/vg_signals.c #1.57:1.58
@@ -985,5 +985,5 @@ void vg_push_signal_frame ( ThreadId tid
sigNo, signame(sigNo), tid );
- /* Signal delivery to skins */
+ /* Signal delivery to tools */
VG_TRACK( pre_deliver_signal, tid, sigNo, /*alt_stack*/False );
@@ -991,5 +991,5 @@ void vg_push_signal_frame ( ThreadId tid
esp_top_of_frame = tst->m_esp;
- /* Signal delivery to skins */
+ /* Signal delivery to tools */
VG_TRACK( pre_deliver_signal, tid, sigNo, /*alt_stack*/True );
}
@@ -1171,5 +1171,5 @@ Int vg_pop_signal_frame ( ThreadId tid )
VG_(proxy_setsigmask)(tid);
- /* Notify skins */
+ /* Notify tools */
VG_TRACK( post_deliver_signal, tid, sigNo );
@@ -1686,5 +1686,5 @@ void vg_sync_signalhandler ( Int sigNo,
using some memory which had not previously been used.
This catches those faults, makes the memory accessible,
- and calls the skin to initialize that page.
+ and calls the tool to initialize that page.
*/
static Int recursion = 0;
--- valgrind/coregrind/vg_symtab2.c #1.73:1.74
@@ -1545,5 +1545,5 @@ Bool get_fnname ( Bool demangle, Addr a,
}
-/* This is available to skins... always demangle C++ names,
+/* This is available to tools... always demangle C++ names,
match anywhere in function, but don't show offsets. */
Bool VG_(get_fnname) ( Addr a, Char* buf, Int nbuf )
@@ -1554,5 +1554,5 @@ Bool VG_(get_fnname) ( Addr a, Char* buf
}
-/* This is available to skins... always demangle C++ names,
+/* This is available to tools... always demangle C++ names,
match anywhere in function, and show offset if nonzero. */
Bool VG_(get_fnname_w_offset) ( Addr a, Char* buf, Int nbuf )
@@ -1563,5 +1563,5 @@ Bool VG_(get_fnname_w_offset) ( Addr a,
}
-/* This is available to skins... always demangle C++ names,
+/* This is available to tools... always demangle C++ names,
only succeed if 'a' matches first instruction of function,
and don't show offsets. */
--- valgrind/coregrind/vg_symtypes.c #1.4:1.5
@@ -690,5 +690,5 @@ Char *VG_(describe_addr)(ThreadId tid, A
bufsz *= 2;
- /* use skin malloc so that the skin client can free it */
+ /* use tool malloc so that the skin client can free it */
n = VG_(malloc)(bufsz);
if (buf != NULL && bufidx != 0)
--- valgrind/coregrind/vg_to_ucode.c #1.123:1.124
@@ -7173,6 +7173,6 @@ Int VG_(disBB) ( UCodeBlock* cb, Addr ei
* into the `extra4b' field of the basic-block-ending JMP.
*
- * The INCEIPs and JMP.extra4b fields allows a skin to track x86
- * instruction sizes, important for some skins (eg. cache simulation).
+ * The INCEIPs and JMP.extra4b fields allows a tool to track x86
+ * instruction sizes, important for some tools (eg. Cachegrind).
*/
if (VG_(clo_single_step)) {
--- valgrind/include/valgrind.h #1.24:1.25
@@ -160,5 +160,5 @@ typedef
VG_USERREQ__COUNT_ERRORS = 0x1201,
- /* These are useful and can be interpreted by any skin that tracks
+ /* These are useful and can be interpreted by any tool that tracks
malloc() et al, by using vg_replace_malloc.c. */
VG_USERREQ__MALLOCLIKE_BLOCK = 0x1301,
@@ -274,6 +274,6 @@ VALGRIND_PRINTF_BACKTRACE(const char *fo
-/* Counts the number of errors that have been recorded by a skin. Nb:
- the skin must record the errors with VG_(maybe_record_error)() or
+/* Counts the number of errors that have been recorded by a tool. Nb:
+ the tool must record the errors with VG_(maybe_record_error)() or
VG_(unique_error)() for them to be counted. */
#define VALGRIND_COUNT_ERRORS \
--- valgrind/include/vg_profile.c #1.10:1.11
@@ -1,6 +1,6 @@
/*--------------------------------------------------------------------*/
-/*--- Profiling machinery. #include this file into a skin to ---*/
-/*--- enable --profile=yes, but not for release versions of skins, ---*/
+/*--- Profiling machinery. #include this file into a tool to ---*/
+/*--- enable --profile=yes, but not for release versions of tools, ---*/
/*--- because it uses glibc code. ---*/
/*--- vg_profile.c ---*/
@@ -77,5 +77,5 @@ void VGP_(register_profile_event) ( Int
VG_(printf)("\nProfile event #%d being registered as `%s'\n"
"already registered as `%s'.\n"
- "Note that skin and core event numbers must not overlap.\n",
+ "Note that tool and core event numbers must not overlap.\n",
n, name, vgp_names[n]);
VG_(skin_panic)("profile event already registered");
--- valgrind/memcheck/mac_malloc_wrappers.c #1.9:1.10
@@ -45,5 +45,5 @@ static UInt cmalloc_bs_mallocd = 0;
UInt VG_(vg_malloc_redzone_szB) = 16;
-/* Function pointers for the two skins to track interesting events. */
+/* Function pointers for the two tools to track interesting events. */
void (*MAC_(new_mem_heap)) ( Addr a, UInt len, Bool is_inited ) = NULL;
void (*MAC_(ban_mem_heap)) ( Addr a, UInt len ) = NULL;
--- valgrind/memcheck/mac_shared.h #1.16:1.17
@@ -155,5 +155,5 @@ typedef
/*------------------------------------------------------------*/
-/*--- Profiling of skins and memory events ---*/
+/*--- Profiling of tools and memory events ---*/
/*------------------------------------------------------------*/
@@ -164,5 +164,5 @@ typedef
VgpESPAdj
}
- VgpSkinCC;
+ VgpToolCC;
/* Define to collect detailed performance info. */
@@ -271,5 +271,5 @@ extern void MAC_(print_common_debug_usag
extern VgHashTable MAC_(malloc_list);
-/* Function pointers for the two skins to track interesting events. */
+/* Function pointers for the two tools to track interesting events. */
extern void (*MAC_(new_mem_heap)) ( Addr a, UInt len, Bool is_inited );
extern void (*MAC_(ban_mem_heap)) ( Addr a, UInt len );
--- valgrind/memcheck/memcheck.h #1.17:1.18
@@ -83,5 +83,5 @@ typedef
/* These two have been moved into core, because they are useful for
- any skin that tracks heap blocks. Hence the suffix. But they're
+ any tool that tracks heap blocks. Hence the suffix. But they're
still here for backwards compatibility, although Valgrind will
abort with an explanatory message if you use them. */
--- valgrind/tests/filter_stderr_basic #1.14:1.15
@@ -8,5 +8,5 @@
# Remove "<name>, a <description> for x86-linux." line and the following
-# copyright notice line. Works for skin and core intro lines.
+# copyright notice line. Works for tool and core intro lines.
sed "/^.*, .* for x86-linux\./ , /./ d" |
|
|
From: Nicholas N. <nj...@ca...> - 2004-01-21 13:59:59
|
CVS commit by nethercote:
Updated the manual for some recent changes, esp. the fact that Memcheck is no
longer the default.
M +70 -82 coregrind/docs/coregrind_core.html 1.22
M +34 -50 coregrind/docs/coregrind_intro.html 1.8
M +5 -7 docs/manual.html 1.47
--- valgrind/docs/manual.html #1.46:1.47
@@ -27,5 +27,5 @@
<a name="title"> </a>
<h1 align=center>Valgrind, version 2.1.0</h1>
-<center>This manual was last updated on 14 December 2003</center>
+<center>This manual was last updated on 21 January 2004</center>
<p>
@@ -53,11 +53,7 @@
1.2 <a href="coregrind_intro.html#intro-navigation">
How to navigate this manual</a>
- <br>
- 1.2.1 <a href="coregrind_intro.html#intro-migrating">
- For users migrating from valgrind-1.0.X</a>
<h4>2 <a href="coregrind_core.html#core">
- Using and understanding the Valgrind core services
- </a></h4>
+ Using and understanding the Valgrind core</a></h4>
2.1 <a href="coregrind_core.html#core-whatdoes">
What it does with your program</a><br>
@@ -88,4 +84,6 @@
2.14 <a href="coregrind_core.html#example">
An example run</a><br>
+ 2.15 <a href="coregrind_core.html#warnings">
+ Warning messages you might see</a><br>
<h4>3 <a href="mc_main.html#mc-top">
@@ -111,5 +109,5 @@
<p>
The following are not part of the user manual. They describe internal
-details of how Valgrind works. Reading them may rot your mind. You
+details of how Valgrind works. Reading them may rot your brain. You
have been warned.
--- valgrind/coregrind/docs/coregrind_core.html #1.21:1.22
@@ -2,7 +2,7 @@
<a name="core"></a>
-<h2>2 Using and understanding the Valgrind core services</h2>
+<h2>2 Using and understanding the Valgrind core</h2>
-This section describes the core services, flags and behaviours. That
+This section describes the Valgrind core services, flags and behaviours. That
means it is relevant regardless of what particular tool you are using.
A point of terminology: most references to "valgrind" in the rest of
@@ -15,28 +15,24 @@
Valgrind is designed to be as non-intrusive as possible. It works
directly with existing executables. You don't need to recompile,
-relink, or otherwise modify, the program to be checked. Simply place
-the word <code>valgrind</code> at the start of the command line
-normally used to run the program, and tell it what tool you want to
-use.
+relink, or otherwise modify, the program to be checked.
-<p>
-So, for example, if you want to run the command <code>ls -l</code>
-using the heavyweight memory-checking tool, issue the command:
-<code>valgrind --tool=memcheck ls -l</code>. The <code>--tool=</code>
-parameter tells the core which tool is to be used.
-
-<p>
-To preserve compatibility with the 1.0.X series, if you do not specify
-a tool, the default is to use Memcheck. That means the above
-example simplifies to: <code>valgrind ls -l</code>.
+Simply put <code>valgrind --tool=<i>tool_name</i></code> at the start of
+the command line normally used to run the program. For example,
+if want to run the command <code>ls -l</code>
+using the heavyweight memory-checking tool Memcheck, issue the command:
+
+ <blockquote>
+ <code>valgrind --tool=memcheck ls -l</code>.
+ </blockquote>
<p>Regardless of which tool is in use, Valgrind takes control of your
program before it starts. Debugging information is read from the
-executable and associated libraries, so that error messages can be
-phrased in terms of source code locations (if that is appropriate).
+executable and associated libraries, so that error messages and other
+outputs can be phrased in terms of source code locations (if that is
+appropriate)
<p>
Your program is then run on a synthetic x86 CPU provided by the
-valgrind core. As new code is executed for the first time, the core
+Valgrind core. As new code is executed for the first time, the core
hands the code to the selected tool. The tool adds its own
instrumentation code to this and hands the result back to the core,
@@ -49,6 +45,6 @@
code at least 12 times, and making it run 25-50 times slower than
natively. At the other end of the spectrum, the ultra-trivial "none"
-tool adds no instrumentation at all and causes in total "only" about a
-4 times slowdown.
+tool (a.k.a. Nulgrind) adds no instrumentation at all and causes in total
+"only" about a 4 times slowdown.
<p>
@@ -60,27 +56,21 @@
<p>
-If -- as is usually the case -- you're using one of the
-error-detection tools, valgrind will often detect errors in
-libraries, for example the GNU C or X11 libraries, which you have to
-use. Since you're probably using valgrind to debug your own
-application, and not those libraries, you don't want to see those
-errors and probably can't fix them anyway.
-
-<p>
-So, rather than swamping you with errors in which you are not
-interested, Valgrind allows you to selectively suppress errors, by
-recording them in a suppressions file which is read when Valgrind
-starts up. The build mechanism attempts to select suppressions which
-give reasonable behaviour for the libc and XFree86 versions detected
-on your machine. To make it easier to write suppressions, you can use
-the <code>--gen-suppressions=yes</code> option which tells Valgrind to
-print out a suppression for each error that appears, which you can
-then copy into a suppressions file.
-
-<p>
-Different tools report different kinds of errors. The suppression
-mechanism therefore allows you to say which tool or tool(s) each
-suppression applies to.
-
+If you're using one of the error-detection tools, Valgrind will often
+detect errors in libraries, for example the GNU C or X11 libraries,
+which you have to use. You might not be interested in these errors,
+since you probably have noo control over that code. Therefore, Valgrind
+allows you to selectively suppress errors, by recording them in a
+suppressions file which is read when Valgrind starts up. The build
+mechanism attempts to select suppressions which give reasonable
+behaviour for the libc and XFree86 versions detected on your machine.
+To make it easier to write suppressions, you can use the
+<code>--gen-suppressions=yes</code> option which tells Valgrind to print
+out a suppression for each error that appears, which you can then copy
+into a suppressions file.
+
+<p>
+Different error-checking tools report different kinds of errors. The
+suppression mechanism therefore allows you to say which tool or tool(s)
+each suppression applies to.
@@ -90,5 +80,5 @@
First off, consider whether it might be beneficial to recompile your
application and supporting libraries with debugging info enabled (the
-<code>-g</code> flag). Without debugging info, the best valgrind
+<code>-g</code> flag). Without debugging info, the best Valgrind tools
will be able to do is guess which function a particular piece of code
belongs to, which makes both error messages and profiling output
@@ -101,5 +91,5 @@
function-call chain, which can help reduce confusion when navigating
around large C++ apps. For whatever it's worth, debugging
-OpenOffice.org with Valgrind is a bit easier when using this flag.
+OpenOffice.org with Memcheck is a bit easier when using this flag.
<p>
@@ -110,6 +100,6 @@
<p>
-This paragraph applies only if you plan to use Memcheck
-(which is the default): On rare occasions, optimisation levels
+This paragraph applies only if you plan to use Memcheck:
+On rare occasions, optimisation levels
at <code>-O2</code> and above have been observed to generate code which
fools Memcheck into wrongly reporting uninitialised value
@@ -133,5 +123,5 @@
<p>
When you're ready to roll, just run your application as you would
-normally, but place <code>valgrind --tool=the-selected-tool</code> in
+normally, but place <code>valgrind --tool=<i>tool_name</i></code> in
front of your usual command-line invocation. Note that you should run
the real (machine-code) executable here. If your application is
@@ -148,5 +138,5 @@
<h3>2.3 The commentary</h3>
-Valgrind writes a commentary, a stream of text, detailing error
+Valgrind tools write a commentary, a stream of text, detailing error
reports and other significant events. All lines in the commentary
have following form:<br>
@@ -160,5 +150,5 @@
become merged together, for whatever reason.
-<p>By default, Valgrind writes only essential messages to the commentary,
+<p>By default, Valgrind tools write only essential messages to the commentary,
so as to avoid flooding you with information of secondary importance.
If you want more information about what is happening, re-run, passing
@@ -166,6 +156,5 @@
<p>
-Version 2 of valgrind gives significantly more flexibility than 1.0.X
-does about where that stream is sent to. You have three options:
+You can direct the commentary to three different places:
<ul>
@@ -196,7 +185,6 @@
in the sources.
<p>
- Note, unfortunately, that you have to use an IP address here --
- for technical reasons, valgrind's core itself can't use the GNU C
- library, and this makes it difficult to do hostname-to-IP lookups.
+ Note, unfortunately, that you have to use an IP address here, rather
+ than a hostname.
<p>
Writing to a network socket is pretty useless if you don't have
@@ -222,10 +210,10 @@
the default (1500). The specified port must be in the range
1024 to 65535. The same restriction applies to port numbers
- specified by a <code>--logsocket=</code> to valgrind itself.
+ specified by a <code>--logsocket=</code> to Valgrind itself.
</ul>
<p>
If a valgrinded process fails to connect to a listener, for
whatever reason (the listener isn't running, invalid or
- unreachable host or port, etc), valgrind switches back to writing
+ unreachable host or port, etc), Valgrind switches back to writing
the commentary to stderr. The same goes for any process which
loses an established connection to a listener. In other words,
@@ -236,5 +224,5 @@
Here is an important point about the relationship between the
commentary and profiling output from tools. The commentary contains a
-mix of messages from the valgrind core and the selected tool. If the
+mix of messages from the Valgrind core and the selected tool. If the
tool reports errors, it will report them to the commentary. However,
if the tool does profiling, the profile data will be written to a file
@@ -312,5 +300,5 @@
<p>
To avoid this cutoff you can use the <code>--error-limit=no</code>
-flag. Then valgrind will always show errors, regardless of how many
+flag. Then Valgrind will always show errors, regardless of how many
there are. Use this flag carefully, since it may have a dire effect
on performance.
@@ -387,5 +375,5 @@
(Nb: no spaces are allowed).
<p>
- Recall that valgrind-2.0.X is a modular system, in which
+ Recall that Valgrind-2.0.X is a modular system, in which
different instrumentation tools can observe your program whilst
it is running. Since different tools detect different kinds of
@@ -479,5 +467,5 @@
-As mentioned above, valgrind's core accepts a common set of flags.
+As mentioned above, Valgrind's core accepts a common set of flags.
The tools also accept tool-specific flags, which are documented
seperately for each tool.
@@ -485,10 +473,10 @@
You invoke Valgrind like this:
<pre>
- valgrind [options-for-Valgrind] your-prog [options for your-prog]
+ valgrind --tool=<i>tool_name</i> [options-for-Valgrind] your-prog [options for your-prog]
</pre>
<p>Note that Valgrind also reads options from the environment variable
<code>$VALGRIND_OPTS</code>, and processes them before the command-line
-options. Options for the valgrind core may be freely mixed with those
+options. Options for the Valgrind core may be freely mixed with those
for the selected tool.
@@ -514,5 +502,5 @@
<li><code>--version</code><br> <p>Show the version number of the
- valgrind core. Tools can have their own version numbers. There
+ Valgrind core. Tools can have their own version numbers. There
is a scheme in place to ensure that tools only execute when the
core version is one they are known to work with. This was done
@@ -559,5 +547,5 @@
the specified port at the specified IP address. The port may be
omitted, in which case port 1500 is used. If a connection
- cannot be made to the specified socket, valgrind falls back to
+ cannot be made to the specified socket, Valgrind falls back to
writing output to the standard error (stderr). This option is
intended to be used in conjunction with the
@@ -604,5 +592,5 @@
<li><code>--error-limit=yes</code> [default]<br>
- <code>--error-limit=no</code> <p>When enabled, valgrind stops
+ <code>--error-limit=no</code> <p>When enabled, Valgrind stops
reporting errors after 30000 in total, or 300 different ones,
have been seen. This is to stop the error tracking machinery
@@ -720,5 +708,5 @@
<ul>
<li><code>--alignment=<number></code> [default: 4]<br> <p>By
- default valgrind's <code>malloc</code>, <code>realloc</code>,
+ default Valgrind's <code>malloc</code>, <code>realloc</code>,
etc, return 4-byte aligned addresses. These are suitable for
any accesses on x86 processors.
@@ -778,5 +766,5 @@
7.1. So this flag is provided in order to inhibit the run of
<code>__libc_freeres</code>. If your program seems to run fine
- on valgrind, but segfaults at exit, you may find that
+ on Valgrind, but segfaults at exit, you may find that
<code>--run-libc-freeres=no</code> fixes that, although at the
cost of possibly falsely reporting space leaks in
@@ -890,7 +878,7 @@
<li><code>--profile=no</code><br>
<code>--profile=yes</code> [default]
- <p>When enabled, does crude internal profiling of valgrind
+ <p>When enabled, does crude internal profiling of Valgrind
itself. This is not for profiling your programs. Rather it is
- to allow the developers to assess where valgrind is spending
+ to allow the developers to assess where Valgrind is spending
its time. The tools must be built for profiling for this to
work.
@@ -994,5 +982,5 @@
debugging a JITter or some other dynamic code generation system.
After this call, attempts to execute code in the invalidated
- address range will cause valgrind to make new translations of that
+ address range will cause Valgrind to make new translations of that
code, which is probably the semantics you want. Note that this is
implemented naively, and involves checking all 200191 entries in
@@ -1078,5 +1066,5 @@
similar, bugs.
<p>
-As of the valgrind-1.0 release, the state of pthread support was as follows:
+As of the Valgrind-1.0 release, the state of pthread support was as follows:
<ul>
<li>Mutexes, condition variables, thread-specific data,
@@ -1214,5 +1202,5 @@
If you describe your program's memory management scheme
using "client requests" (Section 3.7 of this manual),
- valgrind can do better. Nevertheless, using malloc/new
+ Memcheck can do better. Nevertheless, using malloc/new
and free/delete is still the best approach.
</li>
@@ -1480,14 +1468,8 @@
</pre>
<p>The GCC folks fixed this about a week before gcc-3.0 shipped.
-<hr width="100%">
<p>
-</body>
-</html>
-
-
-<h2>Misc text looking for a home</h2>
-
-<h4>2.6.6 Warning messages you might see</h4>
+<a name="warnings"></a>
+<h3>2.15 Warning messages you might see</h3>
Most of these only appear if you run in verbose mode (enabled by
@@ -1551,2 +1533,8 @@
developers, to do with memory permissions.
</ul>
+
+</body>
+</html>
+
+
+
--- valgrind/coregrind/docs/coregrind_intro.html #1.7:1.8
@@ -40,24 +40,4 @@
difficult-to-diagnose crashes.
<p>
-<li><b>Cachegrind</b> is a cache profiler. It performs detailed simulation of
- the I1, D1 and L2 caches in your CPU and so can accurately
- pinpoint the sources of cache misses in your code. If you desire,
- it will show the number of cache misses, memory references and
- instructions accruing to each line of source code, with
- per-function, per-module and whole-program summaries. If you ask
- really nicely it will even show counts for each individual x86
- instruction.
- <p>
- Cachegrind auto-detects your machine's cache configuration
- using the <code>CPUID</code> instruction, and so needs no further
- configuration info, in most cases.
- <p>
- Cachegrind is nicely complemented by Josef Weidendorfer's
- amazing KCacheGrind visualisation tool (<A
- HREF="http://kcachegrind.sourceforge.net">
- http://kcachegrind.sourceforge.net</A>), a KDE application which
- presents these profiling results in a graphical and
- easier-to-understand form.
-<p>
<li><b>Addrcheck</b> is a lightweight version of
Memcheck. It is identical to Memcheck except
@@ -85,4 +65,24 @@
all the addressing errors that appear.
<p>
+<li><b>Cachegrind</b> is a cache profiler. It performs detailed simulation of
+ the I1, D1 and L2 caches in your CPU and so can accurately
+ pinpoint the sources of cache misses in your code. If you desire,
+ it will show the number of cache misses, memory references and
+ instructions accruing to each line of source code, with
+ per-function, per-module and whole-program summaries. If you ask
+ really nicely it will even show counts for each individual x86
+ instruction.
+ <p>
+ Cachegrind auto-detects your machine's cache configuration
+ using the <code>CPUID</code> instruction, and so needs no further
+ configuration info, in most cases.
+ <p>
+ Cachegrind is nicely complemented by Josef Weidendorfer's
+ amazing KCacheGrind visualisation tool (<A
+ HREF="http://kcachegrind.sourceforge.net">
+ http://kcachegrind.sourceforge.net</A>), a KDE application which
+ presents these profiling results in a graphical and
+ easier-to-understand form.
+<p>
<li><b>Helgrind</b> finds data races in multithreaded programs.
Helgrind looks for
@@ -105,5 +105,5 @@
A number of minor tools (<b>corecheck</b>, <b>lackey</b> and
-<b>none</b>) are also supplied. These aren't particularly useful --
+<b>Nulgrind</b>) are also supplied. These aren't particularly useful --
they exist to illustrate how to create simple tools and to help the
valgrind developers in various ways.
@@ -138,20 +138,16 @@
<h3>1.2 How to navigate this manual</h3>
-Valgrind is structured as a set of core services supporting a number
-of profiling and debugging tools. This manual is structured
-similarly. Below, we continue with a description of the valgrind
-core, how to use it, and the flags it supports.
-
-<p>
-The tools each have their own chapters in this manual. You only need
-to read the documentation for the core services and for the tool(s)
-you actually use, although you may find it helpful to be at least a
-little bit familar with what all tools do. If you want to write a new
-tool, read <A HREF="coregrind_tools.html">this</A>.
-
-<p>
-If you're new to all this, you're most likely to be using the Memcheck
-tool, since that's the one selected by default. So, read the rest of
-this page, and the section Memcheck.
+The Valgrind distribution consists of the Valgrind core, upon which are
+built Valgrind tools, which do different kinds of debugging and
+profiling. This manual is structured similarly.
+
+<p>
+First, we describe the Valgrind core, how to use it, and the flags it
+supports. Then, each tool has its own chapter in this manual. You only
+need to read the documentation for the core and for the tool(s) you
+actually use, although you may find it helpful to be at least a little
+bit familar with what all tools do. If you're new to all this, you
+probably want to run the Memcheck tool. If you want to write a new tool,
+read <A HREF="coregrind_tools.html">this</A>.
<p>
@@ -160,19 +156,7 @@
there is no central place describing all the flags that are accepted
-- you have to read the flags documentation both for
-<A HREF="coregrind_core.html#core">valgrind's core</A>
+<A HREF="coregrind_core.html#core">Valgrind's core</A>
and for the tool you want to use.
<p>
-<a name="intro-migrating"></a>
-<h4>1.2.1 For users migrating from valgrind-1.0.X</h4>
-<p>
-Valgrind-2.0.X is a major redesign of the 1.0.X series. You should at
-least be familiar with the concept of the core/tool division,
-as explained above in the Introduction. Having said that, we've tried
-to make the command line handling and behaviour as
-backwards-compatible as we can. In particular, just running
-<code>valgrind [args-for-valgrind] my_prog [args-for-my-prog]</code>
-should work pretty much as before.
-
-<p>
|
|
From: Nicholas N. <nj...@ca...> - 2004-01-21 12:44:39
|
[apologies if you receive this twice; if so, please ignore the first version as it had mistakes] On Sat, 10 Jan 2004, Jeremy Fitzhardinge wrote: > So, I think the init ordering should be: > > 1. stage1 > 1. pad the client address space > 2. do_exec stage2 > 2. stage2:main() > 1. (do something to cope with .init sections of any > libraries we're using) > 2. initialize Segment list to reflect all current mappings > (VG_(init_memory) > 3. init Valgrind heap, make mmap() call VG_(mmap), deal > with brk/sbrk. > 4. init early error reporting (ie default output sink) > 5. set up any other padding > 6. collate arguments from all the possible sources, > generating a unified vg_argv[] array > 3. stage2:VG_(main)() > 1. parse vg_argv > 2. print errors/usage/early failures > 3. dlopen() the tool > 4. init everything else (may need to be after > do_exec(client) if it depends on the shape/placement of > the client address space) > 5. remove all padding/clear all mappings out of client > address space > 6. do_exec client/set up client stack > 7. start VCPU > > As you say, the break between main() and VG_(main) is pretty arbitrary. > Perhaps we should just drop stage2.c, move everything into vg_main.c, > rename VG_(main)() to main(), get rid of KickStartParams (another > historical name). I have a patch that does this -- removes stage2.c, moving it into vg_main.c. This allowed me to remove quite a lot of cruft, because the two were pretty closely intertwined. It also includes my .valgrindrc stuff, and a fix for bug 71126, as previously mentioned. It's at www.cl.cam.ac.uk/~njn25/startup-merge.patch (too big to mail). There are a couple of shortcomings still: no support for quoting in the .valgrindrc files, which Tom wants, and tool-specific CLOs can't have colons in them, which Josef wants. It seems to work ok. I tried my best to just refactor things, and not change any actual behaviour. I've attached a file that lists all the tasks now done in main(), and their dependencies. It doesn't look very much like your list above, Jeremy; mostly I kept the existing order of things. Valgrind has certainly become a tricky sucker to start up. I think these dependencies should eventually go into comments in main(); there are already some dependencies listed for the code that was VG_(main)(), and they're very useful. There is certainly potential for the order of startup events to change, and for neatening up, and fixing the mentioned shortcomings. However, if nobody objects, I'd like to put this patch in sooner rather than later since any intermediate commits could cause some pretty heinous clashes. N |
|
From: Nicholas N. <nj...@ca...> - 2004-01-21 12:02:57
|
On Sat, 10 Jan 2004, Jeremy Fitzhardinge wrote: > So, I think the init ordering should be: > > 1. stage1 > 1. pad the client address space > 2. do_exec stage2 > 2. stage2:main() > 1. (do something to cope with .init sections of any > libraries we're using) > 2. initialize Segment list to reflect all current mappings > (VG_(init_memory) > 3. init Valgrind heap, make mmap() call VG_(mmap), deal > with brk/sbrk. > 4. init early error reporting (ie default output sink) > 5. set up any other padding > 6. collate arguments from all the possible sources, > generating a unified vg_argv[] array > 3. stage2:VG_(main)() > 1. parse vg_argv > 2. print errors/usage/early failures > 3. dlopen() the tool > 4. init everything else (may need to be after > do_exec(client) if it depends on the shape/placement of > the client address space) > 5. remove all padding/clear all mappings out of client > address space > 6. do_exec client/set up client stack > 7. start VCPU > > As you say, the break between main() and VG_(main) is pretty arbitrary. > Perhaps we should just drop stage2.c, move everything into vg_main.c, > rename VG_(main)() to main(), get rid of KickStartParams (another > historical name). Attached is a draft patch that does this -- removes stage2.c, moving it into vg_main.c. This allowed me to remove quite a lot of cruft, because the two were pretty closely intertwined. It also includes my .valgrindrc stuff, and a fix for bug 71126, as previously mentioned. There are a couple of shortcomings still: no support for quoting in the .valgrindrc files, which Tom wants, and tool-specific CLOs can't have colons in them, which Josef wants. It seems to work ok (modulo the TLS patch that just went in and breaks pthreaded programs for me, but that happens without my startup-merge patch too). I tried my best to just refactor things, and not change any actual behaviour. I've attached another file that lists all the tasks now done in main(), and their dependencies. It doesn't look very much like your list above, Jeremy; mostly I kept the existing order of things. Valgrind has certainly become a tricky sucker to start up. I think these dependencies should eventually go into comments in main(); there are already some dependencies listed for the code that was VG_(main)(), and they're very useful. There is certainly potential for the order of startup events to change, and for neatening up, and fixing the mentioned shortcomings. However, if nobody objects, I'd like to put this patch in sooner rather than later since any intermediate commits could cause some pretty heinous clashes. N |
|
From: Jeremy F. <je...@go...> - 2004-01-21 01:28:04
|
CVS commit by fitzhardinge:
This change implements the TLS extension to the x86 ABI. This allows
threads to have thread-private data which is quickly accessible via a
segment in the GDT, stored in %gs. The patch implements the relevent
syscalls (setthreadarea), and also manages switching the VCPU's segment
information at thread context-switch time. Mostly Tom Hughes' work.
A none/tests/tls.c 1.1 [POSSIBLY UNSAFE: printf] [no copyright]
A none/tests/tls.stderr.exp 1.1
A none/tests/tls.stdout.exp 1.1
A none/tests/tls.vgtest 1.1
A none/tests/tls2.c 1.1 [no copyright]
A none/tests/tls2_so.c 1.1 [no copyright]
A none/tests/tls_so.c 1.1 [no copyright]
M +23 -0 glibc-2.3.supp 1.10
M +1 -1 coregrind/Makefile.am 1.63
M +0 -10 coregrind/stage2.c 1.7
M +15 -0 coregrind/vg_execontext.c 1.15
M +18 -0 coregrind/vg_include.h 1.170
M +120 -24 coregrind/vg_ldt.c 1.12
M +190 -36 coregrind/vg_libpthread.c 1.144
M +6 -1 coregrind/vg_main.c 1.138
M +9 -0 coregrind/vg_proxylwp.c 1.13
M +30 -2 coregrind/vg_scheduler.c 1.137
M +69 -9 coregrind/vg_syscalls.c 1.80
M +13 -0 include/vg_kerneliface.h 1.12
M +14 -1 none/tests/Makefile.am 1.23
M +2 -2 none/tests/seg_override.c 1.2
--- valgrind/glibc-2.3.supp #1.9:1.10
@@ -130,4 +130,9 @@
fun:_dl_runtime_resolve
}
+{
+ _dl_fini
+ Helgrind:Eraser
+ fun:_dl_fini
+}
#-------- Threading bugs?
@@ -192,2 +197,20 @@
obj:/lib/ld-2.3.2.so
}
+
+##----------------------------------------------------------------------##
+## SuSE 9 after FV changes (post 2.1.0)
+
+{
+ strlen/_dl_init_paths/dl_main/_dl_sysdep_start(Cond)
+ Memcheck:Cond
+ fun:strlen
+ fun:_dl_init_paths
+ fun:dl_main
+ fun:_dl_sysdep_start
+}
+
+{
+ Ugly strchr error in /lib/ld-2.3.2.so
+ Memcheck:Cond
+ obj:/lib/ld-2.3.2.so
+}
--- valgrind/coregrind/Makefile.am #1.62:1.63
@@ -109,5 +109,5 @@
libpthread_so_DEPENDENCIES = $(srcdir)/vg_libpthread.vs
libpthread_so_LDFLAGS = -Werror -fno-omit-frame-pointer -UVG_LIBDIR \
- -shared -fpic \
+ -shared -fpic -ldl \
-Wl,-version-script $(srcdir)/vg_libpthread.vs \
-Wl,-z,nodelete \
--- valgrind/coregrind/stage2.c #1.6:1.7
@@ -473,5 +473,4 @@ static void list_tools(void)
1. LD_LIBRARY_PATH=$VALGRINDLIB:$LD_LIBRARY_PATH
2. LD_PRELOAD=$VALGRINDLIB/vg_inject.so:($VALGRINDLIB/vgpreload_TOOL.so:)?$LD_PRELOAD
- 3. LD_ASSUME_KERNEL=2.4.1
If any of these is missing, then it is added.
@@ -489,11 +488,8 @@ static char **fix_environment(char **ori
static const char ld_preload[] = "LD_PRELOAD=";
static const int ld_preload_len = sizeof(ld_preload)-1;
- static const char ld_assume_kernel[] = "LD_ASSUME_KERNEL=";
- static const int ld_assume_kernel_len = sizeof(ld_assume_kernel)-1;
static const char valgrind_clo[] = VALGRINDCLO "=";
static const char valgrind_clo_len = sizeof(valgrind_clo)-1;
int ld_preload_done = 0;
int ld_library_path_done = 0;
- int ld_assume_kernel_done = 0;
char *inject_path;
int inject_path_len;
@@ -571,7 +567,4 @@ static char **fix_environment(char **ori
ld_preload_done = 1;
- } else if (memcmp(*cpp, ld_assume_kernel, ld_assume_kernel_len) == 0) {
- *cpp = "LD_ASSUME_KERNEL=2.4.1";
- ld_assume_kernel_done = 1;
} else if (memcmp(*cpp, valgrind_clo, valgrind_clo_len) == 0) {
*cpp = "";
@@ -601,7 +594,4 @@ static char **fix_environment(char **ori
}
- if (!ld_assume_kernel_done)
- ret[envc++] = "LD_ASSUME_KERNEL=2.4.1";
-
ret[envc] = NULL;
--- valgrind/coregrind/vg_execontext.c #1.14:1.15
@@ -320,4 +320,19 @@ void get_needed_regs(ThreadId tid, Addr*
*stack_highest_word = tst->stack_highest_word;
}
+
+ /* Nasty little hack to deal with sysinfo syscalls - if libc is
+ using the sysinfo page for syscalls (the TLS version does), then
+ eip will always appear to be in that page when doing a syscall,
+ not the actual libc function doing the syscall. This check sees
+ if EIP is within the syscall code, and pops the return address
+ off the stack so that eip is placed within the library function
+ calling the syscall. This makes stack backtraces much more
+ useful. */
+ if (*eip >= VG_(client_trampoline_code)+VG_(tramp_syscall_offset) &&
+ *eip < VG_(client_trampoline_code)+VG_(trampoline_code_length) &&
+ VG_(is_addressable)(*esp, sizeof(Addr))) {
+ *eip = *(Addr *)*esp;
+ *esp += sizeof(Addr);
+ }
}
--- valgrind/coregrind/vg_include.h #1.169:1.170
@@ -625,4 +625,6 @@ extern VgLdtEntry*
extern void
VG_(deallocate_LDT_for_thread) ( VgLdtEntry* ldt );
+extern void
+ VG_(clear_TLS_for_thread) ( VgLdtEntry* tls );
/* Simulate the modify_ldt syscall. */
@@ -630,4 +632,10 @@ extern Int VG_(sys_modify_ldt) ( ThreadI
Int func, void* ptr, UInt bytecount );
+/* Simulate the {get,set}_thread_area syscalls. */
+extern Int VG_(sys_set_thread_area) ( ThreadId tid,
+ struct vki_modify_ldt_ldt_s* info );
+extern Int VG_(sys_get_thread_area) ( ThreadId tid,
+ struct vki_modify_ldt_ldt_s* info );
+
/* Called from generated code. Given a segment selector and a virtual
address, return a linear address, and do limit checks too. */
@@ -804,4 +812,8 @@ typedef
VgLdtEntry* ldt;
+ /* TLS table. This consists of a small number (currently 3) of
+ entries from the Global Descriptor Table. */
+ VgLdtEntry tls[VKI_GDT_TLS_ENTRIES];
+
/* Saved machine context. Note the FPU state, %EIP and segment
registers are not shadowed.
@@ -1623,4 +1635,7 @@ extern void VG_(proxy_handlesig)( const
const struct vki_sigcontext *sigcontext );
+/* Get the PID/TID of the ProxyLWP. */
+extern Int VG_(proxy_id)(ThreadId tid);
+
/* ---------------------------------------------------------------------
@@ -1831,4 +1846,7 @@ extern Int VGOFF_(sh_eflags);
extern Int VGOFF_(ldt);
+/* This thread's TLS pointer. */
+extern Int VGOFF_(tls);
+
/* Nb: Most helper offsets are in include/vg_skin.h, for use by skins */
--- valgrind/coregrind/vg_ldt.c #1.11:1.12
@@ -122,4 +122,22 @@ void VG_(deallocate_LDT_for_thread) ( Vg
+/* Clear a TLS array. */
+void VG_(clear_TLS_for_thread) ( VgLdtEntry* tls )
+{
+ VgLdtEntry* tlsp;
+
+ if (0)
+ VG_(printf)("clear_TLS_for_thread\n" );
+
+ for (tlsp = tls; tlsp < tls + VKI_GDT_TLS_ENTRIES; tlsp++) {
+ tlsp->LdtEnt.Words.word1 = 0;
+ tlsp->LdtEnt.Words.word2 = 0;
+ }
+
+ return;
+}
+
+
+
/* Fish the base field out of an VgLdtEntry. This is the only part we
are particularly interested in. */
@@ -152,7 +170,7 @@ unsigned int wine_ldt_get_limit( const V
Addr VG_(do_useseg) ( UInt seg_selector, Addr virtual_addr )
{
+ UInt table;
Addr base;
UInt limit;
- VgLdtEntry* the_ldt;
if (0)
@@ -162,11 +180,27 @@ Addr VG_(do_useseg) ( UInt seg_selector,
seg_selector &= 0x0000FFFF;
- /* Sanity check the segment selector. Ensure that TI=1 (LDT) and
- that RPL=11b (least privilege). These form the bottom 3 bits
- of the selector. */
- vg_assert((seg_selector & 7) == 7);
+ /* Sanity check the segment selector. Ensure that RPL=11b (least
+ privilege). This forms the bottom 2 bits of the selector. */
+ vg_assert((seg_selector & 3) == 3);
- /* convert it onto a table index */
+ /* Extract the table number */
+ table = (seg_selector & 4) >> 2;
+
+ /* Convert the segment selector onto a table index */
seg_selector >>= 3;
+
+ if (table == 0) {
+ VgLdtEntry* the_tls;
+
+ vg_assert(seg_selector >= VKI_GDT_TLS_MIN && seg_selector < VKI_GDT_TLS_MAX);
+
+ /* Come up with a suitable GDT entry. We look at the thread's TLS
+ array, which is pointed to by a VG_(baseBlock) entry. */
+ the_tls = (VgLdtEntry*)VG_(baseBlock)[VGOFF_(tls)];
+ base = (Addr)wine_ldt_get_base ( &the_tls[seg_selector-VKI_GDT_TLS_MIN] );
+ limit = (UInt)wine_ldt_get_limit ( &the_tls[seg_selector-VKI_GDT_TLS_MIN] );
+ } else {
+ VgLdtEntry* the_ldt;
+
vg_assert(seg_selector >= 0 && seg_selector < 8192);
@@ -188,4 +222,5 @@ Addr VG_(do_useseg) ( UInt seg_selector,
limit = (UInt)wine_ldt_get_limit ( &the_ldt[seg_selector] );
}
+ }
/* Note, this check is just slightly too slack. Really it should
@@ -200,4 +235,8 @@ Addr VG_(do_useseg) ( UInt seg_selector,
}
+ if (0)
+ VG_(printf)("do_useseg: base = %p, addr = %p\n",
+ base, base + virtual_addr);
+
return base + virtual_addr;
}
@@ -368,4 +407,61 @@ Int VG_(sys_modify_ldt) ( ThreadId tid,
+Int VG_(sys_set_thread_area) ( ThreadId tid,
+ struct vki_modify_ldt_ldt_s* info )
+{
+ Int idx = info->entry_number;
+
+ if (idx == -1) {
+ for (idx = 0; idx < VKI_GDT_TLS_ENTRIES; idx++) {
+ VgLdtEntry* tls = VG_(threads)[tid].tls + idx;
+
+ if (tls->LdtEnt.Words.word1 == 0 && tls->LdtEnt.Words.word2 == 0)
+ break;
+ }
+
+ if (idx == VKI_GDT_TLS_ENTRIES)
+ return -VKI_ESRCH;
+ } else if (idx < VKI_GDT_TLS_MIN || idx > VKI_GDT_TLS_MAX) {
+ return -VKI_EINVAL;
+ } else {
+ idx = info->entry_number - VKI_GDT_TLS_MIN;
+ }
+
+ translate_to_hw_format(info, VG_(threads)[tid].tls + idx, 0);
+
+ info->entry_number = idx + VKI_GDT_TLS_MIN;
+
+ return 0;
+}
+
+
+Int VG_(sys_get_thread_area) ( ThreadId tid,
+ struct vki_modify_ldt_ldt_s* info )
+{
+ Int idx = info->entry_number;
+ VgLdtEntry* tls;
+
+ if (idx < VKI_GDT_TLS_MIN || idx > VKI_GDT_TLS_MAX)
+ return -VKI_EINVAL;
+
+ tls = VG_(threads)[tid].tls + idx - VKI_GDT_TLS_MIN;
+
+ info->base_addr = ( tls->LdtEnt.Bits.BaseHi << 24 ) |
+ ( tls->LdtEnt.Bits.BaseMid << 16 ) |
+ tls->LdtEnt.Bits.BaseLow;
+ info->limit = ( tls->LdtEnt.Bits.LimitHi << 16 ) |
+ tls->LdtEnt.Bits.LimitLow;
+ info->seg_32bit = tls->LdtEnt.Bits.Default_Big;
+ info->contents = ( tls->LdtEnt.Bits.Type >> 2 ) & 0x3;
+ info->read_exec_only = ( tls->LdtEnt.Bits.Type & 0x1 ) ^ 0x1;
+ info->limit_in_pages = tls->LdtEnt.Bits.Granularity;
+ info->seg_not_present = tls->LdtEnt.Bits.Pres ^ 0x1;
+ info->useable = tls->LdtEnt.Bits.Sys;
+ info->reserved = 0;
+
+ return 0;
+}
+
+
/*--------------------------------------------------------------------*/
/*--- end vg_ldt.c ---*/
--- valgrind/coregrind/vg_libpthread.c #1.143:1.144
@@ -61,4 +61,8 @@
#undef __USE_UNIX98
+#define __USE_GNU
+#include <dlfcn.h>
+#undef __USE_GNU
+
#include <unistd.h>
#include <string.h>
@@ -108,4 +112,7 @@ int is_kerror ( int res )
static
+void init_thread_specific_state ( void );
+
+static
void init_libc_tsd_keys ( void );
@@ -524,4 +531,36 @@ int pthread_getconcurrency(void)
------------------------------------------------ */
+typedef void *(*__attribute__ ((regparm (3), stdcall)) allocate_tls_t) (void *result);
+typedef void (*__attribute__ ((regparm (3), stdcall)) deallocate_tls_t) (void *tcb, int dealloc_tcb);
+
+static allocate_tls_t allocate_tls = NULL;
+static deallocate_tls_t deallocate_tls = NULL;
+
+static
+int get_gs()
+{
+ int gs;
+
+ asm volatile ("movw %%gs, %w0" : "=q" (gs));
+
+ return gs & 0xffff;
+}
+
+static
+void set_gs( int gs )
+{
+ asm volatile ("movw %w0, %%gs" :: "q" (gs));
+}
+
+static
+void *get_tcb()
+{
+ void *tcb;
+
+ asm volatile ("movl %%gs:0, %0" : "=r" (tcb));
+
+ return tcb;
+}
+
/* All exiting threads eventually pass through here, bearing the
return value, or PTHREAD_CANCELED, in ret_val. */
@@ -571,4 +610,10 @@ void thread_exit_wrapper ( void* ret_val
my_free(specifics_ptr);
+ /* Free up any TLS data */
+ if ((get_gs() & 7) == 3 && pthread_self() > 1) {
+ my_assert(deallocate_tls != NULL);
+ deallocate_tls(get_tcb(), 1);
+ }
+
/* Decide on my final disposition. */
VALGRIND_MAGIC_SEQUENCE(detached, (-1) /* default */,
@@ -602,4 +647,7 @@ typedef
struct {
int attr__detachstate;
+ void* tls_data;
+ int tls_segment;
+ unsigned long sysinfo;
void* (*root_fn) ( void* );
void* arg;
@@ -607,4 +655,14 @@ typedef
NewThreadInfo;
+/* Struct used to describe a TDB header, copied from glibc. */
+typedef
+ struct {
+ void *tcb;
+ void *dtv;
+ void *self;
+ int multiple_threads;
+ unsigned long sysinfo;
+ }
+ tcbhead_t;
/* This is passed to the VG_USERREQ__APPLY_IN_NEW_THREAD and so must
@@ -616,4 +674,7 @@ void thread_wrapper ( NewThreadInfo* inf
{
int attr__detachstate;
+ void* tls_data;
+ int tls_segment;
+ unsigned long sysinfo;
void* (*root_fn) ( void* );
void* arg;
@@ -621,7 +682,39 @@ void thread_wrapper ( NewThreadInfo* inf
attr__detachstate = info->attr__detachstate;
+ tls_data = info->tls_data;
+ tls_segment = info->tls_segment;
+ sysinfo = info->sysinfo;
root_fn = info->root_fn;
arg = info->arg;
+ if (tls_data) {
+ tcbhead_t *tcb = tls_data;
+ struct vki_modify_ldt_ldt_s ldt_info;
+
+ /* Fill in the TCB header */
+ tcb->tcb = tcb;
+ tcb->self = tcb;
+ tcb->multiple_threads = 1;
+ tcb->sysinfo = sysinfo;
+
+ /* Fill in an LDT descriptor */
+ ldt_info.entry_number = tls_segment;
+ ldt_info.base_addr = (unsigned long)tls_data;
+ ldt_info.limit = 0xfffff;
+ ldt_info.seg_32bit = 1;
+ ldt_info.contents = 0;
+ ldt_info.read_exec_only = 0;
+ ldt_info.limit_in_pages = 1;
+ ldt_info.seg_not_present = 0;
+ ldt_info.useable = 1;
+ ldt_info.reserved = 0;
+
+ /* Install the thread area */
+ VG_(do_syscall)(__NR_set_thread_area, &ldt_info);
+
+ /* Setup the GS segment register */
+ set_gs(ldt_info.entry_number * 8 + 3);
+ }
+
/* Free up the arg block that pthread_create malloced. */
my_free(info);
@@ -634,4 +727,7 @@ void thread_wrapper ( NewThreadInfo* inf
pthread_detach(pthread_self());
+ /* Initialise thread specific state */
+ init_thread_specific_state();
+
# ifdef GLIBC_2_3
/* Set this thread's locale to the global (default) locale. A hack
@@ -689,4 +785,5 @@ pthread_create (pthread_t *__restrict __
int tid_child;
NewThreadInfo* info;
+ int gs;
ensure_valgrind("pthread_create");
@@ -706,4 +803,27 @@ pthread_create (pthread_t *__restrict __
info->attr__detachstate = PTHREAD_CREATE_JOINABLE;
+ gs = get_gs();
+
+ if ((gs & 7) == 3) {
+ tcbhead_t *tcb = get_tcb();
+
+ if (allocate_tls == NULL || deallocate_tls == NULL) {
+ allocate_tls = (allocate_tls_t)dlsym(RTLD_DEFAULT, "_dl_allocate_tls");
+ deallocate_tls = (deallocate_tls_t)dlsym(RTLD_DEFAULT, "_dl_deallocate_tls");
+ }
+
+ my_assert(allocate_tls != NULL);
+
+ info->tls_data = allocate_tls(NULL);
+ info->tls_segment = gs >> 3;
+ info->sysinfo = tcb->sysinfo;
+
+ tcb->multiple_threads = 1;
+ } else {
+ info->tls_data = NULL;
+ info->tls_segment = -1;
+ info->sysinfo = 0;
+ }
+
info->root_fn = __start_routine;
info->arg = __arg;
@@ -1620,15 +1740,31 @@ void __pthread_initialize ( void )
#include <resolv.h>
-static int thread_specific_errno[VG_N_THREADS];
-static int thread_specific_h_errno[VG_N_THREADS];
-static struct __res_state
- thread_specific_res_state[VG_N_THREADS];
-#undef errno
-extern int errno;
+typedef
+ struct {
+ int *errno_ptr;
+ int *h_errno_ptr;
+ struct __res_state *res_state_ptr;
+ int errno_data;
+ int h_errno_data;
+ struct __res_state res_state_data;
+ }
+ ThreadSpecificState;
+
+static ThreadSpecificState thread_specific_state[VG_N_THREADS];
+
+static
+void init_thread_specific_state ( void )
+{
+ int tid = pthread_self();
+
+ thread_specific_state[tid].errno_ptr = NULL;
+ thread_specific_state[tid].h_errno_ptr = NULL;
+ thread_specific_state[tid].res_state_ptr = NULL;
+}
+
int* __errno_location ( void )
{
int tid;
- int *ret;
ensure_valgrind("__errno_location");
@@ -1639,14 +1775,15 @@ int* __errno_location ( void )
if (tid < 1 || tid >= VG_N_THREADS)
barf("__errno_location: invalid ThreadId");
- if (tid == 1)
- ret = &errno;
+ if (thread_specific_state[tid].errno_ptr == NULL) {
+ if ((get_gs() & 7) == 3)
+ thread_specific_state[tid].errno_ptr = dlsym(RTLD_DEFAULT, "errno");
+ else if (tid == 1)
+ thread_specific_state[tid].errno_ptr = dlvsym(RTLD_DEFAULT, "errno", "GLIBC_2.0");
else
- ret = &thread_specific_errno[tid];
-
- return ret;
+ thread_specific_state[tid].errno_ptr = &thread_specific_state[tid].errno_data;
+ }
+ return thread_specific_state[tid].errno_ptr;
}
-#undef h_errno
-extern int h_errno;
int* __h_errno_location ( void )
{
@@ -1659,12 +1796,15 @@ int* __h_errno_location ( void )
if (tid < 1 || tid >= VG_N_THREADS)
barf("__h_errno_location: invalid ThreadId");
- if (tid == 1)
- return &h_errno;
- return & thread_specific_h_errno[tid];
+ if (thread_specific_state[tid].h_errno_ptr == NULL) {
+ if ((get_gs() & 7) == 3)
+ thread_specific_state[tid].h_errno_ptr = dlsym(RTLD_DEFAULT, "h_errno");
+ else if (tid == 1)
+ thread_specific_state[tid].h_errno_ptr = dlvsym(RTLD_DEFAULT, "h_errno", "GLIBC_2.0");
+ else
+ thread_specific_state[tid].h_errno_ptr = &thread_specific_state[tid].h_errno_data;
+ }
+ return thread_specific_state[tid].h_errno_ptr;
}
-
-#undef _res
-extern struct __res_state _res;
struct __res_state* __res_state ( void )
{
@@ -1677,7 +1817,16 @@ struct __res_state* __res_state ( void )
if (tid < 1 || tid >= VG_N_THREADS)
barf("__res_state: invalid ThreadId");
- if (tid == 1)
- return & _res;
- return & thread_specific_res_state[tid];
+ if (thread_specific_state[tid].res_state_ptr == NULL) {
+ if ((get_gs() & 7) == 3) {
+ struct __res_state **resp = dlsym(RTLD_DEFAULT, "__resp");
+
+ thread_specific_state[tid].res_state_ptr = *resp;
+ } else if (tid == 1) {
+ thread_specific_state[tid].res_state_ptr = dlvsym(RTLD_DEFAULT, "_res", "GLIBC_2.0");
+ } else {
+ thread_specific_state[tid].res_state_ptr = &thread_specific_state[tid].res_state_data;
+ }
+ }
+ return thread_specific_state[tid].res_state_ptr;
}
@@ -2919,8 +3067,12 @@ weak_alias(pthread_rwlock_trywrlock, __p
-/* I've no idea what these are, but they get called quite a lot.
- Anybody know? */
-
#ifndef __UCLIBC__
+/* These are called as part of stdio to lock the FILE structure for MT
+ programs. Unfortunately, the lock is not always a pthreads lock -
+ the NPTL version uses a lighter-weight lock which uses futex
+ directly (and uses a structure which is smaller than
+ pthread_mutex). So basically, this is completely broken on recent
+ glibcs. */
+
#undef _IO_flockfile
void _IO_flockfile ( _IO_FILE * file )
@@ -2928,4 +3080,5 @@ void _IO_flockfile ( _IO_FILE * file )
pthread_mutex_lock(file->_lock);
}
+strong_alias(_IO_flockfile, __flockfile);
weak_alias(_IO_flockfile, flockfile);
@@ -2935,4 +3088,5 @@ void _IO_funlockfile ( _IO_FILE * file )
pthread_mutex_unlock(file->_lock);
}
+strong_alias(_IO_funlockfile, __funlockfile);
weak_alias(_IO_funlockfile, funlockfile);
#endif
--- valgrind/coregrind/vg_main.c #1.137:1.138
@@ -59,4 +59,5 @@ Int VGOFF_(m_dflag) = INVALID_OFFSET;
Int VGOFF_(m_ssestate) = INVALID_OFFSET;
Int VGOFF_(ldt) = INVALID_OFFSET;
+Int VGOFF_(tls) = INVALID_OFFSET;
Int VGOFF_(m_cs) = INVALID_OFFSET;
Int VGOFF_(m_ss) = INVALID_OFFSET;
@@ -328,6 +329,7 @@ static void vg_init_baseBlock ( void )
);
- /* This thread's LDT pointer, and segment registers. */
+ /* This thread's LDT and TLS pointers, and segment registers. */
VGOFF_(ldt) = alloc_BaB(1);
+ VGOFF_(tls) = alloc_BaB(1);
VGOFF_(m_cs) = alloc_BaB(1);
VGOFF_(m_ss) = alloc_BaB(1);
@@ -449,4 +451,7 @@ static void vg_init_baseBlock ( void )
VG_(baseBlock)[VGOFF_(ldt)] = (UInt)NULL;
+ /* Pretend the root thread has no TLS array for now. */
+ VG_(baseBlock)[VGOFF_(tls)] = (UInt)NULL;
+
/* Initialise shadow regs */
if (VG_(needs).shadow_regs) {
--- valgrind/coregrind/vg_proxylwp.c #1.12:1.13
@@ -1374,4 +1374,13 @@ void VG_(proxy_sanity)(void)
}
+/* Get the PID/TID of the ProxyLWP. */
+Int VG_(proxy_id)(ThreadId tid)
+{
+ ThreadState *tst = VG_(get_ThreadState)(tid);
+ ProxyLWP *proxy = tst->proxy;
+
+ return proxy->lwp;
+}
+
/*--------------------------------------------------------------------*/
/*--- Proxy LWP machinery. vg_proxylwp.c ---*/
--- valgrind/coregrind/vg_scheduler.c #1.136:1.137
@@ -340,4 +340,5 @@ void VG_(load_thread_state) ( ThreadId t
VG_(baseBlock)[VGOFF_(ldt)] = (UInt)VG_(threads)[tid].ldt;
+ VG_(baseBlock)[VGOFF_(tls)] = (UInt)VG_(threads)[tid].tls;
VG_(baseBlock)[VGOFF_(m_cs)] = VG_(threads)[tid].m_cs;
VG_(baseBlock)[VGOFF_(m_ss)] = VG_(threads)[tid].m_ss;
@@ -421,4 +422,17 @@ void VG_(save_thread_state) ( ThreadId t
== (void*)VG_(baseBlock)[VGOFF_(ldt)]);
+ /* We don't copy out the TLS entry, because it can never be changed
+ by the normal actions of the thread, only by the set_thread_area
+ syscall, in which case we will correctly be updating
+ VG_(threads)[tid].tls. This printf happens iff the following
+ assertion fails. */
+ if ((void*)VG_(threads)[tid].tls != (void*)VG_(baseBlock)[VGOFF_(tls)])
+ VG_(printf)("VG_(threads)[%d].tls=%p VG_(baseBlock)[VGOFF_(tls)]=%p\n",
+ tid, (void*)VG_(threads)[tid].tls,
+ (void*)VG_(baseBlock)[VGOFF_(tls)]);
+
+ vg_assert((void*)VG_(threads)[tid].tls
+ == (void*)VG_(baseBlock)[VGOFF_(tls)]);
+
VG_(threads)[tid].m_cs = VG_(baseBlock)[VGOFF_(m_cs)];
VG_(threads)[tid].m_ss = VG_(baseBlock)[VGOFF_(m_ss)];
@@ -470,4 +484,5 @@ void VG_(save_thread_state) ( ThreadId t
/* Fill it up with junk. */
VG_(baseBlock)[VGOFF_(ldt)] = junk;
+ VG_(baseBlock)[VGOFF_(tls)] = junk;
VG_(baseBlock)[VGOFF_(m_cs)] = junk;
VG_(baseBlock)[VGOFF_(m_ss)] = junk;
@@ -539,4 +554,5 @@ void mostly_clear_thread_record ( Thread
vg_assert(tid >= 0 && tid < VG_N_THREADS);
VG_(threads)[tid].ldt = NULL;
+ VG_(clear_TLS_for_thread)(VG_(threads)[tid].tls);
VG_(threads)[tid].tid = tid;
VG_(threads)[tid].status = VgTs_Empty;
@@ -597,4 +613,5 @@ void VG_(scheduler_init) ( void )
vg_tid_currently_in_baseBlock = tid_main;
vg_tid_last_in_baseBlock = tid_main;
+ VG_(baseBlock)[VGOFF_(tls)] = (UInt)VG_(threads)[tid_main].tls;
VG_(save_thread_state) ( tid_main );
@@ -1373,4 +1390,7 @@ void cleanup_after_thread_exited ( Threa
VG_(threads)[tid].ldt = NULL;
+ /* Clear its TLS array. */
+ VG_(clear_TLS_for_thread)( VG_(threads)[tid].tls );
+
/* Not interested in the timeout anymore */
VG_(threads)[tid].awaken_at = 0xFFFFFFFF;
@@ -1859,4 +1879,8 @@ void do__apply_in_new_thread ( ThreadId
}
+ /* Initialise the thread's TLS array */
+ VG_(clear_TLS_for_thread)( VG_(threads)[tid].tls );
+ VG_(baseBlock)[VGOFF_(tls)] = (UInt)VG_(threads)[tid].tls;
+
VG_(save_thread_state)(tid);
vg_tid_last_in_baseBlock = tid;
@@ -2076,6 +2100,10 @@ void do_pthread_mutex_lock( ThreadId tid
if (mutex->__m_count > 0) {
-
- vg_assert(VG_(is_valid_tid)((ThreadId)mutex->__m_owner));
+ if (!VG_(is_valid_tid)((ThreadId)mutex->__m_owner)) {
+ VG_(record_pthread_error)( tid,
+ "pthread_mutex_lock/trylock: mutex has invalid owner");
+ SET_PTHREQ_RETVAL(tid, VKI_EINVAL);
+ return;
+ }
/* Someone has it already. */
--- valgrind/coregrind/vg_syscalls.c #1.79:1.80
@@ -1047,13 +1047,4 @@ PRE(exit)
}
-PRE(clone)
-{
- VG_(unimplemented)
- ("clone(): not supported by Valgrind.\n "
- "We do now support programs linked against\n "
- "libpthread.so, though. Re-run with -v and ensure that\n "
- "you are picking up Valgrind's implementation of libpthread.so.");
-}
-
PRE(ptrace)
{
@@ -1185,4 +1176,31 @@ PRE(modify_ldt)
}
+PRE(set_thread_area)
+{
+ MAYBE_PRINTF("set_thread_area ( %p )\n", arg1);
+
+ SYSCALL_TRACK( pre_mem_read, tid,
+ "set_thread_area(ptr)", arg1,
+ sizeof(struct vki_modify_ldt_ldt_s) );
+
+ /* "do" the syscall ourselves; the kernel never sees it */
+ res = VG_(sys_set_thread_area)( tid, (void *)arg1 );
+}
+
+PRE(get_thread_area)
+{
+ MAYBE_PRINTF("get_thread_area ( %p )\n", arg1);
+ SYSCALL_TRACK( pre_mem_write, tid,
+ "get_thread_area(ptr)", arg1,
+ sizeof(struct vki_modify_ldt_ldt_s) );
+
+ /* "do" the syscall ourselves; the kernel never sees it */
+ res = VG_(sys_get_thread_area)( tid, (void *)arg1 );
+
+ if (!VG_(is_kerror)(res)) {
+ VG_TRACK( post_mem_write, arg1, sizeof(struct vki_modify_ldt_ldt_s) );
+ }
+}
+
PRE(setresgid)
{
@@ -2142,4 +2160,22 @@ POST(fork)
}
+PRE(clone)
+{
+ MAYBE_PRINTF("clone ( %d, %p, %p, %p, %p )\n",arg1,arg2,arg3,arg4,arg5);
+
+ if (arg2 == 0 &&
+ arg1 == (VKI_CLONE_CHILD_CLEARTID|VKI_CLONE_CHILD_SETTID|VKI_SIGCHLD)) {
+ before_fork(tid, tst);
+ res = VG_(do_syscall)(SYSNO, arg1, arg2, arg3, arg4, arg5);
+ after_fork(tid, tst);
+ } else {
+ VG_(unimplemented)
+ ("clone(): not supported by Valgrind.\n "
+ "We do now support programs linked against\n "
+ "libpthread.so, though. Re-run with -v and ensure that\n "
+ "you are picking up Valgrind's implementation of libpthread.so.");
+ }
+}
+
PRE(fsync)
{
@@ -4728,4 +4764,25 @@ PRE(utimes)
}
+PRE(futex)
+{
+ /* int futex(void *futex, int op, int val, const struct timespec *timeout); */
+ MAYBE_PRINTF("futex ( %p, %d, %d, %p, %p )\n", arg1,arg2,arg3,arg4,arg5);
+ SYSCALL_TRACK( pre_mem_read, tid, "futex(futex)", arg1, sizeof(int) );
+ if (arg2 == VKI_FUTEX_WAIT && arg4 != (UInt)NULL)
+ SYSCALL_TRACK( pre_mem_read, tid, "futex(timeout)", arg4,
+ sizeof(struct timespec) );
+ if (arg2 == VKI_FUTEX_REQUEUE)
+ SYSCALL_TRACK( pre_mem_read, tid, "futex(futex2)", arg4, sizeof(int) );
+}
+
+POST(futex)
+{
+ if (!VG_(is_kerror)(res)) {
+ VG_TRACK( post_mem_write, arg1, sizeof(int) );
+ if (arg2 == VKI_FUTEX_FD && VG_(clo_track_fds))
+ record_fd_open(tid, res, NULL);
+ }
+}
+
#define SIGNAL_SIMULATION 1
@@ -4928,4 +4985,6 @@ static const struct sys_info special_sys
SYSB_(modify_ldt, False),
+ SYSB_(set_thread_area, False),
+ SYSB_(get_thread_area, False),
SYSB_(execve, False),
@@ -5127,4 +5186,5 @@ static const struct sys_info sys_info[]
SYSBA(mmap2, False),
SYSBA(clock_gettime, False),
+ SYSBA(futex, True),
/* new signal handling makes these normal blocking syscalls */
--- valgrind/include/vg_kerneliface.h #1.11:1.12
@@ -632,4 +632,5 @@ typedef struct vki_modify_ldt_ldt_s {
unsigned int seg_not_present:1;
unsigned int useable:1;
+ unsigned int reserved:25;
} vki_modify_ldt_t;
@@ -638,4 +639,7 @@ typedef struct vki_modify_ldt_ldt_s {
#define VKI_MODIFY_LDT_CONTENTS_CODE 2
+#define VKI_GDT_TLS_ENTRIES 3
+#define VKI_GDT_TLS_MIN 6
+#define VKI_GDT_TLS_MAX (VKI_GDT_TLS_MIN + VKI_GDT_TLS_ENTRIES)
/* Flags for clone() */
@@ -727,4 +731,13 @@ struct statfs64 {
};
+/*
+ * linux/futex.h
+ */
+
+#define VKI_FUTEX_WAIT 0
+#define VKI_FUTEX_WAKE 1
+#define VKI_FUTEX_FD 2
+#define VKI_FUTEX_REQUEUE 3
+
#endif /* __VG_KERNELIFACE_H */
--- valgrind/none/tests/Makefile.am #1.22:1.23
@@ -43,4 +43,5 @@
shortpush.stderr.exp shortpush.vgtest \
shorts.stderr.exp shorts.vgtest \
+ tls.stderr.exp tls.stdout.exp tls.vgtest \
smc1.stderr.exp smc1.stdout.exp smc1.vgtest \
syscall-restart1.vgtest syscall-restart1.stdout.exp syscall-restart1.stderr.exp \
@@ -54,5 +55,5 @@
munmap_exe map_unmap mremap rcl_assert \
rcrl readline1 resolv seg_override sha1_test shortpush shorts smc1 \
- pth_blockedsig \
+ tls.so tls2.so tls pth_blockedsig \
syscall-restart1 syscall-restart2 \
coolo_sigaction gxx304 yield
@@ -96,7 +97,19 @@
syscall_restart1_SOURCES = syscall-restart1.c
syscall_restart2_SOURCES = syscall-restart2.c
+tls_SOURCES = tls.c tls2.c
+tls_DEPENDENCIES = tls.so
+tls_LDFLAGS = -Wl,-rpath,$(srcdir)
+tls_LDADD = tls.so -lpthread
+tls_so_SOURCES = tls_so.c
+tls_so_LDADD = tls2.so
+tls_so_DEPENDENCIES = tls2.so
+tls_so_LDFLAGS = -Wl,-rpath,$(srcdir) -shared
+tls2_so_SOURCES = tls2_so.c
+tls2_so_LDFLAGS = -shared
yield_SOURCES = yield.c
yield_LDADD = -lpthread
+tls_so.o tls2_so.o: CFLAGS += -fpic
+
# pthread C ones
pth_blockedsig_SOURCES = pth_blockedsig.c
--- valgrind/none/tests/seg_override.c #1.1:1.2
@@ -111,6 +111,6 @@ void ldt_seg_write ( int ldt_entno, unsi
asm volatile("movl %2, %%eax\n\t"
"movl %1, %%edx\n\t"
- "movl %0, %%gs\n\t"
- "movl %%eax, %%gs:(%%edx)\t"
+ "movl %0, %%fs\n\t"
+ "movl %%eax, %%fs:(%%edx)\t"
:
: "r" (7 /* LDT(TI), least privilege */ + (ldt_entno << 3)),
|
|
From: Jeremy F. <je...@go...> - 2004-01-21 01:23:07
|
CVS commit by fitzhardinge:
Small update about unimplemented instructions.
M +2 -1 coregrind_core.html 1.21
--- valgrind/coregrind/docs/coregrind_core.html #1.20:1.21
@@ -1188,5 +1188,6 @@
<ul>
<li>No support for 3DNow instructions. If the translator encounters
- these, Valgrind will simply give up.</li>
+ these, Valgrind will generate a SIGILL when the instruction is
+ executed.</li>
<p>
|
|
From: Jeremy F. <je...@go...> - 2004-01-21 01:21:14
|
CVS commit by fitzhardinge: Hasn't this been added already? A exec-sigmask.vgtest 1.1 |