debugobjects: print more data
Subsystems (3)
PATCH v5 1/1 debugobjects: print more data
On complex subsystems like mac80211, structures may include many timers and works. In such case, based only on call trace and object type is hard to conclude where bug could possibly be.
Patch extend debug object descriptor to additional debug hint function. If defined, it return address, which have associated kernel symbol (i.e. hrtimer->function pointer). We print that symbol when bug is detected, to identify the object.
Patch contains debug hint methods for timer_list, work_struct and hrtimer.
---
Cc Andrew, perhaps this could be merged through mm?
v1 -> v2:
- do not invent custom functions for print symbols
- remove not necessary null check, use same call convention like other methods
- fix stray whitespace
- print only symbol name (no function pointer)
v2 -> v3:
- remove remaining kallsyms changes
v3 -> v4:
- make callbacks static
v4 -> v5:
- do not drop WARN
- change "print" method to "debug_hint"
include/linux/debugobjects.h | 5 ++++- kernel/hrtimer.c | 6 ++++++ kernel/timer.c | 6 ++++++ kernel/workqueue.c | 6 ++++++ lib/debugobjects.c | 9 ++++++--- 5 files changed, 28 insertions(+), 4 deletions(-)
include/linux/debugobjects.h +4 -1
@@ -34,7 +34,10 @@ struct debug_obj {/** * struct debug_obj_descr - object type specific debug description structure +* * @name: name of the object typee +* @debug_hint: function returning address, which have associated +* kernel symbol, to allow identify the object * @fixup_init: fixup function, which is called when the init check * fails * @fixup_activate: fixup function, which is called when the activate check
@@ -46,7 +49,7 @@ struct debug_obj {*/ struct debug_obj_descr {const char *name; - +void *(*debug_hint) (void *addr);int (*fixup_init) (void *addr,enum debug_obj_state state);int (*fixup_activate) (void *addr,enum debug_obj_state state);int (*fixup_destroy) (void *addr,enum debug_obj_state state);
kernel/hrtimer.c +6 -0
@@ -334,6 +334,11 @@ EXPORT_SYMBOL_GPL(ktime_add_safe);static struct debug_obj_descr hrtimer_debug_descr; +static void *hrtimer_debug_hint (void *addr) +{ +return ((struct hrtimer *) addr)->function; +} +/* * fixup_init is called when: * - an active object is initialized
@@ -393,6 +398,7 @@ static int hrtimer_fixup_free(void *addr, enum debug_obj_state state)static struct debug_obj_descr hrtimer_debug_descr = { .name ="hrtimer" , + .debug_hint = hrtimer_debug_hint, .fixup_init = hrtimer_fixup_init, .fixup_activate = hrtimer_fixup_activate, .fixup_free = hrtimer_fixup_free,
kernel/timer.c +6 -0
@@ -404,6 +404,11 @@ static void timer_stats_account_timer(struct timer_list *timer) {}static struct debug_obj_descr timer_debug_descr; +static void *timer_debug_hint (void *addr) +{ +return ((struct timer_list *) addr)->function; +} +/* * fixup_init is called when: * - an active object is initialized
@@ -477,6 +482,7 @@ static int timer_fixup_free(void *addr, enum debug_obj_state state)static struct debug_obj_descr timer_debug_descr = { .name ="timer_list" , + .debug_hint = timer_debug_hint, .fixup_init = timer_fixup_init, .fixup_activate = timer_fixup_activate, .fixup_free = timer_fixup_free,
kernel/workqueue.c +6 -0
@@ -314,6 +314,11 @@ static inline int __next_wq_cpu(int cpu, const struct cpumask *mask,static struct debug_obj_descr work_debug_descr; +static void *work_debug_hint (void *addr) +{ + return ((struct work_struct *work) addr)->func; +} +/* * fixup_init is called when: * - an active object is initialized
@@ -385,6 +390,7 @@ static int work_fixup_free(void *addr, enum debug_obj_state state)static struct debug_obj_descr work_debug_descr = { .name ="work_struct" , + .debug_hint = work_debug_hint, .fixup_init = work_fixup_init, .fixup_activate = work_fixup_activate, .fixup_free = work_fixup_free,
lib/debugobjects.c +6 -3
@@ -249,14 +249,17 @@ static struct debug_bucket *get_bucket(unsigned long addr)static void debug_print_object (struct debug_obj *obj,char *msg) { +struct debug_obj_descr *descr = obj->descr;static int limit; -if (limit <5 && obj->descr != descr_test) { +if (limit <5 && descr != descr_test) { +void *hint = descr->debug_hint ? + descr->debug_hint (obj->object) :NULL ; limit++;WARN (1 ,KERN_ERR "ODEBUG: %s %s (active state %u) " -"object type: %s\n" , +"object type: %s hint: %pS\n" , msg, obj_states[obj->state], obj->astate, - obj->descr->name); + descr->name, hint); } debug_objects_warnings++; }
Signature · 1 line
1.7.1
Quoted 9 lines · Stanislaw Gruszka
On complex subsystems like mac80211, structures may include many timers and works. In such case, based only on call trace and object type is hard to conclude where bug could possibly be.
Patch extend debug object descriptor to additional debug hint function. If defined, it return address, which have associated kernel symbol (i.e.
hrtimer->functionpointer). We print that symbol when bug is detected, to identify the object.
Quoted 6 lines
Patch contains debug hint methods for
timer_list,work_structand hrtimer.Signed-off-by Stanislaw Gruszka <[email protected]>---
Cc Andrew, perhaps this could be merged through mm?
It's on my list. I just was away for a few days.
[tip:core/debugobjects] debugobjects: Add hint for better object identification
In reply to Stanislaw GruszkaCommit-ID: be1e60006500eebfb3b82e0c0915ea898dfd224e Gitweb: http://git.kernel.org/tip/be1e60006500eebfb3b82e0c0915ea898dfd224e Author: Stanislaw Gruszka <[email protected]> AuthorDate: Mon, 7 Mar 2011 09:58:33 +0100 Committer: Thomas Gleixner <[email protected]> CommitDate: Tue, 8 Mar 2011 10:25:47 +0100
debugobjects: Add hint for better object identification
In complex subsystems like mac80211 structures can contain several timers and work structs, so identifying a specific instance from the call trace and object type output of debugobjects can be hard.
Allow the subsystems which support debugobjects to provide a hint function. This function returns a pointer to a kernel address (preferrably the objects callback function) which is printed along with the debugobjects type.
Add hint methods for timer_list, work_struct and hrtimer.
[ tglx: Massaged changelog ]
LKML-Reference: <[email protected]>
--- include/linux/debugobjects.h | 5 ++++- kernel/hrtimer.c | 6 ++++++ kernel/timer.c | 6 ++++++ kernel/workqueue.c | 6 ++++++ lib/debugobjects.c | 9 ++++++--- 5 files changed, 28 insertions(+), 4 deletions(-)
include/linux/debugobjects.h +4 -1
@@ -34,7 +34,10 @@ struct debug_obj {/** * struct debug_obj_descr - object type specific debug description structure +* * @name: name of the object typee +* @debug_hint: function returning address, which have associated +* kernel symbol, to allow identify the object * @fixup_init: fixup function, which is called when the init check * fails * @fixup_activate: fixup function, which is called when the activate check
@@ -46,7 +49,7 @@ struct debug_obj {*/ struct debug_obj_descr {const char *name; - +void *(*debug_hint) (void *addr);int (*fixup_init) (void *addr,enum debug_obj_state state);int (*fixup_activate) (void *addr,enum debug_obj_state state);int (*fixup_destroy) (void *addr,enum debug_obj_state state);
kernel/hrtimer.c +6 -0
@@ -334,6 +334,11 @@ EXPORT_SYMBOL_GPL(ktime_add_safe);static struct debug_obj_descr hrtimer_debug_descr; +static void *hrtimer_debug_hint (void *addr) +{ +return ((struct hrtimer *) addr)->function; +} +/* * fixup_init is called when: * - an active object is initialized
@@ -393,6 +398,7 @@ static int hrtimer_fixup_free(void *addr, enum debug_obj_state state)static struct debug_obj_descr hrtimer_debug_descr = { .name ="hrtimer" , + .debug_hint = hrtimer_debug_hint, .fixup_init = hrtimer_fixup_init, .fixup_activate = hrtimer_fixup_activate, .fixup_free = hrtimer_fixup_free,
kernel/timer.c +6 -0
@@ -404,6 +404,11 @@ static void timer_stats_account_timer(struct timer_list *timer) {}static struct debug_obj_descr timer_debug_descr; +static void *timer_debug_hint (void *addr) +{ +return ((struct timer_list *) addr)->function; +} +/* * fixup_init is called when: * - an active object is initialized
@@ -477,6 +482,7 @@ static int timer_fixup_free(void *addr, enum debug_obj_state state)static struct debug_obj_descr timer_debug_descr = { .name ="timer_list" , + .debug_hint = timer_debug_hint, .fixup_init = timer_fixup_init, .fixup_activate = timer_fixup_activate, .fixup_free = timer_fixup_free,
kernel/workqueue.c +6 -0
@@ -316,6 +316,11 @@ static inline int __next_wq_cpu(int cpu, const struct cpumask *mask,static struct debug_obj_descr work_debug_descr; +static void *work_debug_hint (void *addr) +{ + return ((struct work_struct *work) addr)->func; +} +/* * fixup_init is called when: * - an active object is initialized
@@ -387,6 +392,7 @@ static int work_fixup_free(void *addr, enum debug_obj_state state)static struct debug_obj_descr work_debug_descr = { .name ="work_struct" , + .debug_hint = work_debug_hint, .fixup_init = work_fixup_init, .fixup_activate = work_fixup_activate, .fixup_free = work_fixup_free,
lib/debugobjects.c +6 -3
@@ -249,14 +249,17 @@ static struct debug_bucket *get_bucket(unsigned long addr)static void debug_print_object (struct debug_obj *obj,char *msg) { +struct debug_obj_descr *descr = obj->descr;static int limit; -if (limit <5 && obj->descr != descr_test) { +if (limit <5 && descr != descr_test) { +void *hint = descr->debug_hint ? + descr->debug_hint (obj->object) :NULL ; limit++;WARN (1 ,KERN_ERR "ODEBUG: %s %s (active state %u) " -"object type: %s\n" , +"object type: %s hint: %pS\n" , msg, obj_states[obj->state], obj->astate, - obj->descr->name); + descr->name, hint); } debug_objects_warnings++; }
Re: [tip:core/debugobjects] debugobjects: Add hint for better object identification
kernel/workqueue.c static inline int __next_wq_cpu(int cpu, const struct cpumask *mask, · line 322
Quoted 5 lines · tip-bot for Stanislaw Gruszka
kernel/workqueue.c +4
-0+static void *work_debug_hint (void *addr) +{ + return ((struct work_struct *work) addr)->func; +}
Care to send compilable patches ?
Thanks,
tglx
Re: [tip:core/debugobjects] debugobjects: Add hint for better object identification
Quoted 5 lines · Thomas Gleixner
kernel/workqueue.c static inline int __next_wq_cpu(int cpu, const struct cpumask *mask, · line 321
Quoted 4 lines · tip-bot for Stanislaw Gruszka
kernel/workqueue.c +3
-0+static void *work_debug_hint (void *addr) +{ + return ((struct work_struct *work) addr)->func;
Uhh.
Quoted 1 line
Care to send compilable patches ?
I'm sorry, it compile here with
gcc version 4.4.4 20100726 (Red Hat 4.4.4-13).
Could you fix it, or should I repost?
Stanislaw
[tip:core/debugobjects] debugobjects: Add hint for better object identification
In reply to Stanislaw GruszkaCommit-ID: 997772884036e6e121de39322179989154437d9f Gitweb: http://git.kernel.org/tip/997772884036e6e121de39322179989154437d9f Author: Stanislaw Gruszka <[email protected]> AuthorDate: Mon, 7 Mar 2011 09:58:33 +0100 Committer: Thomas Gleixner <[email protected]> CommitDate: Tue, 8 Mar 2011 16:10:38 +0100
debugobjects: Add hint for better object identification
In complex subsystems like mac80211 structures can contain several timers and work structs, so identifying a specific instance from the call trace and object type output of debugobjects can be hard.
Allow the subsystems which support debugobjects to provide a hint function. This function returns a pointer to a kernel address (preferrably the objects callback function) which is printed along with the debugobjects type.
Add hint methods for timer_list, work_struct and hrtimer.
[ tglx: Massaged changelog, made it compile ]
LKML-Reference: <[email protected]>
--- include/linux/debugobjects.h | 5 ++++- kernel/hrtimer.c | 6 ++++++ kernel/timer.c | 6 ++++++ kernel/workqueue.c | 6 ++++++ lib/debugobjects.c | 9 ++++++--- 5 files changed, 28 insertions(+), 4 deletions(-)
include/linux/debugobjects.h +4 -1
@@ -34,7 +34,10 @@ struct debug_obj {/** * struct debug_obj_descr - object type specific debug description structure +* * @name: name of the object typee +* @debug_hint: function returning address, which have associated +* kernel symbol, to allow identify the object * @fixup_init: fixup function, which is called when the init check * fails * @fixup_activate: fixup function, which is called when the activate check
@@ -46,7 +49,7 @@ struct debug_obj {*/ struct debug_obj_descr {const char *name; - +void *(*debug_hint) (void *addr);int (*fixup_init) (void *addr,enum debug_obj_state state);int (*fixup_activate) (void *addr,enum debug_obj_state state);int (*fixup_destroy) (void *addr,enum debug_obj_state state);
kernel/hrtimer.c +6 -0
@@ -334,6 +334,11 @@ EXPORT_SYMBOL_GPL(ktime_add_safe);static struct debug_obj_descr hrtimer_debug_descr; +static void *hrtimer_debug_hint (void *addr) +{ +return ((struct hrtimer *) addr)->function; +} +/* * fixup_init is called when: * - an active object is initialized
@@ -393,6 +398,7 @@ static int hrtimer_fixup_free(void *addr, enum debug_obj_state state)static struct debug_obj_descr hrtimer_debug_descr = { .name ="hrtimer" , + .debug_hint = hrtimer_debug_hint, .fixup_init = hrtimer_fixup_init, .fixup_activate = hrtimer_fixup_activate, .fixup_free = hrtimer_fixup_free,
kernel/timer.c +6 -0
@@ -404,6 +404,11 @@ static void timer_stats_account_timer(struct timer_list *timer) {}static struct debug_obj_descr timer_debug_descr; +static void *timer_debug_hint (void *addr) +{ +return ((struct timer_list *) addr)->function; +} +/* * fixup_init is called when: * - an active object is initialized
@@ -477,6 +482,7 @@ static int timer_fixup_free(void *addr, enum debug_obj_state state)static struct debug_obj_descr timer_debug_descr = { .name ="timer_list" , + .debug_hint = timer_debug_hint, .fixup_init = timer_fixup_init, .fixup_activate = timer_fixup_activate, .fixup_free = timer_fixup_free,
kernel/workqueue.c +6 -0
@@ -316,6 +316,11 @@ static inline int __next_wq_cpu(int cpu, const struct cpumask *mask,static struct debug_obj_descr work_debug_descr; +static void *work_debug_hint (void *addr) +{ +return ((struct work_struct *) addr)->func; +} +/* * fixup_init is called when: * - an active object is initialized
@@ -387,6 +392,7 @@ static int work_fixup_free(void *addr, enum debug_obj_state state)static struct debug_obj_descr work_debug_descr = { .name ="work_struct" , + .debug_hint = work_debug_hint, .fixup_init = work_fixup_init, .fixup_activate = work_fixup_activate, .fixup_free = work_fixup_free,
lib/debugobjects.c +6 -3
@@ -249,14 +249,17 @@ static struct debug_bucket *get_bucket(unsigned long addr)static void debug_print_object (struct debug_obj *obj,char *msg) { +struct debug_obj_descr *descr = obj->descr;static int limit; -if (limit <5 && obj->descr != descr_test) { +if (limit <5 && descr != descr_test) { +void *hint = descr->debug_hint ? + descr->debug_hint (obj->object) :NULL ; limit++;WARN (1 ,KERN_ERR "ODEBUG: %s %s (active state %u) " -"object type: %s\n" , +"object type: %s hint: %pS\n" , msg, obj_states[obj->state], obj->astate, - obj->descr->name); + descr->name, hint); } debug_objects_warnings++; }