1 // SoftEther UT-VPN SourceCode
\r
3 // Copyright (C) 2004-2010 SoftEther Corporation.
\r
4 // Copyright (C) 2004-2010 University of Tsukuba, Japan.
\r
5 // Copyright (C) 2003-2010 Daiyuu Nobori.
\r
6 // All Rights Reserved.
\r
8 // http://utvpn.tsukuba.ac.jp/
\r
10 // This program is free software; you can redistribute it and/or
\r
11 // modify it under the terms of the GNU General Public License
\r
12 // version 2 as published by the Free Software Foundation.
\r
14 // This program is distributed in the hope that it will be useful,
\r
15 // but WITHOUT ANY WARRANTY; without even the implied warranty of
\r
16 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
\r
17 // GNU General Public License for more details.
\r
19 // You should have received a copy of the GNU General Public License version 2
\r
20 // along with this program; if not, write to the Free Software
\r
21 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
\r
23 // このファイルは GPL バージョン 2 ライセンスで公開されています。
\r
24 // 誰でもこのファイルの内容を複製、改変したり、改変したバージョンを再配布
\r
25 // することができます。ただし、原著作物を改変した場合は、原著作物の著作権表示
\r
26 // を除去することはできません。改変した著作物を配布する場合は、改変実施者の
\r
27 // 著作権表示を原著作物の著作権表示に付随して記載するようにしてください。
\r
29 // この SoftEther UT-VPN オープンソース・プロジェクトは、日本国の
\r
30 // ソフトイーサ株式会社 (SoftEther Corporation, http://www.softether.co.jp/ )
\r
31 // および筑波大学 (University of Tsukuba, http://www.tsukuba.ac.jp/ ) によって
\r
33 // 本プログラムの配布者は、本プログラムを、業としての利用以外のため、
\r
34 // および、試験または研究のために利用が行われることを想定して配布
\r
36 // SoftEther UT-VPN プロジェクトの Web サイトは http://utvpn.tsukuba.ac.jp/ に
\r
38 // 本ソフトウェアの不具合の修正、機能改良、セキュリティホールの修復などのコード
\r
39 // の改変を行った場合で、その成果物を SoftEther UT-VPN プロジェクトに提出して
\r
40 // いただける場合は、 http://utvpn.tsukuba.ac.jp/ までソースコードを送付して
\r
41 // ください。SoftEther UT-VPN プロジェクトの本体リリースまたはブランチリリース
\r
44 // GPL に基づいて原著作物が提供される本ソフトウェアの改良版を配布、販売する
\r
45 // 場合は、そのソースコードを GPL に基づいて誰にでも開示する義務が生じます。
\r
47 // 本ソフトウェアに関連する著作権、特許権、商標権はソフトイーサ株式会社
\r
48 // (SoftEther Corporation) およびその他の著作権保持者が保有しています。
\r
49 // ソフトイーサ株式会社等はこれらの権利を放棄していません。本ソフトウェアの
\r
50 // 二次著作物を配布、販売する場合は、これらの権利を侵害しないようにご注意
\r
53 // お願い: どのような通信ソフトウェアにも通常は必ず未発見の
\r
54 // セキュリティホールが潜んでいます。本ソースコードをご覧いただいた結果、
\r
55 // UT-VPN にセキュリティホールを発見された場合は、当該セキュリティホールの
\r
56 // 情報を不特定多数に開示される前に、必ず、ソフトイーサ株式会社
\r
57 // および脆弱性情報の届出を受け付ける公的機関まで通報いただき、
\r
58 // 公益保護にご協力いただきますようお願い申し上げます。
\r
60 // ソフトイーサ株式会社は、当該セキュリティホールについて迅速に対処を
\r
61 // 行い、UT-VPN および UT-VPN に関連するソフトウェアのユーザー・顧客
\r
64 // ソフトイーサへの届出先: http://www.softether.co.jp/jp/contact/
\r
65 // 日本国内の脆弱性情報届出受付公的機関:
\r
67 // http://www.ipa.go.jp/security/vuln/report/
\r
69 // 上記各事項について不明な点は、ソフトイーサ株式会社までご連絡ください。
\r
70 // 連絡先: http://www.softether.co.jp/jp/contact/
\r
72 // -----------------------------------------------
\r
75 // 新規リリース by SoftEther
\r
76 // -----------------------------------------------
\r
88 #include <Mayaqua/Mayaqua.h>
\r
91 static LOCK *obj_lock;
\r
92 static LOCK *obj_id_lock;
\r
94 static LOCK *cs_lock;
\r
95 static bool disable_tracking = false;
\r
96 static TRACKING_LIST **hashlist;
\r
98 static bool do_not_get_callstack;
\r
101 void TrackingEnable()
\r
103 disable_tracking = false;
\r
107 void TrackingDisable()
\r
109 disable_tracking = true;
\r
113 bool IsTrackingEnabled()
\r
115 return !disable_tracking;
\r
119 void MemoryDebugMenu()
\r
121 char tmp[MAX_SIZE];
\r
124 Print("Mayaqua Kernel Memory Debug Tools\n"
\r
125 "Copyright (C) SoftEther Corporation. All Rights Reserved.\n\n");
\r
126 g_memcheck = false;
\r
130 GetLine(tmp, sizeof(tmp));
\r
131 t = ParseToken(tmp, " \t");
\r
132 if (t->NumTokens == 0)
\r
135 DebugPrintAllObjects();
\r
139 if (!StrCmpi(cmd, "?"))
\r
141 DebugPrintCommandList();
\r
143 else if (!StrCmpi(cmd, "a"))
\r
145 DebugPrintAllObjects();
\r
147 else if (!StrCmpi(cmd, "i"))
\r
149 if (t->NumTokens == 1)
\r
151 Print("Usage: i <obj_id>\n\n");
\r
155 DebugPrintObjectInfo(ToInt(t->Token[1]));
\r
158 else if (!StrCmpi(cmd, "q"))
\r
162 else if (ToInt(cmd) != 0)
\r
164 DebugPrintObjectInfo(ToInt(t->Token[0]));
\r
168 Print("Command Not Found,\n\n");
\r
176 // オブジェクトを時間順にソートする
\r
177 int SortObjectView(void *p1, void *p2)
\r
179 TRACKING_OBJECT *o1, *o2;
\r
180 if (p1 == NULL || p2 == NULL)
\r
184 o1 = *(TRACKING_OBJECT **)p1;
\r
185 o2 = *(TRACKING_OBJECT **)p2;
\r
186 if (o1 == NULL || o2 == NULL)
\r
191 if (o1->Id > o2->Id)
\r
195 else if (o1->Id == o2->Id)
\r
203 void PrintObjectInfo(TRACKING_OBJECT *o)
\r
206 char tmp[MAX_SIZE];
\r
213 UINT64ToSystem(&t, o->CreatedDate);
\r
214 GetDateTimeStrMilli(tmp, sizeof(tmp), &t);
\r
216 Print(" TRACKING_OBJECT ID: %u\n"
\r
217 " TRACKING_OBJECT TYPE: %s\n"
\r
219 " TRACKING_OBJECT SIZE: %u bytes\n"
\r
220 " CREATED DATE: %s\n",
\r
221 o->Id, o->Name, UINT64_TO_POINTER(o->Address), o->Size, tmp);
\r
223 PrintCallStack(o->CallStack);
\r
227 void DebugPrintObjectInfo(UINT id)
\r
230 TRACKING_OBJECT *o;
\r
234 LockTrackingList();
\r
236 for (i = 0;i < TRACKING_NUM_ARRAY;i++)
\r
238 if (hashlist[i] != NULL)
\r
240 TRACKING_LIST *t = hashlist[i];
\r
244 if (t->Object->Id == id)
\r
250 if (t->Next == NULL)
\r
265 UnlockTrackingList();
\r
270 Print("obj_id %u Not Found.\n\n", id);
\r
274 PrintObjectInfo(o);
\r
279 void PrintObjectList(TRACKING_OBJECT *o)
\r
281 char tmp[MAX_SIZE];
\r
283 UINT64ToSystem(&t, o->CreatedDate);
\r
284 GetTimeStrMilli(tmp, sizeof(tmp), &t);
\r
285 TrackGetObjSymbolInfo(o);
\r
286 Print("%-4u - [%-6s] %s 0x%p size=%-5u %11s %u\n",
\r
287 o->Id, o->Name, tmp, UINT64_TO_POINTER(o->Address), o->Size, o->FileName, o->LineNumber);
\r
291 void DebugPrintAllObjects()
\r
297 view = NewListFast(SortObjectView);
\r
298 LockTrackingList();
\r
300 for (i = 0;i < TRACKING_NUM_ARRAY;i++)
\r
302 if (hashlist[i] != NULL)
\r
304 TRACKING_LIST *t = hashlist[i];
\r
308 Add(view, t->Object);
\r
310 if (t->Next == NULL)
\r
320 UnlockTrackingList();
\r
326 for (i = 0;i < LIST_NUM(view);i++)
\r
328 TRACKING_OBJECT *o = (TRACKING_OBJECT *)LIST_DATA(view, i);
\r
329 PrintObjectList(o);
\r
339 void DebugPrintCommandList()
\r
342 "a - All Objects\n"
\r
343 "i - Object Information\n"
\r
350 void PrintMemoryStatus()
\r
353 GetMemoryStatus(&s);
\r
354 Print("MEMORY STATUS:\n"
\r
355 " NUM_OF_MEMORY_BLOCKS: %u\n"
\r
356 " SIZE_OF_TOTAL_MEMORY: %u bytes\n",
\r
357 s.MemoryBlocksNum, s.MemorySize);
\r
361 void GetMemoryStatus(MEMORY_STATUS *status)
\r
365 if (status == NULL)
\r
370 LockTrackingList();
\r
374 for (i = 0;i < TRACKING_NUM_ARRAY;i++)
\r
376 if (hashlist[i] != NULL)
\r
378 TRACKING_LIST *t = hashlist[i];
\r
382 TRACKING_OBJECT *o = t->Object;
\r
384 if (StrCmpi(o->Name, "MEM") == 0)
\r
390 if (t->Next == NULL)
\r
400 UnlockTrackingList();
\r
402 status->MemoryBlocksNum = num;
\r
403 status->MemorySize = size;
\r
406 // オブジェクトからシンボル情報を取得する
\r
407 void TrackGetObjSymbolInfo(TRACKING_OBJECT *o)
\r
415 if (!(o->LineNumber == 0 && o->FileName[0] == 0))
\r
420 if (o->CallStack != NULL)
\r
422 GetCallStackSymbolInfo(o->CallStack);
\r
423 if (StrLen(o->CallStack->filename) != 0 && o->CallStack->line != 0)
\r
425 StrCpy(o->FileName, sizeof(o->FileName), o->CallStack->filename);
\r
426 o->LineNumber = o->CallStack->line;
\r
431 // 新しいオブジェクトを追跡リストに入れる
\r
432 void TrackNewObj(UINT64 addr, char *name, UINT size)
\r
434 TRACKING_OBJECT *o;
\r
437 if (addr == 0 || name == NULL)
\r
442 if (IsMemCheck() == false)
\r
448 if (disable_tracking)
\r
454 OSLock(obj_id_lock);
\r
458 OSUnlock(obj_id_lock);
\r
460 o = OSMemoryAlloc(sizeof(TRACKING_OBJECT));
\r
465 o->CreatedDate = LocalTime64();
\r
466 o->CallStack = WalkDownCallStack(GetCallStack(), 2);
\r
468 o->FileName[0] = 0;
\r
471 LockTrackingList();
\r
473 InsertTrackingList(o);
\r
475 UnlockTrackingList();
\r
478 // 追跡リストからオブジェクトを削除する
\r
479 void TrackDeleteObj(UINT64 addr)
\r
481 TRACKING_OBJECT *o;
\r
488 if (IsMemCheck() == false)
\r
494 if (disable_tracking)
\r
499 LockTrackingList();
\r
501 o = SearchTrackingList(addr);
\r
504 UnlockTrackingList();
\r
508 printf("TrackDeleteObj: 0x%x is not Object!!\n", (void *)addr);
\r
512 DeleteTrackingList(o, true);
\r
514 UnlockTrackingList();
\r
517 // 追跡しているオブジェクトのサイズを変更する
\r
518 void TrackChangeObjSize(UINT64 addr, UINT size, UINT64 new_addr)
\r
520 TRACKING_OBJECT *o;
\r
527 if (IsMemCheck() == false)
\r
533 if (disable_tracking)
\r
538 LockTrackingList();
\r
540 o = SearchTrackingList(addr);
\r
543 UnlockTrackingList();
\r
547 DeleteTrackingList(o, false);
\r
550 o->Address = new_addr;
\r
552 InsertTrackingList(o);
\r
554 UnlockTrackingList();
\r
558 int CompareTrackingObject(const void *p1, const void *p2)
\r
560 TRACKING_OBJECT *o1, *o2;
\r
562 if (p1 == NULL || p2 == NULL)
\r
566 o1 = *(TRACKING_OBJECT **)p1;
\r
567 o2 = *(TRACKING_OBJECT **)p2;
\r
568 if (o1 == NULL || o2 == NULL)
\r
573 if (o1->Address > o2->Address)
\r
577 if (o1->Address == o2->Address)
\r
584 // オブジェクトをトラッキングリストから検索
\r
585 TRACKING_OBJECT *SearchTrackingList(UINT64 Address)
\r
594 i = TRACKING_HASH(Address);
\r
596 if (hashlist[i] != NULL)
\r
598 TRACKING_LIST *tt = hashlist[i];
\r
602 if (tt->Object->Address == Address)
\r
619 // オブジェクトをトラッキングリストから削除
\r
620 void DeleteTrackingList(TRACKING_OBJECT *o, bool free_object_memory)
\r
629 i = TRACKING_HASH(o->Address);
\r
631 if (hashlist[i] != NULL)
\r
633 TRACKING_LIST *ft = NULL;
\r
635 if (hashlist[i]->Object == o)
\r
638 hashlist[i] = hashlist[i]->Next;
\r
642 TRACKING_LIST *tt = hashlist[i];
\r
643 TRACKING_LIST *prev = NULL;
\r
647 if (tt->Object == o)
\r
649 prev->Next = tt->Next;
\r
654 if (tt->Next == NULL)
\r
668 if (free_object_memory)
\r
670 FreeCallStack(o->CallStack);
\r
677 // オブジェクトをトラッキングリストに挿入
\r
678 void InsertTrackingList(TRACKING_OBJECT *o)
\r
688 t = OSMemoryAlloc(sizeof(TRACKING_LIST));
\r
692 i = TRACKING_HASH(o->Address);
\r
694 if (hashlist[i] == NULL)
\r
700 TRACKING_LIST *tt = hashlist[i];
\r
703 if (tt->Next == NULL)
\r
715 void LockTrackingList()
\r
721 void UnlockTrackingList()
\r
723 OSUnlock(obj_lock);
\r
727 void InitTracking()
\r
733 hashlist = (TRACKING_LIST **)OSMemoryAlloc(sizeof(TRACKING_LIST *) * TRACKING_NUM_ARRAY);
\r
735 for (i = 0;i < TRACKING_NUM_ARRAY;i++)
\r
737 hashlist[i] = NULL;
\r
743 obj_lock = OSNewLock();
\r
744 obj_id_lock = OSNewLock();
\r
745 cs_lock = OSNewLock();
\r
747 s = GetCallStack();
\r
750 do_not_get_callstack = true;
\r
754 do_not_get_callstack = false;
\r
760 void FreeTracking()
\r
764 OSDeleteLock(obj_lock);
\r
765 OSDeleteLock(obj_id_lock);
\r
766 OSDeleteLock(cs_lock);
\r
768 obj_id_lock = NULL;
\r
772 for (i = 0;i < TRACKING_NUM_ARRAY;i++)
\r
774 if (hashlist[i] != NULL)
\r
776 TRACKING_LIST *t = hashlist[i];
\r
780 TRACKING_LIST *t2 = t;
\r
781 TRACKING_OBJECT *o = t->Object;
\r
783 FreeCallStack(o->CallStack);
\r
799 OSMemoryFree(hashlist);
\r
803 void PrintCallStack(CALLSTACK_DATA *s)
\r
805 char tmp[MAX_SIZE * 2];
\r
807 GetCallStackStr(tmp, sizeof(tmp), s);
\r
811 // コールスタックを文字列に変換する
\r
812 void GetCallStackStr(char *str, UINT size, CALLSTACK_DATA *s)
\r
814 char tmp[MAX_SIZE];
\r
815 char tmp2[MAX_SIZE];
\r
816 char tmp3[MAX_SIZE];
\r
826 StrCpy(str, size, "(Unknown)\n");
\r
839 GetCallStackSymbolInfo(s);
\r
841 if (s->name == NULL)
\r
843 Format(tmp, sizeof(tmp), "0x%p ---", UINT64_TO_POINTER(s->offset));
\r
847 Format(tmp, sizeof(tmp), "0x%p %s() + 0x%02x",
\r
848 (void *)s->offset, s->name, UINT64_TO_POINTER(s->disp));
\r
850 for (i = 0;i < num;i++)
\r
855 StrCpy(tmp3, sizeof(tmp3), tmp2);
\r
856 StrCat(tmp3, sizeof(tmp3), tmp);
\r
857 Format(tmp, sizeof(tmp), "%-55s %11s %u\n", tmp3, s->filename, s->line);
\r
858 StrCat(str, size, tmp);
\r
866 CALLSTACK_DATA *GetCallStack()
\r
869 if (do_not_get_callstack)
\r
878 s = OSGetCallStack();
\r
886 // コールスタックを 3 つ分だけ下降する
\r
887 s = WalkDownCallStack(s, 3);
\r
892 // コールスタックのシンボル情報を取得
\r
893 bool GetCallStackSymbolInfo(CALLSTACK_DATA *s)
\r
904 ret = OSGetCallStackSymbolInfo(s);
\r
911 // コールスタックを指定された数だけ下降する
\r
912 CALLSTACK_DATA *WalkDownCallStack(CALLSTACK_DATA *s, UINT num)
\r
914 CALLSTACK_DATA *cs, *tmp;
\r
934 OSMemoryFree(tmp->name);
\r
945 void FreeCallStack(CALLSTACK_DATA *s)
\r
955 CALLSTACK_DATA *next = s->next;
\r
956 OSMemoryFree(s->name);
\r