Implemented SymEnumLines.

This commit is contained in:
Eric Pouech 2005-11-03 09:51:26 +00:00 committed by Alexandre Julliard
parent 8ad685c5b3
commit 9c1b57c3d4
5 changed files with 93 additions and 13 deletions

View File

@ -26,6 +26,7 @@
@ stub StackWalk64
@ stdcall StackWalk(long long long ptr ptr ptr ptr ptr ptr)
@ stdcall SymCleanup(long)
@ stdcall SymEnumLines(ptr double str str ptr ptr)
@ stdcall SymEnumSourceFiles(ptr double str ptr ptr)
@ stub SymEnumSym
@ stdcall SymEnumSymbols(ptr double str ptr ptr)

View File

@ -289,6 +289,19 @@ struct process
IMAGEHLP_STACK_FRAME ctx_frame;
};
struct line_info
{
unsigned long is_first : 1,
is_last : 1,
is_source_file : 1,
line_number;
union
{
unsigned long pc_offset; /* if is_source_file isn't set */
unsigned source_file; /* if is_source_file is set */
} u;
};
/* dbghelp.c */
extern struct process* process_find_by_handle(HANDLE hProcess);
extern HANDLE hMsvcrt;

View File

@ -26,6 +26,9 @@
#include "dbghelp_private.h"
#include "wine/debug.h"
#ifdef HAVE_REGEX_H
# include <regex.h>
#endif
WINE_DEFAULT_DEBUG_CHANNEL(dbghelp);
@ -136,3 +139,66 @@ BOOL WINAPI SymEnumSourceFiles(HANDLE hProcess, ULONG64 ModBase, LPSTR Mask,
return TRUE;
}
/******************************************************************
* SymEnumLines (DBGHELP.@)
*
*/
BOOL WINAPI SymEnumLines(HANDLE hProcess, ULONG64 base, PCSTR compiland,
PCSTR srcfile, PSYM_ENUMLINES_CALLBACK cb, PVOID user)
{
struct process* pcs;
struct module* module;
struct hash_table_iter hti;
struct symt_ht* sym;
regex_t re;
struct line_info* dli;
void* ptr;
SRCCODEINFO sci;
char* file;
if (!cb) return FALSE;
pcs = process_find_by_handle(hProcess);
if (!pcs) return FALSE;
if (!(dbghelp_options & SYMOPT_LOAD_LINES)) return TRUE;
if (regcomp(&re, srcfile, REG_NOSUB))
{
FIXME("Couldn't compile %s\n", srcfile);
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
if (compiland) FIXME("Unsupported yet (filtering on compiland %s)\n", compiland);
module = module_find_by_addr(pcs, base, DMT_UNKNOWN);
if (!(module = module_get_debug(pcs, module))) return FALSE;
sci.SizeOfStruct = sizeof(sci);
sci.ModBase = base;
hash_table_iter_init(&module->ht_symbols, &hti, NULL);
while ((ptr = hash_table_iter_up(&hti)))
{
sym = GET_ENTRY(ptr, struct symt_ht, hash_elt);
if (sym->symt.tag != SymTagFunction) continue;
dli = NULL;
sci.FileName[0] = '\0';
while ((dli = vector_iter_up(&((struct symt_function*)sym)->vlines, dli)))
{
if (dli->is_source_file)
{
file = (char*)source_get(module, dli->u.source_file);
if (regexec(&re, file, 0, NULL, 0) != 0) file = "";
strcpy(sci.FileName, file);
}
else if (sci.FileName[0])
{
sci.Key = dli;
sci.Obj[0] = '\0'; /* FIXME */
sci.LineNumber = dli->line_number;
sci.Address = dli->u.pc_offset;
if (!cb(&sci, user)) break;
}
}
}
return TRUE;
}

View File

@ -40,19 +40,6 @@
WINE_DEFAULT_DEBUG_CHANNEL(dbghelp);
WINE_DECLARE_DEBUG_CHANNEL(dbghelp_symt);
struct line_info
{
unsigned long is_first : 1,
is_last : 1,
is_source_file : 1,
line_number;
union
{
unsigned long pc_offset; /* if is_source_file isn't set */
unsigned source_file; /* if is_source_file is set */
} u;
};
inline static int cmp_addr(ULONG64 a1, ULONG64 a2)
{
if (a1 > a2) return 1;

View File

@ -749,6 +749,19 @@ BOOL WINAPI SymEnumSourceFiles(HANDLE, ULONG64, LPSTR, PSYM_ENUMSOURCFILES_CALLB
BOOL WINAPI SymGetLineFromAddr(HANDLE, DWORD, PDWORD, PIMAGEHLP_LINE);
BOOL WINAPI SymGetLinePrev(HANDLE, PIMAGEHLP_LINE);
BOOL WINAPI SymGetLineNext(HANDLE, PIMAGEHLP_LINE);
typedef struct _SRCCODEINFO
{
DWORD SizeOfStruct;
PVOID Key;
DWORD64 ModBase;
char Obj[MAX_PATH+1];
char FileName[MAX_PATH+1];
DWORD LineNumber;
DWORD64 Address;
} SRCCODEINFO, *PSRCCODEINFO;
typedef BOOL (CALLBACK* PSYM_ENUMLINES_CALLBACK)(PSRCCODEINFO, PVOID);
BOOL WINAPI SymEnumLines(HANDLE, ULONG64, PCSTR, PCSTR, PSYM_ENUMLINES_CALLBACK, PVOID);
/*************************
* File & image handling *