This is the mail archive of the systemtap@sourceware.org mailing list for the systemtap project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: dereferencing pointer to incomplete type ‘struct workqueue_struct’


Thanks David, this is helpful.  Struct definitions in .c files is new
to me.  I'll also check out using kderef_* as well.  Thanks!

On Thu, Apr 27, 2017 at 10:43 AM, David Smith <dsmith@redhat.com> wrote:
> If you look carefully, workqueue_struct isn't defined in
> include/linux/workqueue.h. It is declared ("struct
> workqueue_struct;"), but never fully defined ("struct workqueue_struct
> { char *name, ... }") in that file. So, that's why the compiler is
> giving you that error. It has nothing to do with systemtap, if you
> tried to compile a kernel module without systemtap, you'd get the same
> error. The workqueue_struct definition is private to the workqueue.c
> file.
>
> Strangely enough, systemtap use of debuginfo would give it a
> definition of that structure. So, you could write something like the
> following in script language:
>
> ====
> function display_wq_name:long(wq:long)
> {
>     printf("workqueue struct %s\n", @cast(wq, "workqueue_struct")->name)
> }
> ====
>
> However, the problem is iterating through that list in script
> language. To do that correctly, you'd need embedded-C as you've got
> here.
>
> To solve your problem, unfortunately copying the workqueue_struct
> definition into your module is the only way to go to make the compiler
> happy. Of course if you plan to use this long term, you'll have to
> keep an eye on that private structure and be on the lookout for
> changes.
>
> Also note that if this is just a one-off exercise, your code is fine.
> If you planned to use this long term or on a system you really cared
> about, you'd need to change it to use systemtap's kderef_* functions
> to ensure that memory is safe to read.
>
>
> On Thu, Apr 27, 2017 at 8:02 AM, John Busch <jbusch175@gmail.com> wrote:
>> This worked for me.  Thank you Arkady!
>>
>> On Thu, Apr 27, 2017 at 3:07 AM, Arkady <arkady.miasnikov@gmail.com> wrote:
>>> The simplest way to resolve the problem is top copy the struct to the
>>> inline C code
>>>
>>> http://lxr.free-electrons.com/source/kernel/workqueue.c#L239
>>>
>>> On Wed, Apr 26, 2017 at 6:20 PM, John Busch <jbusch175@gmail.com> wrote:
>>>> Hello,
>>>>
>>>> I’m new to SystemTap, and trying to print information about kernel
>>>> work queues.  I’ve used the example code in section 4.3 [1] of the
>>>> tutorial as my starting point, and I’m working on an up-to-date Fedora
>>>> 25 system.
>>>>
>>>> The example code in the tutorial works just fine.  However, when I
>>>> essentially swap out variable and struct names to modify the example
>>>> to walk through workqueue_structs (instead of task_structs), I get a
>>>> “dereferencing pointer to incomplete type ‘struct workqueue_struct’”
>>>> compilation error on the line containing list_for_each_safe.  Code
>>>> sample below.
>>>>
>>>> workqueue_struct is defined in workqueue.h [2] and workqueue.c [4],
>>>> and I’m trying to access the global variable system_wq [3, 5].  How
>>>> would I gain access to these objects in systemtap?  I must be doing
>>>> something wrong, but can't figure out what it is.
>>>>
>>>> Thanks!
>>>>
>>>> [1] https://sourceware.org/systemtap/tutorial/Tapsets.html
>>>> [2] http://lxr.free-electrons.com/source/include/linux/workqueue.h#L16
>>>> [3] http://lxr.free-electrons.com/source/include/linux/workqueue.h#L365
>>>> [4] http://lxr.free-electrons.com/source/kernel/workqueue.c#L239
>>>> [5] http://lxr.free-electrons.com/source/kernel/workqueue.c#L338
>>>>
>>>> %{
>>>> #include <linux/workqueue.h>
>>>> #include <linux/list.h>
>>>> %}
>>>>
>>>> function read_wq_list:long ()
>>>> %{
>>>>    int ret = 0;
>>>>    struct workqueue_struct *wq;
>>>>    struct list_head *p, *n;
>>>>
>>>>    list_for_each_safe(p, n, system_wq->list) {
>>>>        wq = list_entry(p, struct workqueue_struct, list);
>>>>        _stp_printf("workqueue struct %s\n", wq->name);
>>>>    }
>>>>
>>>>    STAP_RETURN(ret);
>>>> %}
>>>>
>>>> probe begin
>>>> {
>>>> printf("reading list of workqueues\n")
>>>> read_wq_list()
>>>> exit()
>>>> }
>
>
>
> --
> David Smith
> Principal Software Engineer
> Red Hat


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]