* RFA: [Ada] extract known tasks array parameters from symbol table
@ 2012-02-13 15:14 Tristan Gingold
2012-02-13 16:16 ` Joel Brobecker
0 siblings, 1 reply; 12+ messages in thread
From: Tristan Gingold @ 2012-02-13 15:14 UTC (permalink / raw)
To: gdb-patches@sourceware.org ml; +Cc: Joel Brobecker
Hi,
while trying to use 'info tasks' on VMS, I hit an issue with the known_tasks array business, because the elements are only 32 bit pointers on VMS. I took the occasion to make the code more generic and getting rid of the fixed parameters. So this patch now tries to extract array size and element type from the symbol table first, and fall back to the minsymtab in case of error.
Maybe we should get rid of the fallback, as without debug symbol for Ada.Tasking, the whole ada-tasks.c code is pretty useless.
Manually tested on ia64-hp-openvms.
Tristan.
gdb/
2012-02-13 Tristan Gingold <gingold@adacore.com>
* ada-tasks.c (struct ada_tasks_inferior_data): Add
known_tasks_element and known_tasks_length fields.
(read_known_tasks_array): Change argument type. Use pointer type
and number of elements from DATA. Adjust.
(read_known_tasks_list): Likewise.
(get_known_tasks_addr): Change profile. Try symtab first, and
extract type and size from it.
(ada_set_current_inferior_known_tasks_addr): Adjust for above
change.
diff --git a/gdb/ada-tasks.c b/gdb/ada-tasks.c
index 274d83a..45b597f 100644
--- a/gdb/ada-tasks.c
+++ b/gdb/ada-tasks.c
@@ -215,6 +215,12 @@ struct ada_tasks_inferior_data
above. */
CORE_ADDR known_tasks_addr;
+ /* Type of elements of the known task. Usually a pointer. */
+ struct type *known_tasks_element;
+
+ /* Number of elements in the known tasks array. */
+ unsigned int known_tasks_length;
+
/* When nonzero, this flag indicates that the task_list field
below is up to date. When set to zero, the list has either
not been initialized, or has potentially become stale. */
@@ -774,24 +780,21 @@ add_ada_task (CORE_ADDR task_id, struct inferior *inf)
it in the current inferior's TASK_LIST. Return non-zero upon success. */
static int
-read_known_tasks_array (CORE_ADDR known_tasks_addr)
+read_known_tasks_array (struct ada_tasks_inferior_data *data)
{
- const int target_ptr_byte =
- gdbarch_ptr_bit (target_gdbarch) / TARGET_CHAR_BIT;
- const int known_tasks_size = target_ptr_byte * MAX_NUMBER_OF_KNOWN_TASKS;
+ const int target_ptr_byte = TYPE_LENGTH (data->known_tasks_element);
+ const int known_tasks_size = target_ptr_byte * data->known_tasks_length;
gdb_byte *known_tasks = alloca (known_tasks_size);
int i;
/* Build a new list by reading the ATCBs from the Known_Tasks array
in the Ada runtime. */
- read_memory (known_tasks_addr, known_tasks, known_tasks_size);
- for (i = 0; i < MAX_NUMBER_OF_KNOWN_TASKS; i++)
+ read_memory (data->known_tasks_addr, known_tasks, known_tasks_size);
+ for (i = 0; i < data->known_tasks_length; i++)
{
- struct type *data_ptr_type =
- builtin_type (target_gdbarch)->builtin_data_ptr;
CORE_ADDR task_id =
extract_typed_address (known_tasks + i * target_ptr_byte,
- data_ptr_type);
+ data->known_tasks_element);
if (task_id != 0)
add_ada_task (task_id, current_inferior ());
@@ -804,13 +807,10 @@ read_known_tasks_array (CORE_ADDR known_tasks_addr)
the current inferior's TASK_LIST. Return non-zero upon success. */
static int
-read_known_tasks_list (CORE_ADDR known_tasks_addr)
+read_known_tasks_list (struct ada_tasks_inferior_data *data)
{
- const int target_ptr_byte =
- gdbarch_ptr_bit (target_gdbarch) / TARGET_CHAR_BIT;
+ const int target_ptr_byte = TYPE_LENGTH (data->known_tasks_element);
gdb_byte *known_tasks = alloca (target_ptr_byte);
- struct type *data_ptr_type =
- builtin_type (target_gdbarch)->builtin_data_ptr;
CORE_ADDR task_id;
const struct ada_tasks_pspace_data *pspace_data
= get_ada_tasks_pspace_data (current_program_space);
@@ -820,8 +820,8 @@ read_known_tasks_list (CORE_ADDR known_tasks_addr)
return 0;
/* Build a new list by reading the ATCBs. Read head of the list. */
- read_memory (known_tasks_addr, known_tasks, target_ptr_byte);
- task_id = extract_typed_address (known_tasks, data_ptr_type);
+ read_memory (data->known_tasks_addr, known_tasks, target_ptr_byte);
+ task_id = extract_typed_address (known_tasks, data->known_tasks_element);
while (task_id != 0)
{
struct value *tcb_value;
@@ -841,21 +841,85 @@ read_known_tasks_list (CORE_ADDR known_tasks_addr)
return 1;
}
-/* Return the address of the variable NAME that contains all the known
- tasks maintained in the Ada Runtime. Return NULL if the variable
- could not be found, meaning that the inferior program probably does
- not use tasking. */
+/* Try method KIND to extract known tasks info for DATA.
+ Return non-zero in case of success, and set the known tasks field of DATA.
+*/
-static CORE_ADDR
-get_known_tasks_addr (const char *name)
+static int
+get_known_tasks_addr (struct ada_tasks_inferior_data *data,
+ enum ada_known_tasks_kind kind)
{
+ const char *name;
struct minimal_symbol *msym;
+ struct symbol *sym;
+
+ switch (kind)
+ {
+ case ADA_TASKS_ARRAY:
+ name = KNOWN_TASKS_NAME;
+ break;
+ case ADA_TASKS_LIST:
+ name = KNOWN_TASKS_LIST;
+ break;
+ default:
+ /* Should never happen, but be safe. */
+ return 0;
+ }
+
+ /* First try psymtab/symtab. */
+ sym = lookup_symbol_in_language (name, NULL, VAR_DOMAIN, language_c, NULL);
+ if (sym != NULL)
+ {
+ /* Validate. */
+ struct type *type = check_typedef (SYMBOL_TYPE (sym));
+ struct type *eltype;
+ struct type *idxtype;
+
+ switch (kind)
+ {
+ case ADA_TASKS_ARRAY:
+ if (TYPE_CODE (type) == TYPE_CODE_ARRAY
+ && (eltype = check_typedef (TYPE_TARGET_TYPE (type)))
+ && TYPE_CODE (eltype) == TYPE_CODE_PTR
+ && (idxtype = check_typedef (TYPE_INDEX_TYPE (type)))
+ && !TYPE_LOW_BOUND_UNDEFINED (idxtype)
+ && !TYPE_HIGH_BOUND_UNDEFINED (idxtype))
+ {
+ data->known_tasks_kind = ADA_TASKS_ARRAY;
+ data->known_tasks_addr = SYMBOL_VALUE_ADDRESS (sym);
+ data->known_tasks_element = eltype;
+ data->known_tasks_length =
+ TYPE_HIGH_BOUND (idxtype) - TYPE_LOW_BOUND (idxtype) + 1;
+ return 1;
+ }
+ break;
+ case ADA_TASKS_LIST:
+ if (TYPE_CODE (type) == TYPE_CODE_PTR)
+ {
+ data->known_tasks_kind = ADA_TASKS_LIST;
+ data->known_tasks_addr = SYMBOL_VALUE_ADDRESS (sym);
+ data->known_tasks_element = type;
+ data->known_tasks_length = 1;
+ return 1;
+ }
+ break;
+ default:
+ break;
+ }
+ }
+
+ /* Fallback using minsymtab. */
msym = lookup_minimal_symbol (name, NULL, NULL);
if (msym == NULL)
return 0;
- return SYMBOL_VALUE_ADDRESS (msym);
+ data->known_tasks_kind = kind;
+ data->known_tasks_addr = SYMBOL_VALUE_ADDRESS (msym);
+ data->known_tasks_element = builtin_type (target_gdbarch)->builtin_data_ptr;
+ data->known_tasks_length =
+ (kind == ADA_TASKS_ARRAY) ? MAX_NUMBER_OF_KNOWN_TASKS : 1;
+ return 1;
}
/* Assuming DATA is the ada-tasks' data for the current inferior,
@@ -865,26 +929,14 @@ get_known_tasks_addr (const char *name)
static void
ada_set_current_inferior_known_tasks_addr (struct ada_tasks_inferior_data *data)
{
- CORE_ADDR known_tasks_addr;
-
if (data->known_tasks_kind != ADA_TASKS_UNKNOWN)
return;
- known_tasks_addr = get_known_tasks_addr (KNOWN_TASKS_NAME);
- if (known_tasks_addr != 0)
- {
- data->known_tasks_kind = ADA_TASKS_ARRAY;
- data->known_tasks_addr = known_tasks_addr;
- return;
- }
+ if (get_known_tasks_addr (data, ADA_TASKS_ARRAY))
+ return;
- known_tasks_addr = get_known_tasks_addr (KNOWN_TASKS_LIST);
- if (known_tasks_addr != 0)
- {
- data->known_tasks_kind = ADA_TASKS_LIST;
- data->known_tasks_addr = known_tasks_addr;
- return;
- }
+ if (get_known_tasks_addr (data, ADA_TASKS_LIST))
+ return;
data->known_tasks_kind = ADA_TASKS_NOT_FOUND;
data->known_tasks_addr = 0;
@@ -917,9 +969,9 @@ read_known_tasks (void)
case ADA_TASKS_NOT_FOUND: /* Tasking not in use in inferior. */
return 0;
case ADA_TASKS_ARRAY:
- return read_known_tasks_array (data->known_tasks_addr);
+ return read_known_tasks_array (data);
case ADA_TASKS_LIST:
- return read_known_tasks_list (data->known_tasks_addr);
+ return read_known_tasks_list (data);
}
/* Step 3: Set task_list_valid_p, to avoid re-reading the Known_Tasks
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: RFA: [Ada] extract known tasks array parameters from symbol table
2012-02-13 15:14 RFA: [Ada] extract known tasks array parameters from symbol table Tristan Gingold
@ 2012-02-13 16:16 ` Joel Brobecker
2012-02-14 8:19 ` Tristan Gingold
2012-02-16 14:40 ` Tristan Gingold
0 siblings, 2 replies; 12+ messages in thread
From: Joel Brobecker @ 2012-02-13 16:16 UTC (permalink / raw)
To: Tristan Gingold; +Cc: gdb-patches@sourceware.org ml
Hi Tristan,
> Maybe we should get rid of the fallback, as without debug symbol for
> Ada.Tasking, the whole ada-tasks.c code is pretty useless.
The problem is that certain GNU/Linux distributions decided to simply
strip all runtime libraries of debug info, and then provide additional
packages for the debug version of these shared libs. And apparently,
it's a significant disruption to address this issue at the package
creation level. So we need to try to support those users the best
we can.
> Manually tested on ia64-hp-openvms.
I'd really like it to be tested on at least a GNU/Linux variant as
well as a bareboard variant using the ravenscar runtime (try the list).
Or, alternatively, put the patch in our tree, and then wait a day or
two to get the results of the nightly testing.
> gdb/
> 2012-02-13 Tristan Gingold <gingold@adacore.com>
>
> * ada-tasks.c (struct ada_tasks_inferior_data): Add
> known_tasks_element and known_tasks_length fields.
> (read_known_tasks_array): Change argument type. Use pointer type
> and number of elements from DATA. Adjust.
> (read_known_tasks_list): Likewise.
> (get_known_tasks_addr): Change profile. Try symtab first, and
> extract type and size from it.
> (ada_set_current_inferior_known_tasks_addr): Adjust for above
> change.
Mostly OK.
Just a few thoughts on your patch.
> -/* Return the address of the variable NAME that contains all the known
> - tasks maintained in the Ada Runtime. Return NULL if the variable
> - could not be found, meaning that the inferior program probably does
> - not use tasking. */
> +/* Try method KIND to extract known tasks info for DATA.
> + Return non-zero in case of success, and set the known tasks field of DATA.
> +*/
Nit-picking: Can you fold the last line at around 70 chars?
> -static CORE_ADDR
> -get_known_tasks_addr (const char *name)
> +static int
> +get_known_tasks_addr (struct ada_tasks_inferior_data *data,
> + enum ada_known_tasks_kind kind)
For this function, I would like it to be renamed to "get_ada_tasks_info",
"get_inferior_tasks_info", or maybe even "ada_task_info_sniffer".
Something like that.
Also, I am thinking that there is no reason that the caller should
be testing each kind one after the other. I think something like:
static struct ada_tasks_inferior_data *
ada_task_info_sniffer (void)
{
[lookup array symbol]
if (symbol)
{
[validate]
return array_info;
}
[lookup list symbol]
if (symbol)
{
[validate]
return list_info;
}
[...]
WDYT?
--
Joel
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: RFA: [Ada] extract known tasks array parameters from symbol table
2012-02-13 16:16 ` Joel Brobecker
@ 2012-02-14 8:19 ` Tristan Gingold
2012-02-14 15:47 ` Joel Brobecker
2012-02-16 14:40 ` Tristan Gingold
1 sibling, 1 reply; 12+ messages in thread
From: Tristan Gingold @ 2012-02-14 8:19 UTC (permalink / raw)
To: Joel Brobecker; +Cc: gdb-patches@sourceware.org ml
On Feb 13, 2012, at 5:15 PM, Joel Brobecker wrote:
> Hi Tristan,
>
>> Maybe we should get rid of the fallback, as without debug symbol for
>> Ada.Tasking, the whole ada-tasks.c code is pretty useless.
>
> The problem is that certain GNU/Linux distributions decided to simply
> strip all runtime libraries of debug info, and then provide additional
> packages for the debug version of these shared libs. And apparently,
> it's a significant disruption to address this issue at the package
> creation level. So we need to try to support those users the best
> we can.
Ok. But how are debug infos for the ATCB read ? Are they in the executable due to implicit with of ada.tasking ?
>> Manually tested on ia64-hp-openvms.
>
> I'd really like it to be tested on at least a GNU/Linux variant as
> well as a bareboard variant using the ravenscar runtime (try the list).
> Or, alternatively, put the patch in our tree, and then wait a day or
> two to get the results of the nightly testing.
Ok, will do.
>> gdb/
>> 2012-02-13 Tristan Gingold <gingold@adacore.com>
>>
>> * ada-tasks.c (struct ada_tasks_inferior_data): Add
>> known_tasks_element and known_tasks_length fields.
>> (read_known_tasks_array): Change argument type. Use pointer type
>> and number of elements from DATA. Adjust.
>> (read_known_tasks_list): Likewise.
>> (get_known_tasks_addr): Change profile. Try symtab first, and
>> extract type and size from it.
>> (ada_set_current_inferior_known_tasks_addr): Adjust for above
>> change.
>
> Mostly OK.
>
> Just a few thoughts on your patch.
>
>> -/* Return the address of the variable NAME that contains all the known
>> - tasks maintained in the Ada Runtime. Return NULL if the variable
>> - could not be found, meaning that the inferior program probably does
>> - not use tasking. */
>> +/* Try method KIND to extract known tasks info for DATA.
>> + Return non-zero in case of success, and set the known tasks field of DATA.
>> +*/
>
> Nit-picking: Can you fold the last line at around 70 chars?
Sure.
>
>> -static CORE_ADDR
>> -get_known_tasks_addr (const char *name)
>> +static int
>> +get_known_tasks_addr (struct ada_tasks_inferior_data *data,
>> + enum ada_known_tasks_kind kind)
>
> For this function, I would like it to be renamed to "get_ada_tasks_info",
> "get_inferior_tasks_info", or maybe even "ada_task_info_sniffer".
> Something like that.
>
> Also, I am thinking that there is no reason that the caller should
> be testing each kind one after the other. I think something like:
>
> static struct ada_tasks_inferior_data *
> ada_task_info_sniffer (void)
> {
> [lookup array symbol]
> if (symbol)
> {
> [validate]
> return array_info;
> }
>
> [lookup list symbol]
> if (symbol)
> {
> [validate]
> return list_info;
> }
> [...]
>
> WDYT?
Will submit a new version.
Tristan.
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: RFA: [Ada] extract known tasks array parameters from symbol table
2012-02-14 8:19 ` Tristan Gingold
@ 2012-02-14 15:47 ` Joel Brobecker
0 siblings, 0 replies; 12+ messages in thread
From: Joel Brobecker @ 2012-02-14 15:47 UTC (permalink / raw)
To: Tristan Gingold; +Cc: gdb-patches@sourceware.org ml
> > The problem is that certain GNU/Linux distributions decided to simply
> > strip all runtime libraries of debug info, and then provide additional
> > packages for the debug version of these shared libs. And apparently,
> > it's a significant disruption to address this issue at the package
> > creation level. So we need to try to support those users the best
> > we can.
>
> Ok. But how are debug infos for the ATCB read ? Are they in the
> executable due to implicit with of ada.tasking ?
I am not 100% sure, but that's my guess as well.
--
Joel
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: RFA: [Ada] extract known tasks array parameters from symbol table
2012-02-13 16:16 ` Joel Brobecker
2012-02-14 8:19 ` Tristan Gingold
@ 2012-02-16 14:40 ` Tristan Gingold
2012-02-16 17:19 ` Joel Brobecker
1 sibling, 1 reply; 12+ messages in thread
From: Tristan Gingold @ 2012-02-16 14:40 UTC (permalink / raw)
To: Joel Brobecker; +Cc: gdb-patches@sourceware.org ml
Hi Joel,
here is the new version, taking into account your comments: I have mostly reshaped ada_set_current_inferior_known_tasks_addr, tell me if the new form is ok (and then I will test it more thoroughly).
Tristan.
gdb/
2012-02-13 Tristan Gingold <gingold@adacore.com>
* ada-tasks.c (struct ada_tasks_inferior_data): Add
known_tasks_element and known_tasks_length fields.
(read_known_tasks_array): Change argument type. Use pointer type
and number of elements from DATA. Adjust.
(read_known_tasks_list): Likewise.
(get_known_tasks_addr): Remove.
(ada_set_current_inferior_known_tasks_addr): Try symtab first.
Merge former get_known_tasks_addr code.
diff --git a/gdb/ada-tasks.c b/gdb/ada-tasks.c
index 274d83a..5815cf9 100644
--- a/gdb/ada-tasks.c
+++ b/gdb/ada-tasks.c
@@ -215,6 +215,12 @@ struct ada_tasks_inferior_data
above. */
CORE_ADDR known_tasks_addr;
+ /* Type of elements of the known task. Usually a pointer. */
+ struct type *known_tasks_element;
+
+ /* Number of elements in the known tasks array. */
+ unsigned int known_tasks_length;
+
/* When nonzero, this flag indicates that the task_list field
below is up to date. When set to zero, the list has either
not been initialized, or has potentially become stale. */
@@ -774,24 +780,21 @@ add_ada_task (CORE_ADDR task_id, struct inferior *inf)
it in the current inferior's TASK_LIST. Return non-zero upon success. */
static int
-read_known_tasks_array (CORE_ADDR known_tasks_addr)
+read_known_tasks_array (struct ada_tasks_inferior_data *data)
{
- const int target_ptr_byte =
- gdbarch_ptr_bit (target_gdbarch) / TARGET_CHAR_BIT;
- const int known_tasks_size = target_ptr_byte * MAX_NUMBER_OF_KNOWN_TASKS;
+ const int target_ptr_byte = TYPE_LENGTH (data->known_tasks_element);
+ const int known_tasks_size = target_ptr_byte * data->known_tasks_length;
gdb_byte *known_tasks = alloca (known_tasks_size);
int i;
/* Build a new list by reading the ATCBs from the Known_Tasks array
in the Ada runtime. */
- read_memory (known_tasks_addr, known_tasks, known_tasks_size);
- for (i = 0; i < MAX_NUMBER_OF_KNOWN_TASKS; i++)
+ read_memory (data->known_tasks_addr, known_tasks, known_tasks_size);
+ for (i = 0; i < data->known_tasks_length; i++)
{
- struct type *data_ptr_type =
- builtin_type (target_gdbarch)->builtin_data_ptr;
CORE_ADDR task_id =
extract_typed_address (known_tasks + i * target_ptr_byte,
- data_ptr_type);
+ data->known_tasks_element);
if (task_id != 0)
add_ada_task (task_id, current_inferior ());
@@ -804,13 +807,10 @@ read_known_tasks_array (CORE_ADDR known_tasks_addr)
the current inferior's TASK_LIST. Return non-zero upon success. */
static int
-read_known_tasks_list (CORE_ADDR known_tasks_addr)
+read_known_tasks_list (struct ada_tasks_inferior_data *data)
{
- const int target_ptr_byte =
- gdbarch_ptr_bit (target_gdbarch) / TARGET_CHAR_BIT;
+ const int target_ptr_byte = TYPE_LENGTH (data->known_tasks_element);
gdb_byte *known_tasks = alloca (target_ptr_byte);
- struct type *data_ptr_type =
- builtin_type (target_gdbarch)->builtin_data_ptr;
CORE_ADDR task_id;
const struct ada_tasks_pspace_data *pspace_data
= get_ada_tasks_pspace_data (current_program_space);
@@ -820,8 +820,8 @@ read_known_tasks_list (CORE_ADDR known_tasks_addr)
return 0;
/* Build a new list by reading the ATCBs. Read head of the list. */
- read_memory (known_tasks_addr, known_tasks, target_ptr_byte);
- task_id = extract_typed_address (known_tasks, data_ptr_type);
+ read_memory (data->known_tasks_addr, known_tasks, target_ptr_byte);
+ task_id = extract_typed_address (known_tasks, data->known_tasks_element);
while (task_id != 0)
{
struct value *tcb_value;
@@ -841,23 +841,6 @@ read_known_tasks_list (CORE_ADDR known_tasks_addr)
return 1;
}
-/* Return the address of the variable NAME that contains all the known
- tasks maintained in the Ada Runtime. Return NULL if the variable
- could not be found, meaning that the inferior program probably does
- not use tasking. */
-
-static CORE_ADDR
-get_known_tasks_addr (const char *name)
-{
- struct minimal_symbol *msym;
-
- msym = lookup_minimal_symbol (name, NULL, NULL);
- if (msym == NULL)
- return 0;
-
- return SYMBOL_VALUE_ADDRESS (msym);
-}
-
/* Assuming DATA is the ada-tasks' data for the current inferior,
set the known_tasks_kind and known_tasks_addr fields. Do nothing
if those fields are already set and still up to date. */
@@ -865,27 +848,95 @@ get_known_tasks_addr (const char *name)
static void
ada_set_current_inferior_known_tasks_addr (struct ada_tasks_inferior_data *data)
{
- CORE_ADDR known_tasks_addr;
+ const char *name;
+ struct minimal_symbol *msym;
+ struct symbol *sym;
+ /* Return now if already set. */
if (data->known_tasks_kind != ADA_TASKS_UNKNOWN)
return;
- known_tasks_addr = get_known_tasks_addr (KNOWN_TASKS_NAME);
- if (known_tasks_addr != 0)
+ /* First with the symtab, which knows the exact array type and size. */
+
+ /* Try array. */
+
+ sym = lookup_symbol_in_language (KNOWN_TASKS_NAME, NULL, VAR_DOMAIN,
+ language_c, NULL);
+ if (sym != NULL)
+ {
+ /* Validate. */
+ struct type *type = check_typedef (SYMBOL_TYPE (sym));
+ struct type *eltype;
+ struct type *idxtype;
+
+ if (TYPE_CODE (type) == TYPE_CODE_ARRAY
+ && (eltype = check_typedef (TYPE_TARGET_TYPE (type)))
+ && TYPE_CODE (eltype) == TYPE_CODE_PTR
+ && (idxtype = check_typedef (TYPE_INDEX_TYPE (type)))
+ && !TYPE_LOW_BOUND_UNDEFINED (idxtype)
+ && !TYPE_HIGH_BOUND_UNDEFINED (idxtype))
+ {
+ data->known_tasks_kind = ADA_TASKS_ARRAY;
+ data->known_tasks_addr = SYMBOL_VALUE_ADDRESS (sym);
+ data->known_tasks_element = eltype;
+ data->known_tasks_length =
+ TYPE_HIGH_BOUND (idxtype) - TYPE_LOW_BOUND (idxtype) + 1;
+ return;
+ }
+ }
+
+ /* Try list. */
+
+ sym = lookup_symbol_in_language (KNOWN_TASKS_LIST, NULL, VAR_DOMAIN,
+ language_c, NULL);
+ if (sym != NULL)
+ {
+ /* Validate. */
+ struct type *type = check_typedef (SYMBOL_TYPE (sym));
+
+ if (TYPE_CODE (type) == TYPE_CODE_PTR)
+ {
+ data->known_tasks_kind = ADA_TASKS_LIST;
+ data->known_tasks_addr = SYMBOL_VALUE_ADDRESS (sym);
+ data->known_tasks_element = type;
+ data->known_tasks_length = 1;
+ return;
+ }
+ }
+
+ /* Fallback using the minsymtab. The runtime may have been stripped (as in
+ some distributions), but it is likely that the executable still contains
+ debug information on the task type (due to implicit with of Ada.Tasking).
+ */
+
+ /* Try array. */
+
+ msym = lookup_minimal_symbol (KNOWN_TASKS_NAME, NULL, NULL);
+ if (msym != NULL)
{
data->known_tasks_kind = ADA_TASKS_ARRAY;
- data->known_tasks_addr = known_tasks_addr;
+ data->known_tasks_addr = SYMBOL_VALUE_ADDRESS (msym);
+ data->known_tasks_element =
+ builtin_type (target_gdbarch)->builtin_data_ptr;
+ data->known_tasks_length = MAX_NUMBER_OF_KNOWN_TASKS;
return;
}
- known_tasks_addr = get_known_tasks_addr (KNOWN_TASKS_LIST);
- if (known_tasks_addr != 0)
+ /* Try list. */
+
+ msym = lookup_minimal_symbol (KNOWN_TASKS_LIST, NULL, NULL);
+ if (msym != NULL)
{
data->known_tasks_kind = ADA_TASKS_LIST;
- data->known_tasks_addr = known_tasks_addr;
+ data->known_tasks_addr = SYMBOL_VALUE_ADDRESS (msym);
+ data->known_tasks_element =
+ builtin_type (target_gdbarch)->builtin_data_ptr;
+ data->known_tasks_length = 1;
return;
}
+ /* Can't find tasks. */
+
data->known_tasks_kind = ADA_TASKS_NOT_FOUND;
data->known_tasks_addr = 0;
}
@@ -917,9 +968,9 @@ read_known_tasks (void)
case ADA_TASKS_NOT_FOUND: /* Tasking not in use in inferior. */
return 0;
case ADA_TASKS_ARRAY:
- return read_known_tasks_array (data->known_tasks_addr);
+ return read_known_tasks_array (data);
case ADA_TASKS_LIST:
- return read_known_tasks_list (data->known_tasks_addr);
+ return read_known_tasks_list (data);
}
/* Step 3: Set task_list_valid_p, to avoid re-reading the Known_Tasks
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: RFA: [Ada] extract known tasks array parameters from symbol table
2012-02-16 14:40 ` Tristan Gingold
@ 2012-02-16 17:19 ` Joel Brobecker
2012-02-17 16:34 ` Tristan Gingold
0 siblings, 1 reply; 12+ messages in thread
From: Joel Brobecker @ 2012-02-16 17:19 UTC (permalink / raw)
To: Tristan Gingold; +Cc: gdb-patches@sourceware.org ml
> here is the new version, taking into account your comments: I have
> mostly reshaped ada_set_current_inferior_known_tasks_addr, tell me if
> the new form is ok (and then I will test it more thoroughly).
Overall, that looks good to me. I see what you mean in terms of
supporting the stripped runtime (this near duplication is ugly),
but I don't see an efficient way to avoid it.
Just one minor comment:
> @@ -865,27 +848,95 @@ get_known_tasks_addr (const char *name)
> static void
> ada_set_current_inferior_known_tasks_addr (struct ada_tasks_inferior_data *data)
I would change the name of the function since it's doing more and more
than just setting the address. Something like "set_ada_tasks_inferior_data"
for instance, or maybe "ada_tasks_inferior_data_sniffer", etc.
Can you also update the comment to just say that it sets all fields in
DATA instead of specifying each one? It's a bit more vague, but still
true nonetheless, and will avoid having to update the comment if we add
new fields again in the future.
Thank you!
--
Joel
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: RFA: [Ada] extract known tasks array parameters from symbol table
2012-02-16 17:19 ` Joel Brobecker
@ 2012-02-17 16:34 ` Tristan Gingold
2012-02-17 16:37 ` Joel Brobecker
0 siblings, 1 reply; 12+ messages in thread
From: Tristan Gingold @ 2012-02-17 16:34 UTC (permalink / raw)
To: Joel Brobecker; +Cc: gdb-patches@sourceware.org ml
On Feb 16, 2012, at 6:15 PM, Joel Brobecker wrote:
>> here is the new version, taking into account your comments: I have
>> mostly reshaped ada_set_current_inferior_known_tasks_addr, tell me if
>> the new form is ok (and then I will test it more thoroughly).
>
> Overall, that looks good to me. I see what you mean in terms of
> supporting the stripped runtime (this near duplication is ugly),
> but I don't see an efficient way to avoid it.
>
> Just one minor comment:
>
>> @@ -865,27 +848,95 @@ get_known_tasks_addr (const char *name)
>> static void
>> ada_set_current_inferior_known_tasks_addr (struct ada_tasks_inferior_data *data)
>
> I would change the name of the function since it's doing more and more
> than just setting the address. Something like "set_ada_tasks_inferior_data"
> for instance, or maybe "ada_tasks_inferior_data_sniffer", etc.
>
> Can you also update the comment to just say that it sets all fields in
> DATA instead of specifying each one? It's a bit more vague, but still
> true nonetheless, and will avoid having to update the comment if we add
> new fields again in the future.
So, like this ?
Tristan.
gdb/
2012-02-13 Tristan Gingold <gingold@adacore.com>
* ada-tasks.c (struct ada_tasks_inferior_data): Add
known_tasks_element and known_tasks_length fields.
(read_known_tasks_array): Change argument type. Use pointer type
and number of elements from DATA. Adjust.
(read_known_tasks_list): Likewise.
(get_known_tasks_addr): Remove.
(ada_set_current_inferior_known_tasks_addr): Renamed to ...
(ada_tasks_inferior_data_sniffer): ... this. Try symtab first.
Merge former get_known_tasks_addr code.
diff --git a/gdb/ada-tasks.c b/gdb/ada-tasks.c
index 274d83a..2ee573e 100644
--- a/gdb/ada-tasks.c
+++ b/gdb/ada-tasks.c
@@ -215,6 +215,12 @@ struct ada_tasks_inferior_data
above. */
CORE_ADDR known_tasks_addr;
+ /* Type of elements of the known task. Usually a pointer. */
+ struct type *known_tasks_element;
+
+ /* Number of elements in the known tasks array. */
+ unsigned int known_tasks_length;
+
/* When nonzero, this flag indicates that the task_list field
below is up to date. When set to zero, the list has either
not been initialized, or has potentially become stale. */
@@ -774,24 +780,21 @@ add_ada_task (CORE_ADDR task_id, struct inferior *inf)
it in the current inferior's TASK_LIST. Return non-zero upon success. */
static int
-read_known_tasks_array (CORE_ADDR known_tasks_addr)
+read_known_tasks_array (struct ada_tasks_inferior_data *data)
{
- const int target_ptr_byte =
- gdbarch_ptr_bit (target_gdbarch) / TARGET_CHAR_BIT;
- const int known_tasks_size = target_ptr_byte * MAX_NUMBER_OF_KNOWN_TASKS;
+ const int target_ptr_byte = TYPE_LENGTH (data->known_tasks_element);
+ const int known_tasks_size = target_ptr_byte * data->known_tasks_length;
gdb_byte *known_tasks = alloca (known_tasks_size);
int i;
/* Build a new list by reading the ATCBs from the Known_Tasks array
in the Ada runtime. */
- read_memory (known_tasks_addr, known_tasks, known_tasks_size);
- for (i = 0; i < MAX_NUMBER_OF_KNOWN_TASKS; i++)
+ read_memory (data->known_tasks_addr, known_tasks, known_tasks_size);
+ for (i = 0; i < data->known_tasks_length; i++)
{
- struct type *data_ptr_type =
- builtin_type (target_gdbarch)->builtin_data_ptr;
CORE_ADDR task_id =
extract_typed_address (known_tasks + i * target_ptr_byte,
- data_ptr_type);
+ data->known_tasks_element);
if (task_id != 0)
add_ada_task (task_id, current_inferior ());
@@ -804,13 +807,10 @@ read_known_tasks_array (CORE_ADDR known_tasks_addr)
the current inferior's TASK_LIST. Return non-zero upon success. */
static int
-read_known_tasks_list (CORE_ADDR known_tasks_addr)
+read_known_tasks_list (struct ada_tasks_inferior_data *data)
{
- const int target_ptr_byte =
- gdbarch_ptr_bit (target_gdbarch) / TARGET_CHAR_BIT;
+ const int target_ptr_byte = TYPE_LENGTH (data->known_tasks_element);
gdb_byte *known_tasks = alloca (target_ptr_byte);
- struct type *data_ptr_type =
- builtin_type (target_gdbarch)->builtin_data_ptr;
CORE_ADDR task_id;
const struct ada_tasks_pspace_data *pspace_data
= get_ada_tasks_pspace_data (current_program_space);
@@ -820,8 +820,8 @@ read_known_tasks_list (CORE_ADDR known_tasks_addr)
return 0;
/* Build a new list by reading the ATCBs. Read head of the list. */
- read_memory (known_tasks_addr, known_tasks, target_ptr_byte);
- task_id = extract_typed_address (known_tasks, data_ptr_type);
+ read_memory (data->known_tasks_addr, known_tasks, target_ptr_byte);
+ task_id = extract_typed_address (known_tasks, data->known_tasks_element);
while (task_id != 0)
{
struct value *tcb_value;
@@ -841,51 +841,101 @@ read_known_tasks_list (CORE_ADDR known_tasks_addr)
return 1;
}
-/* Return the address of the variable NAME that contains all the known
- tasks maintained in the Ada Runtime. Return NULL if the variable
- could not be found, meaning that the inferior program probably does
- not use tasking. */
+/* Set all fields of the current inferior ada-tasks data pointed by DATA.
+ Do nothing if those fields are already set and still up to date. */
-static CORE_ADDR
-get_known_tasks_addr (const char *name)
+static void
+ada_tasks_inferior_data_sniffer (struct ada_tasks_inferior_data *data)
{
+ const char *name;
struct minimal_symbol *msym;
+ struct symbol *sym;
- msym = lookup_minimal_symbol (name, NULL, NULL);
- if (msym == NULL)
- return 0;
+ /* Return now if already set. */
+ if (data->known_tasks_kind != ADA_TASKS_UNKNOWN)
+ return;
- return SYMBOL_VALUE_ADDRESS (msym);
-}
+ /* First with the symtab, which knows the exact array type and size. */
-/* Assuming DATA is the ada-tasks' data for the current inferior,
- set the known_tasks_kind and known_tasks_addr fields. Do nothing
- if those fields are already set and still up to date. */
+ /* Try array. */
-static void
-ada_set_current_inferior_known_tasks_addr (struct ada_tasks_inferior_data *data)
-{
- CORE_ADDR known_tasks_addr;
+ sym = lookup_symbol_in_language (KNOWN_TASKS_NAME, NULL, VAR_DOMAIN,
+ language_c, NULL);
+ if (sym != NULL)
+ {
+ /* Validate. */
+ struct type *type = check_typedef (SYMBOL_TYPE (sym));
+ struct type *eltype;
+ struct type *idxtype;
+
+ if (TYPE_CODE (type) == TYPE_CODE_ARRAY
+ && (eltype = check_typedef (TYPE_TARGET_TYPE (type)))
+ && TYPE_CODE (eltype) == TYPE_CODE_PTR
+ && (idxtype = check_typedef (TYPE_INDEX_TYPE (type)))
+ && !TYPE_LOW_BOUND_UNDEFINED (idxtype)
+ && !TYPE_HIGH_BOUND_UNDEFINED (idxtype))
+ {
+ data->known_tasks_kind = ADA_TASKS_ARRAY;
+ data->known_tasks_addr = SYMBOL_VALUE_ADDRESS (sym);
+ data->known_tasks_element = eltype;
+ data->known_tasks_length =
+ TYPE_HIGH_BOUND (idxtype) - TYPE_LOW_BOUND (idxtype) + 1;
+ return;
+ }
+ }
- if (data->known_tasks_kind != ADA_TASKS_UNKNOWN)
- return;
+ /* Try list. */
- known_tasks_addr = get_known_tasks_addr (KNOWN_TASKS_NAME);
- if (known_tasks_addr != 0)
+ sym = lookup_symbol_in_language (KNOWN_TASKS_LIST, NULL, VAR_DOMAIN,
+ language_c, NULL);
+ if (sym != NULL)
+ {
+ /* Validate. */
+ struct type *type = check_typedef (SYMBOL_TYPE (sym));
+
+ if (TYPE_CODE (type) == TYPE_CODE_PTR)
+ {
+ data->known_tasks_kind = ADA_TASKS_LIST;
+ data->known_tasks_addr = SYMBOL_VALUE_ADDRESS (sym);
+ data->known_tasks_element = type;
+ data->known_tasks_length = 1;
+ return;
+ }
+ }
+
+ /* Fallback using the minsymtab. The runtime may have been stripped (as in
+ some distributions), but it is likely that the executable still contains
+ debug information on the task type (due to implicit with of Ada.Tasking).
+ */
+
+ /* Try array. */
+
+ msym = lookup_minimal_symbol (KNOWN_TASKS_NAME, NULL, NULL);
+ if (msym != NULL)
{
data->known_tasks_kind = ADA_TASKS_ARRAY;
- data->known_tasks_addr = known_tasks_addr;
+ data->known_tasks_addr = SYMBOL_VALUE_ADDRESS (msym);
+ data->known_tasks_element =
+ builtin_type (target_gdbarch)->builtin_data_ptr;
+ data->known_tasks_length = MAX_NUMBER_OF_KNOWN_TASKS;
return;
}
- known_tasks_addr = get_known_tasks_addr (KNOWN_TASKS_LIST);
- if (known_tasks_addr != 0)
+ /* Try list. */
+
+ msym = lookup_minimal_symbol (KNOWN_TASKS_LIST, NULL, NULL);
+ if (msym != NULL)
{
data->known_tasks_kind = ADA_TASKS_LIST;
- data->known_tasks_addr = known_tasks_addr;
+ data->known_tasks_addr = SYMBOL_VALUE_ADDRESS (msym);
+ data->known_tasks_element =
+ builtin_type (target_gdbarch)->builtin_data_ptr;
+ data->known_tasks_length = 1;
return;
}
+ /* Can't find tasks. */
+
data->known_tasks_kind = ADA_TASKS_NOT_FOUND;
data->known_tasks_addr = 0;
}
@@ -909,7 +959,7 @@ read_known_tasks (void)
return, as we don't want a stale task list to be used... This can
happen for instance when debugging a non-multitasking program after
having debugged a multitasking one. */
- ada_set_current_inferior_known_tasks_addr (data);
+ ada_tasks_inferior_data_sniffer (data);
gdb_assert (data->known_tasks_kind != ADA_TASKS_UNKNOWN);
switch (data->known_tasks_kind)
@@ -917,9 +967,9 @@ read_known_tasks (void)
case ADA_TASKS_NOT_FOUND: /* Tasking not in use in inferior. */
return 0;
case ADA_TASKS_ARRAY:
- return read_known_tasks_array (data->known_tasks_addr);
+ return read_known_tasks_array (data);
case ADA_TASKS_LIST:
- return read_known_tasks_list (data->known_tasks_addr);
+ return read_known_tasks_list (data);
}
/* Step 3: Set task_list_valid_p, to avoid re-reading the Known_Tasks
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: RFA: [Ada] extract known tasks array parameters from symbol table
2012-02-17 16:34 ` Tristan Gingold
@ 2012-02-17 16:37 ` Joel Brobecker
2012-02-17 19:23 ` Tristan Gingold
2012-02-20 17:11 ` Tristan Gingold
0 siblings, 2 replies; 12+ messages in thread
From: Joel Brobecker @ 2012-02-17 16:37 UTC (permalink / raw)
To: Tristan Gingold; +Cc: gdb-patches@sourceware.org ml
> So, like this ?
[...]
> gdb/
> 2012-02-13 Tristan Gingold <gingold@adacore.com>
>
> * ada-tasks.c (struct ada_tasks_inferior_data): Add
> known_tasks_element and known_tasks_length fields.
> (read_known_tasks_array): Change argument type. Use pointer type
> and number of elements from DATA. Adjust.
> (read_known_tasks_list): Likewise.
> (get_known_tasks_addr): Remove.
> (ada_set_current_inferior_known_tasks_addr): Renamed to ...
> (ada_tasks_inferior_data_sniffer): ... this. Try symtab first.
> Merge former get_known_tasks_addr code.
Yep! That looks good to me.
Thanks!
--
Joel
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: RFA: [Ada] extract known tasks array parameters from symbol table
2012-02-17 16:37 ` Joel Brobecker
@ 2012-02-17 19:23 ` Tristan Gingold
2012-02-20 17:11 ` Tristan Gingold
1 sibling, 0 replies; 12+ messages in thread
From: Tristan Gingold @ 2012-02-17 19:23 UTC (permalink / raw)
To: Joel Brobecker; +Cc: gdb-patches@sourceware.org ml
On Feb 17, 2012, at 5:34 PM, Joel Brobecker wrote:
>> So, like this ?
> [...]
>> gdb/
>> 2012-02-13 Tristan Gingold <gingold@adacore.com>
>>
>> * ada-tasks.c (struct ada_tasks_inferior_data): Add
>> known_tasks_element and known_tasks_length fields.
>> (read_known_tasks_array): Change argument type. Use pointer type
>> and number of elements from DATA. Adjust.
>> (read_known_tasks_list): Likewise.
>> (get_known_tasks_addr): Remove.
>> (ada_set_current_inferior_known_tasks_addr): Renamed to ...
>> (ada_tasks_inferior_data_sniffer): ... this. Try symtab first.
>> Merge former get_known_tasks_addr code.
>
> Yep! That looks good to me.
Ok, so I will commit after checking it on Linux and with ravenscar (i.e., not before Monday :-)
Thanks,
Tristan.
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: RFA: [Ada] extract known tasks array parameters from symbol table
2012-02-17 16:37 ` Joel Brobecker
2012-02-17 19:23 ` Tristan Gingold
@ 2012-02-20 17:11 ` Tristan Gingold
2012-02-21 18:16 ` Joel Brobecker
1 sibling, 1 reply; 12+ messages in thread
From: Tristan Gingold @ 2012-02-20 17:11 UTC (permalink / raw)
To: Joel Brobecker; +Cc: gdb-patches@sourceware.org ml
On Feb 17, 2012, at 5:34 PM, Joel Brobecker wrote:
>> So, like this ?
> [...]
>> gdb/
>> 2012-02-13 Tristan Gingold <gingold@adacore.com>
>>
>> * ada-tasks.c (struct ada_tasks_inferior_data): Add
>> known_tasks_element and known_tasks_length fields.
>> (read_known_tasks_array): Change argument type. Use pointer type
>> and number of elements from DATA. Adjust.
>> (read_known_tasks_list): Likewise.
>> (get_known_tasks_addr): Remove.
>> (ada_set_current_inferior_known_tasks_addr): Renamed to ...
>> (ada_tasks_inferior_data_sniffer): ... this. Try symtab first.
>> Merge former get_known_tasks_addr code.
>
> Yep! That looks good to me.
In fact it wasn't that good. Leads to crash in case the symbol was LOC_UNRESOLVED. It is therefore better to use the minsymtab to get the address. Here is the new version.
Tristan.
2012-02-13 Tristan Gingold <gingold@adacore.com>
* ada-tasks.c (struct ada_tasks_inferior_data): Add
known_tasks_element and known_tasks_length fields.
(read_known_tasks_array): Change argument type. Use pointer type
and number of elements from DATA. Adjust.
(read_known_tasks_list): Likewise.
(get_known_tasks_addr): Remove.
(ada_set_current_inferior_known_tasks_addr): Renamed to ...
(ada_tasks_inferior_data_sniffer): ... this. Use symtab for element
type and array length. Merge former get_known_tasks_addr code.
diff --git a/gdb/ada-tasks.c b/gdb/ada-tasks.c
index 274d83a..4c0b667 100644
--- a/gdb/ada-tasks.c
+++ b/gdb/ada-tasks.c
@@ -215,6 +215,12 @@ struct ada_tasks_inferior_data
above. */
CORE_ADDR known_tasks_addr;
+ /* Type of elements of the known task. Usually a pointer. */
+ struct type *known_tasks_element;
+
+ /* Number of elements in the known tasks array. */
+ unsigned int known_tasks_length;
+
/* When nonzero, this flag indicates that the task_list field
below is up to date. When set to zero, the list has either
not been initialized, or has potentially become stale. */
@@ -774,24 +780,21 @@ add_ada_task (CORE_ADDR task_id, struct inferior *inf)
it in the current inferior's TASK_LIST. Return non-zero upon success. */
static int
-read_known_tasks_array (CORE_ADDR known_tasks_addr)
+read_known_tasks_array (struct ada_tasks_inferior_data *data)
{
- const int target_ptr_byte =
- gdbarch_ptr_bit (target_gdbarch) / TARGET_CHAR_BIT;
- const int known_tasks_size = target_ptr_byte * MAX_NUMBER_OF_KNOWN_TASKS;
+ const int target_ptr_byte = TYPE_LENGTH (data->known_tasks_element);
+ const int known_tasks_size = target_ptr_byte * data->known_tasks_length;
gdb_byte *known_tasks = alloca (known_tasks_size);
int i;
/* Build a new list by reading the ATCBs from the Known_Tasks array
in the Ada runtime. */
- read_memory (known_tasks_addr, known_tasks, known_tasks_size);
- for (i = 0; i < MAX_NUMBER_OF_KNOWN_TASKS; i++)
+ read_memory (data->known_tasks_addr, known_tasks, known_tasks_size);
+ for (i = 0; i < data->known_tasks_length; i++)
{
- struct type *data_ptr_type =
- builtin_type (target_gdbarch)->builtin_data_ptr;
CORE_ADDR task_id =
extract_typed_address (known_tasks + i * target_ptr_byte,
- data_ptr_type);
+ data->known_tasks_element);
if (task_id != 0)
add_ada_task (task_id, current_inferior ());
@@ -804,13 +807,10 @@ read_known_tasks_array (CORE_ADDR known_tasks_addr)
the current inferior's TASK_LIST. Return non-zero upon success. */
static int
-read_known_tasks_list (CORE_ADDR known_tasks_addr)
+read_known_tasks_list (struct ada_tasks_inferior_data *data)
{
- const int target_ptr_byte =
- gdbarch_ptr_bit (target_gdbarch) / TARGET_CHAR_BIT;
+ const int target_ptr_byte = TYPE_LENGTH (data->known_tasks_element);
gdb_byte *known_tasks = alloca (target_ptr_byte);
- struct type *data_ptr_type =
- builtin_type (target_gdbarch)->builtin_data_ptr;
CORE_ADDR task_id;
const struct ada_tasks_pspace_data *pspace_data
= get_ada_tasks_pspace_data (current_program_space);
@@ -820,8 +820,8 @@ read_known_tasks_list (CORE_ADDR known_tasks_addr)
return 0;
/* Build a new list by reading the ATCBs. Read head of the list. */
- read_memory (known_tasks_addr, known_tasks, target_ptr_byte);
- task_id = extract_typed_address (known_tasks, data_ptr_type);
+ read_memory (data->known_tasks_addr, known_tasks, target_ptr_byte);
+ task_id = extract_typed_address (known_tasks, data->known_tasks_element);
while (task_id != 0)
{
struct value *tcb_value;
@@ -841,51 +841,95 @@ read_known_tasks_list (CORE_ADDR known_tasks_addr)
return 1;
}
-/* Return the address of the variable NAME that contains all the known
- tasks maintained in the Ada Runtime. Return NULL if the variable
- could not be found, meaning that the inferior program probably does
- not use tasking. */
-
-static CORE_ADDR
-get_known_tasks_addr (const char *name)
-{
- struct minimal_symbol *msym;
-
- msym = lookup_minimal_symbol (name, NULL, NULL);
- if (msym == NULL)
- return 0;
-
- return SYMBOL_VALUE_ADDRESS (msym);
-}
-
-/* Assuming DATA is the ada-tasks' data for the current inferior,
- set the known_tasks_kind and known_tasks_addr fields. Do nothing
- if those fields are already set and still up to date. */
+/* Set all fields of the current inferior ada-tasks data pointed by DATA.
+ Do nothing if those fields are already set and still up to date. */
static void
-ada_set_current_inferior_known_tasks_addr (struct ada_tasks_inferior_data *data)
+ada_tasks_inferior_data_sniffer (struct ada_tasks_inferior_data *data)
{
- CORE_ADDR known_tasks_addr;
+ const char *name;
+ struct minimal_symbol *msym;
+ struct symbol *sym;
+ /* Return now if already set. */
if (data->known_tasks_kind != ADA_TASKS_UNKNOWN)
return;
- known_tasks_addr = get_known_tasks_addr (KNOWN_TASKS_NAME);
- if (known_tasks_addr != 0)
+ /* Try array. */
+
+ msym = lookup_minimal_symbol (KNOWN_TASKS_NAME, NULL, NULL);
+ if (msym != NULL)
{
data->known_tasks_kind = ADA_TASKS_ARRAY;
- data->known_tasks_addr = known_tasks_addr;
+ data->known_tasks_addr = SYMBOL_VALUE_ADDRESS (msym);
+
+ /* Try to get pointer type and array length from the symtab. */
+ sym = lookup_symbol_in_language (KNOWN_TASKS_NAME, NULL, VAR_DOMAIN,
+ language_c, NULL);
+ if (sym != NULL)
+ {
+ /* Validate. */
+ struct type *type = check_typedef (SYMBOL_TYPE (sym));
+ struct type *eltype;
+ struct type *idxtype;
+
+ if (TYPE_CODE (type) == TYPE_CODE_ARRAY
+ && (eltype = check_typedef (TYPE_TARGET_TYPE (type)))
+ && TYPE_CODE (eltype) == TYPE_CODE_PTR
+ && (idxtype = check_typedef (TYPE_INDEX_TYPE (type)))
+ && !TYPE_LOW_BOUND_UNDEFINED (idxtype)
+ && !TYPE_HIGH_BOUND_UNDEFINED (idxtype))
+ {
+ data->known_tasks_element = eltype;
+ data->known_tasks_length =
+ TYPE_HIGH_BOUND (idxtype) - TYPE_LOW_BOUND (idxtype) + 1;
+ return;
+ }
+ }
+
+ /* Fallback to default values. The runtime may have been stripped (as
+ in some distributions), but it is likely that the executable still
+ contains debug information on the task type (due to implicit with of
+ Ada.Tasking). */
+ data->known_tasks_element =
+ builtin_type (target_gdbarch)->builtin_data_ptr;
+ data->known_tasks_length = MAX_NUMBER_OF_KNOWN_TASKS;
return;
}
- known_tasks_addr = get_known_tasks_addr (KNOWN_TASKS_LIST);
- if (known_tasks_addr != 0)
+
+ /* Try list. */
+
+ msym = lookup_minimal_symbol (KNOWN_TASKS_LIST, NULL, NULL);
+ if (msym != NULL)
{
data->known_tasks_kind = ADA_TASKS_LIST;
- data->known_tasks_addr = known_tasks_addr;
+ data->known_tasks_addr = SYMBOL_VALUE_ADDRESS (msym);
+ data->known_tasks_length = 1;
+
+ sym = lookup_symbol_in_language (KNOWN_TASKS_LIST, NULL, VAR_DOMAIN,
+ language_c, NULL);
+ if (sym != NULL && SYMBOL_VALUE_ADDRESS (sym) != 0)
+ {
+ /* Validate. */
+ struct type *type = check_typedef (SYMBOL_TYPE (sym));
+
+ if (TYPE_CODE (type) == TYPE_CODE_PTR)
+ {
+ data->known_tasks_element = type;
+ return;
+ }
+ }
+
+ /* Fallback to default values. */
+ data->known_tasks_element =
+ builtin_type (target_gdbarch)->builtin_data_ptr;
+ data->known_tasks_length = 1;
return;
}
+ /* Can't find tasks. */
+
data->known_tasks_kind = ADA_TASKS_NOT_FOUND;
data->known_tasks_addr = 0;
}
@@ -909,7 +953,7 @@ read_known_tasks (void)
return, as we don't want a stale task list to be used... This can
happen for instance when debugging a non-multitasking program after
having debugged a multitasking one. */
- ada_set_current_inferior_known_tasks_addr (data);
+ ada_tasks_inferior_data_sniffer (data);
gdb_assert (data->known_tasks_kind != ADA_TASKS_UNKNOWN);
switch (data->known_tasks_kind)
@@ -917,9 +961,9 @@ read_known_tasks (void)
case ADA_TASKS_NOT_FOUND: /* Tasking not in use in inferior. */
return 0;
case ADA_TASKS_ARRAY:
- return read_known_tasks_array (data->known_tasks_addr);
+ return read_known_tasks_array (data);
case ADA_TASKS_LIST:
- return read_known_tasks_list (data->known_tasks_addr);
+ return read_known_tasks_list (data);
}
/* Step 3: Set task_list_valid_p, to avoid re-reading the Known_Tasks
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: RFA: [Ada] extract known tasks array parameters from symbol table
2012-02-20 17:11 ` Tristan Gingold
@ 2012-02-21 18:16 ` Joel Brobecker
2012-02-23 16:34 ` Tristan Gingold
0 siblings, 1 reply; 12+ messages in thread
From: Joel Brobecker @ 2012-02-21 18:16 UTC (permalink / raw)
To: Tristan Gingold; +Cc: gdb-patches@sourceware.org ml
> In fact it wasn't that good. Leads to crash in case the symbol was
> LOC_UNRESOLVED. It is therefore better to use the minsymtab to get
> the address. Here is the new version.
Ah - Ugh!
> 2012-02-13 Tristan Gingold <gingold@adacore.com>
>
> * ada-tasks.c (struct ada_tasks_inferior_data): Add
> known_tasks_element and known_tasks_length fields.
> (read_known_tasks_array): Change argument type. Use pointer type
> and number of elements from DATA. Adjust.
> (read_known_tasks_list): Likewise.
> (get_known_tasks_addr): Remove.
> (ada_set_current_inferior_known_tasks_addr): Renamed to ...
> (ada_tasks_inferior_data_sniffer): ... this. Use symtab for element
> type and array length. Merge former get_known_tasks_addr code.
This one looks good to me. Thanks!
--
Joel
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: RFA: [Ada] extract known tasks array parameters from symbol table
2012-02-21 18:16 ` Joel Brobecker
@ 2012-02-23 16:34 ` Tristan Gingold
0 siblings, 0 replies; 12+ messages in thread
From: Tristan Gingold @ 2012-02-23 16:34 UTC (permalink / raw)
To: Joel Brobecker; +Cc: gdb-patches@sourceware.org ml
On Feb 21, 2012, at 6:07 PM, Joel Brobecker wrote:
>> In fact it wasn't that good. Leads to crash in case the symbol was
>> LOC_UNRESOLVED. It is therefore better to use the minsymtab to get
>> the address. Here is the new version.
>
> Ah - Ugh!
>
>> 2012-02-13 Tristan Gingold <gingold@adacore.com>
>>
>> * ada-tasks.c (struct ada_tasks_inferior_data): Add
>> known_tasks_element and known_tasks_length fields.
>> (read_known_tasks_array): Change argument type. Use pointer type
>> and number of elements from DATA. Adjust.
>> (read_known_tasks_list): Likewise.
>> (get_known_tasks_addr): Remove.
>> (ada_set_current_inferior_known_tasks_addr): Renamed to ...
>> (ada_tasks_inferior_data_sniffer): ... this. Use symtab for element
>> type and array length. Merge former get_known_tasks_addr code.
>
> This one looks good to me. Thanks!
Now committed.
Thanks,
Tristan.
^ permalink raw reply [flat|nested] 12+ messages in thread
end of thread, other threads:[~2012-02-23 11:18 UTC | newest]
Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-02-13 15:14 RFA: [Ada] extract known tasks array parameters from symbol table Tristan Gingold
2012-02-13 16:16 ` Joel Brobecker
2012-02-14 8:19 ` Tristan Gingold
2012-02-14 15:47 ` Joel Brobecker
2012-02-16 14:40 ` Tristan Gingold
2012-02-16 17:19 ` Joel Brobecker
2012-02-17 16:34 ` Tristan Gingold
2012-02-17 16:37 ` Joel Brobecker
2012-02-17 19:23 ` Tristan Gingold
2012-02-20 17:11 ` Tristan Gingold
2012-02-21 18:16 ` Joel Brobecker
2012-02-23 16:34 ` Tristan Gingold
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox